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.
5 #include "chrome_frame/test/test_with_web_server.h"
7 #include "base/base_paths.h"
8 #include "base/file_version_info.h"
9 #include "base/path_service.h"
10 #include "base/stringprintf.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/win/windows_version.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/installer/util/product.h"
16 #include "chrome/installer/util/install_util.h"
17 #include "chrome/installer/util/helper.h"
18 #include "chrome_frame/html_utils.h"
19 #include "chrome_frame/utils.h"
20 #include "chrome_frame/test/chrome_frame_test_utils.h"
21 #include "chrome_frame/test/mock_ie_event_sink_actions.h"
22 #include "chrome_frame/test/mock_ie_event_sink_test.h"
23 #include "chrome_frame/test/test_scrubber.h"
24 #include "net/base/mime_util.h"
25 #include "net/base/stream_listen_socket.h"
26 #include "net/http/http_util.h"
28 using chrome_frame_test::kChromeFrameLongNavigationTimeout
;
29 using chrome_frame_test::kChromeFrameVeryLongNavigationTimeout
;
32 using testing::StrCaseEq
;
34 const wchar_t kDocRoot
[] = L
"chrome_frame\\test\\data";
38 // Helper method for creating the appropriate HTTP response headers.
39 std::string
CreateHttpHeaders(CFInvocation invocation
,
40 bool add_no_cache_header
,
41 const std::string
& content_type
) {
42 std::ostringstream ss
;
43 ss
<< "HTTP/1.1 200 OK\r\n"
44 << "Connection: close\r\n"
45 << "Content-Type: " << content_type
<< "\r\n";
46 if (invocation
.type() == CFInvocation::HTTP_HEADER
)
47 ss
<< "X-UA-Compatible: chrome=1\r\n";
48 if (add_no_cache_header
) {
49 ss
<< "Cache-Control: no-cache\r\n";
50 ss
<< "Expires: Tue, 15 Nov 1994 08:12:31 GMT\r\n";
55 std::string
GetMockHttpHeaders(const FilePath
& mock_http_headers_path
) {
57 file_util::ReadFileToString(mock_http_headers_path
, &headers
);
61 class ChromeFrameTestEnvironment
: public testing::Environment
{
63 virtual ~ChromeFrameTestEnvironment() {}
64 virtual void SetUp() OVERRIDE
{
65 ScopedChromeFrameRegistrar::RegisterDefaults();
69 ::testing::Environment
* const chrome_frame_env
=
70 ::testing::AddGlobalTestEnvironment(new ChromeFrameTestEnvironment
);
74 FilePath
ChromeFrameTestWithWebServer::test_file_path_
;
75 FilePath
ChromeFrameTestWithWebServer::results_dir_
;
76 FilePath
ChromeFrameTestWithWebServer::CFInstall_path_
;
77 FilePath
ChromeFrameTestWithWebServer::CFInstance_path_
;
78 ScopedTempDir
ChromeFrameTestWithWebServer::temp_dir_
;
79 FilePath
ChromeFrameTestWithWebServer::chrome_user_data_dir_
;
80 chrome_frame_test::TimedMsgLoop
* ChromeFrameTestWithWebServer::loop_
;
81 std::string
ChromeFrameTestWithWebServer::local_address_
;
82 testing::StrictMock
<MockWebServerListener
>*
83 ChromeFrameTestWithWebServer::listener_mock_
;
84 testing::StrictMock
<MockWebServer
>* ChromeFrameTestWithWebServer::server_mock_
;
86 ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer() {
90 void ChromeFrameTestWithWebServer::SetUpTestCase() {
91 FilePath chrome_frame_source_path
;
92 PathService::Get(base::DIR_SOURCE_ROOT
, &chrome_frame_source_path
);
93 chrome_frame_source_path
= chrome_frame_source_path
.Append(
94 FILE_PATH_LITERAL("chrome_frame"));
96 test_file_path_
= chrome_frame_source_path
97 .Append(FILE_PATH_LITERAL("test"))
98 .Append(FILE_PATH_LITERAL("data"));
100 results_dir_
= chrome_frame_test::GetTestDataFolder().AppendASCII("dump");
102 // Copy the CFInstance.js and CFInstall.js files from src\chrome_frame to
103 // src\chrome_frame\test\data.
104 FilePath CFInstance_src_path
;
105 FilePath CFInstall_src_path
;
107 CFInstance_src_path
= chrome_frame_source_path
.AppendASCII("CFInstance.js");
108 CFInstance_path_
= test_file_path_
.AppendASCII("CFInstance.js");
110 ASSERT_TRUE(file_util::CopyFile(CFInstance_src_path
, CFInstance_path_
));
112 CFInstall_src_path
= chrome_frame_source_path
.AppendASCII("CFInstall.js");
113 CFInstall_path_
= test_file_path_
.AppendASCII("CFInstall.js");
115 ASSERT_TRUE(file_util::CopyFile(CFInstall_src_path
, CFInstall_path_
));
117 loop_
= new chrome_frame_test::TimedMsgLoop();
118 loop_
->set_snapshot_on_timeout(true);
119 local_address_
= chrome_frame_test::GetLocalIPv4Address();
120 listener_mock_
= new testing::StrictMock
<MockWebServerListener
>();
121 server_mock_
= new testing::StrictMock
<MockWebServer
>(
122 1337, ASCIIToWide(local_address_
),
123 chrome_frame_test::GetTestDataFolder());
124 server_mock_
->set_listener(listener_mock_
);
128 void ChromeFrameTestWithWebServer::TearDownTestCase() {
131 delete listener_mock_
;
132 listener_mock_
= NULL
;
133 local_address_
.clear();
136 file_util::Delete(CFInstall_path_
, false);
137 file_util::Delete(CFInstance_path_
, false);
138 if (temp_dir_
.IsValid())
139 EXPECT_TRUE(temp_dir_
.Delete());
143 const FilePath
& ChromeFrameTestWithWebServer::GetChromeUserDataDirectory() {
144 if (!temp_dir_
.IsValid()) {
145 EXPECT_TRUE(temp_dir_
.CreateUniqueTempDir());
146 chrome_user_data_dir_
= temp_dir_
.path().AppendASCII("User Data");
148 return chrome_user_data_dir_
;
151 void ChromeFrameTestWithWebServer::SetUp() {
152 // Make sure that we are not accidentally enabling gcf protocol.
153 SetConfigBool(kAllowUnsafeURLs
, false);
155 server_mock().ClearResults();
156 server_mock().ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE
));
157 server_mock().set_expected_result("OK");
160 void ChromeFrameTestWithWebServer::TearDown() {
162 loop().RunAllPending();
163 testing::Mock::VerifyAndClear(listener_mock_
);
164 testing::Mock::VerifyAndClear(server_mock_
);
167 bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser
,
168 const wchar_t* page
) {
169 std::wstring url
= page
;
171 // We should resolve the URL only if it is a relative url.
172 GURL
parsed_url(WideToUTF8(page
));
173 if (!parsed_url
.has_scheme()) {
174 url
= server_mock().Resolve(page
);
179 browser_handle_
.Set(chrome_frame_test::LaunchIE(url
));
180 } else if (browser
== CHROME
) {
181 const FilePath
& user_data_dir
= GetChromeUserDataDirectory();
182 chrome_frame_test::OverrideDataDirectoryForThisTest(user_data_dir
.value());
183 browser_handle_
.Set(chrome_frame_test::LaunchChrome(url
, user_data_dir
));
188 return browser_handle_
.IsValid();
191 void ChromeFrameTestWithWebServer::CloseBrowser() {
192 if (!browser_handle_
.IsValid())
196 if (browser_
== IE
) {
197 attempts
= chrome_frame_test::CloseAllIEWindows();
199 attempts
= chrome_frame_test::CloseVisibleWindowsOnAllThreads(
204 DWORD wait
= ::WaitForSingleObject(browser_handle_
, 20000);
205 if (wait
== WAIT_OBJECT_0
) {
206 browser_handle_
.Close();
208 LOG(ERROR
) << "WaitForSingleObject returned " << wait
;
211 LOG(ERROR
) << "No attempts to close browser windows";
214 if (browser_handle_
.IsValid()) {
216 if (!::GetExitCodeProcess(browser_handle_
, &exit_code
) ||
217 exit_code
== STILL_ACTIVE
) {
218 LOG(ERROR
) << L
"Forcefully killing browser process. Exit:" << exit_code
;
219 base::KillProcess(browser_handle_
, 0, true);
221 browser_handle_
.Close();
225 bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
226 return simulate_input::EnsureProcessInForeground(
227 GetProcessId(browser_handle_
));
230 bool ChromeFrameTestWithWebServer::WaitForTestToComplete(
231 base::TimeDelta duration
) {
232 loop().RunFor(duration
);
233 return !loop().WasTimedOut();
236 bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds
) {
240 const wchar_t kPostedResultSubstring
[] = L
"/writefile/";
242 void ChromeFrameTestWithWebServer::SimpleBrowserTestExpectedResult(
243 BrowserKind browser
, const wchar_t* page
, const char* result
) {
245 ExpectAndHandlePostedResult();
246 // Retry tests that timeout once; see http://crbug.com/96449.
248 // NOTE: Failed ASSERTs cause this function to exit immediately.
249 // Don't take a snapshot on the first try.
250 loop().set_snapshot_on_timeout(tries
!= 0);
251 ASSERT_TRUE(LaunchBrowser(browser
, page
));
252 if (WaitForTestToComplete(TestTimeouts::action_max_timeout())) {
253 // The test exited without timing out. Confirm that the expected response
254 // was posted and return.
255 ASSERT_EQ(result
, server_mock().posted_result());
258 ASSERT_EQ(std::string(), server_mock().posted_result())
259 << "Test timed out yet provided a result.";
260 ASSERT_EQ(0, tries
++) << "Failing test due to two timeouts.";
261 // Close the browser and try a second time.
263 LOG(ERROR
) << "Retrying test once since it timed out.";
265 loop().set_snapshot_on_timeout(true);
268 void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser
,
269 const wchar_t* page
) {
270 SimpleBrowserTestExpectedResult(browser
, page
, "OK");
273 void ChromeFrameTestWithWebServer::ExpectAndHandlePostedResult() {
274 EXPECT_CALL(listener_mock(), OnExpectedResponse())
275 .WillRepeatedly(QUIT_LOOP_SOON(loop(),
276 base::TimeDelta::FromMilliseconds(100)));
277 server_mock().ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE
),
278 kPostedResultSubstring
);
281 void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser
,
282 const wchar_t* page
) {
283 FilePath plugin_path
;
284 PathService::Get(base::DIR_MODULE
, &plugin_path
);
285 plugin_path
= plugin_path
.Append(kChromeFrameDllName
);
287 static FileVersionInfo
* version_info
=
288 FileVersionInfo::CreateFileVersionInfo(plugin_path
);
290 std::wstring version
;
292 version
= version_info
->product_version();
294 // If we can't find the Chrome Frame DLL in the src tree, we turn to
295 // the directory where chrome is installed.
297 BrowserDistribution
* dist
= BrowserDistribution::GetDistribution();
299 InstallUtil::GetChromeVersion(dist
, true, &ver_system
);
301 InstallUtil::GetChromeVersion(dist
, false, &ver_system
);
302 ASSERT_TRUE(ver_system
.IsValid() || ver_user
.IsValid());
304 bool system_install
= ver_system
.IsValid();
305 FilePath
cf_dll_path(installer::GetChromeInstallPath(system_install
, dist
));
306 cf_dll_path
= cf_dll_path
.Append(UTF8ToWide(
307 ver_system
.IsValid() ? ver_system
.GetString() : ver_user
.GetString()));
308 cf_dll_path
= cf_dll_path
.Append(kChromeFrameDllName
);
309 version_info
= FileVersionInfo::CreateFileVersionInfo(cf_dll_path
);
311 version
= version_info
->product_version();
314 server_mock().set_expected_result(WideToUTF8(version
));
316 EXPECT_TRUE(version_info
);
317 EXPECT_FALSE(version
.empty());
319 SimpleBrowserTestExpectedResult(browser
, page
, WideToASCII(version
).c_str());
322 // MockWebServer methods
323 void MockWebServer::ExpectAndServeRequest(CFInvocation invocation
,
324 const std::wstring
& url
) {
325 ExpectAndServeRequestWithCardinality(invocation
, url
, testing::Exactly(1));
328 void MockWebServer::ExpectAndServeRequestWithCardinality(
329 CFInvocation invocation
, const std::wstring
& url
,
330 testing::Cardinality cardinality
) {
331 EXPECT_CALL(*this, Get(_
, chrome_frame_test::UrlPathEq(url
), _
))
333 .WillRepeatedly(SendResponse(this, invocation
));
336 void MockWebServer::ExpectAndServeRequestAllowCache(CFInvocation invocation
,
337 const std::wstring
&url
) {
338 EXPECT_CALL(*this, Get(_
, chrome_frame_test::UrlPathEq(url
), _
))
339 .WillOnce(SendResponse(this, invocation
));
342 void MockWebServer::ExpectAndServeRequestAnyNumberTimes(
343 CFInvocation invocation
, const std::wstring
& path_prefix
) {
344 EXPECT_CALL(*this, Get(_
, testing::StartsWith(path_prefix
), _
))
345 .WillRepeatedly(SendResponse(this, invocation
));
348 void MockWebServer::ExpectAndHandlePostedResult(
349 CFInvocation invocation
, const std::wstring
& post_suffix
) {
350 EXPECT_CALL(*this, Post(_
, testing::HasSubstr(post_suffix
), _
))
351 .WillRepeatedly(HandlePostedResponseHelper(this, invocation
));
354 void MockWebServer::HandlePostedResponse(
355 test_server::ConfigurableConnection
* connection
,
356 const test_server::Request
& request
) {
357 posted_result_
= request
.content();
358 if (listener_
&& posted_result_
== expected_result_
)
359 listener_
->OnExpectedResponse();
360 connection
->Send("HTTP/1.1 200 OK\r\n", "");
363 void MockWebServer::SendResponseHelper(
364 test_server::ConfigurableConnection
* connection
,
365 const std::wstring
& request_uri
,
366 const test_server::Request
& request
,
367 CFInvocation invocation
,
368 bool add_no_cache_header
) {
369 static const wchar_t kEchoHeader
[] = L
"/echoheader?";
370 if (request_uri
.find(kEchoHeader
) != std::wstring::npos
) {
371 std::wstring header
= request_uri
.substr(
373 request_uri
.length() - wcslen(kEchoHeader
));
375 std::string header_value
= http_utils::GetHttpHeaderFromHeaderList(
376 WideToUTF8(header
), request
.headers());
377 connection
->Send(header_value
, "");
380 // Convert |request_uri| to a path.
381 std::wstring path
= request_uri
;
382 size_t query_index
= request_uri
.find(L
"?");
383 if (query_index
!= std::string::npos
) {
384 path
= path
.erase(query_index
);
386 FilePath file_path
= root_dir_
;
388 file_path
= file_path
.Append(path
.substr(1)); // remove first '/'
390 std::string headers
, body
;
391 std::string content_type
;
392 if (file_util::PathExists(file_path
) &&
393 !file_util::DirectoryExists(file_path
)) {
394 FilePath
mock_http_headers(file_path
.value() + L
".mock-http-headers");
395 if (file_util::PathExists(mock_http_headers
)) {
396 headers
= GetMockHttpHeaders(mock_http_headers
);
397 content_type
= http_utils::GetHttpHeaderFromHeaderList("Content-type",
400 EXPECT_TRUE(net::GetMimeTypeFromFile(file_path
, &content_type
));
401 VLOG(1) << "Going to send file (" << WideToUTF8(file_path
.value())
402 << ") with content type (" << content_type
<< ")";
403 headers
= CreateHttpHeaders(invocation
, add_no_cache_header
,
407 EXPECT_FALSE(headers
.empty());
409 EXPECT_TRUE(file_util::ReadFileToString(file_path
, &body
))
410 << "Could not read file (" << WideToUTF8(file_path
.value()) << ")";
411 if (invocation
.type() == CFInvocation::META_TAG
&&
412 StartsWithASCII(content_type
, "text/html", false)) {
413 EXPECT_TRUE(chrome_frame_test::AddCFMetaTag(&body
)) << "Could not add "
414 << "meta tag to HTML file.";
417 VLOG(1) << "Going to send 404 for non-existent file ("
418 << WideToUTF8(file_path
.value()) << ")";
419 headers
= "HTTP/1.1 404 Not Found";
422 connection
->Send(headers
, body
);
425 const wchar_t kPostMessageBasicPage
[] = L
"postmessage_basic_host.html";
427 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_PostMessageBasic
) {
428 SimpleBrowserTest(IE
, kPostMessageBasicPage
);
431 TEST_F(ChromeFrameTestWithWebServer
, FullTabIE_MIMEFilterBasic
) {
432 const wchar_t kMIMEFilterBasicPage
[] =
433 L
"chrome_frame_mime_filter_test.html";
435 // If this test fails for IE8 then it is possible that prebinding is enabled.
436 // A known workaround is to disable it until CF properly handles it.
438 // HKCU\Software\Microsoft\Internet Explorer\Main
439 // Value name: EnablePreBinding (REG_DWORD)
441 SimpleBrowserTest(IE
, kMIMEFilterBasicPage
);
444 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_Resize
) {
445 SimpleBrowserTest(IE
, L
"chrome_frame_resize.html");
448 const wchar_t kNavigateURLAbsolutePage
[] =
449 L
"navigateurl_absolute_host.html";
451 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_NavigateURLAbsolute
) {
452 SimpleBrowserTest(IE
, kNavigateURLAbsolutePage
);
455 const wchar_t kNavigateURLRelativePage
[] =
456 L
"navigateurl_relative_host.html";
458 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_NavigateURLRelative
) {
459 SimpleBrowserTest(IE
, kNavigateURLRelativePage
);
462 const wchar_t kNavigateSimpleObjectFocus
[] = L
"simple_object_focus.html";
464 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_ObjectFocus
) {
465 SimpleBrowserTest(IE
, kNavigateSimpleObjectFocus
);
468 const wchar_t kiframeBasicPage
[] = L
"iframe_basic_host.html";
470 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_iframeBasic
) {
471 SimpleBrowserTest(IE
, kiframeBasicPage
);
474 const wchar_t kSrcPropertyTestPage
[] = L
"src_property_host.html";
476 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_SrcProperty
) {
477 SimpleBrowserTest(IE
, kSrcPropertyTestPage
);
480 const wchar_t kCFInstanceBasicTestPage
[] = L
"CFInstance_basic_host.html";
482 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceBasic
) {
483 SimpleBrowserTest(IE
, kCFInstanceBasicTestPage
);
486 const wchar_t kCFISingletonPage
[] = L
"CFInstance_singleton_host.html";
488 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceSingleton
) {
489 SimpleBrowserTest(IE
, kCFISingletonPage
);
492 const wchar_t kCFIDelayPage
[] = L
"CFInstance_delay_host.html";
494 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceDelay
) {
495 SimpleBrowserTest(IE
, kCFIDelayPage
);
498 const wchar_t kCFIFallbackPage
[] = L
"CFInstance_fallback_host.html";
500 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceFallback
) {
501 SimpleBrowserTest(IE
, kCFIFallbackPage
);
504 const wchar_t kCFINoSrcPage
[] = L
"CFInstance_no_src_host.html";
506 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceNoSrc
) {
507 SimpleBrowserTest(IE
, kCFINoSrcPage
);
510 const wchar_t kCFIIfrOnLoadPage
[] = L
"CFInstance_iframe_onload_host.html";
512 // disabled since it's unlikely that we care about this case
513 TEST_F(ChromeFrameTestWithWebServer
,
514 DISABLED_WidgetModeIE_CFInstanceIfrOnLoad
) {
515 SimpleBrowserTest(IE
, kCFIIfrOnLoadPage
);
518 const wchar_t kCFIZeroSizePage
[] = L
"CFInstance_zero_size_host.html";
520 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceZeroSize
) {
521 SimpleBrowserTest(IE
, kCFIZeroSizePage
);
524 const wchar_t kCFIIfrPostPage
[] = L
"CFInstance_iframe_post_host.html";
526 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceIfrPost
) {
527 SimpleBrowserTest(IE
, kCFIIfrPostPage
);
530 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeChrome_CFInstanceIfrPost
) {
531 SimpleBrowserTest(CHROME
, kCFIIfrPostPage
);
534 const wchar_t kCFIPostPage
[] = L
"CFInstance_post_host.html";
536 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstancePost
) {
537 if (chrome_frame_test::GetInstalledIEVersion() == IE_9
) {
538 LOG(INFO
) << "Not running test on Vista/Windows 7 with IE9";
541 SimpleBrowserTest(IE
, kCFIPostPage
);
544 // This test randomly fails on the ChromeFrame builder.
545 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeChrome_CFInstancePost
) {
546 SimpleBrowserTest(CHROME
, kCFIPostPage
);
549 const wchar_t kCFIRPCPage
[] = L
"CFInstance_rpc_host.html";
551 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceRPC
) {
552 if (chrome_frame_test::GetInstalledIEVersion() == IE_9
) {
553 LOG(INFO
) << "Not running test on Vista/Windows 7 with IE9";
556 SimpleBrowserTest(IE
, kCFIRPCPage
);
559 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeChrome_CFInstanceRPC
) {
560 SimpleBrowserTest(CHROME
, kCFIRPCPage
);
563 const wchar_t kCFIRPCInternalPage
[] =
564 L
"CFInstance_rpc_internal_host.html";
566 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceRPCInternal
) {
567 if (chrome_frame_test::GetInstalledIEVersion() == IE_9
) {
568 LOG(INFO
) << "Not running test on Vista/Windows 7 with IE9";
571 SimpleBrowserTest(IE
, kCFIRPCInternalPage
);
574 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeChrome_CFInstanceRPCInternal
) {
575 SimpleBrowserTest(CHROME
, kCFIRPCInternalPage
);
578 const wchar_t kCFIDefaultCtorPage
[] =
579 L
"CFInstance_default_ctor_host.html";
581 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_CFInstanceDefaultCtor
) {
582 SimpleBrowserTest(IE
, kCFIDefaultCtorPage
);
585 const wchar_t kCFInstallBasicTestPage
[] = L
"CFInstall_basic.html";
587 TEST_F(ChromeFrameTestWithWebServer
, FullTabIE_CFInstallBasic
) {
588 SimpleBrowserTest(IE
, kCFInstallBasicTestPage
);
591 const wchar_t kCFInstallPlaceTestPage
[] = L
"CFInstall_place.html";
593 TEST_F(ChromeFrameTestWithWebServer
, FullTabIE_CFInstallPlace
) {
594 SimpleBrowserTest(IE
, kCFInstallPlaceTestPage
);
597 const wchar_t kCFInstallOverlayTestPage
[] = L
"CFInstall_overlay.html";
599 TEST_F(ChromeFrameTestWithWebServer
, FullTabIE_CFInstallOverlay
) {
600 SimpleBrowserTest(IE
, kCFInstallOverlayTestPage
);
603 const wchar_t kCFInstallDismissTestPage
[] = L
"CFInstall_dismiss.html";
605 TEST_F(ChromeFrameTestWithWebServer
, FullTabIE_CFInstallDismiss
) {
606 SimpleBrowserTest(IE
, kCFInstallDismissTestPage
);
609 const wchar_t kInitializeHiddenPage
[] = L
"initialize_hidden.html";
611 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_InitializeHidden
) {
612 SimpleBrowserTest(IE
, kInitializeHiddenPage
);
615 const wchar_t kFullTabHttpHeaderPage
[] = L
"chrome_frame_http_header.html";
617 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_CFHttpHeaderBasic
) {
618 SimpleBrowserTest(IE
, kFullTabHttpHeaderPage
);
621 const wchar_t kFullTabHttpHeaderPageIFrame
[] =
622 L
"chrome_frame_http_header_host.html";
624 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_CFHttpHeaderIFrame
) {
625 SimpleBrowserTest(IE
, kFullTabHttpHeaderPageIFrame
);
628 const wchar_t kFullTabHttpHeaderPageFrameset
[] =
629 L
"chrome_frame_http_header_frameset.html";
631 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_CFHttpHeaderFrameSet
) {
632 SimpleBrowserTest(IE
, kFullTabHttpHeaderPageFrameset
);
635 const wchar_t kVersionPage
[] = L
"version.html";
637 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_Version
) {
638 VersionTest(IE
, kVersionPage
);
641 const wchar_t kEventListenerPage
[] = L
"event_listener.html";
643 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_EventListener
) {
644 SimpleBrowserTest(IE
, kEventListenerPage
);
647 const wchar_t kPrivilegedApisPage
[] = L
"privileged_apis_host.html";
649 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_PrivilegedApis
) {
650 SimpleBrowserTest(IE
, kPrivilegedApisPage
);
653 const wchar_t kMetaTagPage
[] = L
"meta_tag.html";
654 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_MetaTag
) {
655 SimpleBrowserTest(IE
, kMetaTagPage
);
658 const wchar_t kCFProtocolPage
[] = L
"cf_protocol.html";
659 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_CFProtocol
) {
660 // Temporarily enable gcf: protocol for this test.
661 SetConfigBool(kAllowUnsafeURLs
, true);
662 SimpleBrowserTest(IE
, kCFProtocolPage
);
663 SetConfigBool(kAllowUnsafeURLs
, false);
666 const wchar_t kPersistentCookieTest
[] =
667 L
"persistent_cookie_test_page.html";
668 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_PersistentCookieTest
) {
669 SimpleBrowserTest(IE
, kPersistentCookieTest
);
672 const wchar_t kNavigateOutPage
[] = L
"navigate_out.html";
673 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_NavigateOut
) {
674 SimpleBrowserTest(IE
, kNavigateOutPage
);
677 const wchar_t kReferrerMainTest
[] = L
"referrer_main.html";
679 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_ReferrerTest
) {
680 SimpleBrowserTest(IE
, kReferrerMainTest
);
683 const wchar_t kSubFrameTestPage
[] = L
"full_tab_sub_frame_main.html";
684 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_SubFrame
) {
685 SimpleBrowserTest(IE
, kSubFrameTestPage
);
688 const wchar_t kSubIFrameTestPage
[] = L
"full_tab_sub_iframe_main.html";
689 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_SubIFrame
) {
690 SimpleBrowserTest(IE
, kSubIFrameTestPage
);
693 const wchar_t kXMLHttpRequestTestUrl
[] =
694 L
"xmlhttprequest_test.html";
696 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_XHRTest
) {
697 SimpleBrowserTest(IE
, kXMLHttpRequestTestUrl
);
700 const wchar_t kInstallFlowTestUrl
[] =
701 L
"install_flow_test.html";
703 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_InstallFlowTest
) {
704 if (base::win::GetVersion() < base::win::VERSION_VISTA
) {
705 ScopedChromeFrameRegistrar::UnregisterAtPath(
706 GetChromeFrameBuildPath().value(),
707 chrome_frame_test::GetTestBedType());
709 ASSERT_TRUE(LaunchBrowser(IE
, kInstallFlowTestUrl
));
711 loop().RunFor(kChromeFrameLongNavigationTimeout
);
713 ScopedChromeFrameRegistrar::RegisterAtPath(
714 GetChromeFrameBuildPath().value(),
715 chrome_frame_test::GetTestBedType());
717 ExpectAndHandlePostedResult();
718 loop().RunFor(kChromeFrameLongNavigationTimeout
);
720 chrome_frame_test::CloseAllIEWindows();
721 ASSERT_EQ("OK", server_mock().posted_result());
725 const wchar_t kMultipleCFInstancesTestUrl
[] =
726 L
"multiple_cf_instances_main.html";
728 TEST_F(ChromeFrameTestWithWebServer
, WidgetModeIE_MultipleCFInstances
) {
729 SimpleBrowserTest(IE
, kMultipleCFInstancesTestUrl
);
732 const wchar_t kXHRHeaderTestUrl
[] =
733 L
"xmlhttprequest_header_test.html";
735 // Marking as flaky since it occasionally times out. crbug.com/127395.
736 TEST_F(ChromeFrameTestWithWebServer
, FLAKY_FullTabModeIE_XHRHeaderTest
) {
737 SimpleBrowserTest(IE
, kXHRHeaderTestUrl
);
740 const wchar_t kDeleteCookieTest
[] =
741 L
"fulltab_delete_cookie_test.html";
743 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_DeleteCookieTest
) {
744 SimpleBrowserTest(IE
, kDeleteCookieTest
);
747 const wchar_t kAnchorUrlNavigate
[] =
748 L
"fulltab_anchor_url_navigate.html#chrome_frame";
750 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_AnchorUrlNavigateTest
) {
751 SimpleBrowserTest(IE
, kAnchorUrlNavigate
);
754 // Test whether POST-ing a form from an mshtml page to a CF page will cause
755 // the request to get reissued. It should not.
756 // https://code.google.com/p/chromium/issues/detail?id=143699
757 TEST_F(ChromeFrameTestWithWebServer
, FLAKY_FullTabModeIE_TestPostReissue
) {
758 // The order of pages in this array is assumed to be mshtml, cf, script.
759 const wchar_t* kPages
[] = {
760 L
"full_tab_post_mshtml.html",
761 L
"full_tab_post_target_cf.html",
762 L
"chrome_frame_tester_helpers.js",
765 SimpleWebServerTest
server(local_address_
, 46664);
766 server
.PopulateStaticFileListT
<test_server::FileResponse
>(kPages
,
767 arraysize(kPages
), GetCFTestFilePath());
769 ASSERT_TRUE(LaunchBrowser(IE
, server
.FormatHttpPath(kPages
[0]).c_str()));
771 loop().RunFor(kChromeFrameLongNavigationTimeout
);
773 const test_server::Request
* request
= NULL
;
774 server
.FindRequest("/quit?OK", &request
);
775 ASSERT_TRUE(request
!= NULL
);
776 EXPECT_EQ("OK", request
->arguments());
778 if (request
->arguments().compare("OK") == 0) {
779 // Check how many requests we got for the cf page. Also expect it to be
781 int requests
= server
.GetRequestCountForPage(kPages
[1], "POST");
782 EXPECT_EQ(1, requests
);
786 // Test whether following a link from an mshtml page to a CF page will cause
787 // multiple network requests. It should not.
788 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_TestMultipleGet
) {
789 // The order of pages in this array is assumed to be mshtml, cf, script.
790 const wchar_t* kPages
[] = {
791 L
"full_tab_get_mshtml.html",
792 L
"full_tab_get_target_cf.html",
793 L
"chrome_frame_tester_helpers.js",
796 SimpleWebServerTest
server(local_address_
, 46664);
798 server
.PopulateStaticFileListT
<test_server::FileResponse
>(kPages
,
799 arraysize(kPages
), GetCFTestFilePath());
801 ASSERT_TRUE(LaunchBrowser(IE
, server
.FormatHttpPath(kPages
[0]).c_str()));
803 loop().RunFor(kChromeFrameVeryLongNavigationTimeout
);
805 const test_server::Request
* request
= NULL
;
806 server
.FindRequest("/quit?OK", &request
);
807 ASSERT_TRUE(request
!= NULL
);
808 EXPECT_EQ("OK", request
->arguments());
810 if (request
->arguments().compare("OK") == 0) {
811 // Check how many requests we got for the cf page and check that it was
813 int requests
= server
.GetRequestCountForPage(kPages
[1], "GET");
814 EXPECT_EQ(1, requests
);
818 const wchar_t kSetCookieTest
[] =
819 L
"fulltab_set_cookie_test.html";
821 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_SetCookieTest
) {
822 SimpleBrowserTest(IE
, kSetCookieTest
);
825 const wchar_t kXHRConditionalHeaderTestUrl
[] =
826 L
"xmlhttprequest_conditional_header_test.html";
828 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_XHRConditionalHeaderTest
) {
829 SimpleBrowserTest(IE
, kXHRConditionalHeaderTestUrl
);
832 const wchar_t kWindowCloseTestUrl
[] =
833 L
"window_close.html";
835 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_WindowClose
) {
836 SimpleBrowserTest(IE
, kWindowCloseTestUrl
);
839 std::string
GetHeaderValue(const std::string
& headers
,
840 const char* header_name
) {
841 net::HttpUtil::HeadersIterator
it(headers
.begin(), headers
.end(),
843 while (it
.GetNext()) {
844 if (lstrcmpiA(it
.name().c_str(), header_name
) == 0) {
851 // Specialized implementation of test_server::FileResponse that supports
852 // adding the request's User-Agent header to the returned document.
853 // The class also supports $request_id$ which will be replaced with an
854 // id that's incremented each time the response is sent over a socket.
855 class UaTemplateFileResponse
: public test_server::FileResponse
{
857 typedef test_server::FileResponse SuperClass
;
859 UaTemplateFileResponse(const char* request_path
, const FilePath
& file_path
)
860 : test_server::FileResponse(request_path
, file_path
), request_id_(0) {
863 virtual bool Matches(const test_server::Request
& r
) const {
864 bool ret
= SuperClass::Matches(r
);
866 ua_
= GetHeaderValue(r
.headers(), "User-Agent");
870 virtual size_t ContentLength() const {
871 const char kRequestIdTemplate
[] = "$request_id$";
872 const char kUserAgentTemplate
[] = "$UA$";
874 size_t length
= SuperClass::ContentLength();
876 content_
.assign(reinterpret_cast<const char*>(file_
->data()),
878 size_t i
= content_
.find(kUserAgentTemplate
);
879 if (i
!= std::string::npos
)
880 content_
.replace(i
, arraysize(kUserAgentTemplate
) - 1, ua_
);
881 i
= content_
.find(kRequestIdTemplate
);
882 if (i
!= std::string::npos
) {
883 content_
.replace(i
, arraysize(kRequestIdTemplate
) - 1,
884 base::StringPrintf("%i", request_id_
));
886 return content_
.length();
889 virtual void WriteContents(net::StreamListenSocket
* socket
) const {
890 DCHECK(content_
.length());
891 socket
->Send(content_
.c_str(), content_
.length(), false);
896 mutable std::string ua_
;
897 mutable std::string content_
;
898 mutable int request_id_
;
901 // This test simulates a URL that on first request returns a document
902 // that should be rendered in mshtml, then pops up a sign-in page that
903 // after signing in, refreshes the original page that should then return
904 // a page that needs to be rendered in GCF.
906 // This test currently fails because GCF does not add the chromeframe header
907 // to requests that mshtml initiates via IInternetSession::CreateBinding.
908 TEST_F(ChromeFrameTestWithWebServer
, FAILS_FullTabModeIE_RefreshMshtmlTest
) {
909 const wchar_t* kPages
[] = {
910 L
"mshtml_refresh_test.html",
911 L
"mshtml_refresh_test_popup.html",
914 SimpleWebServerTest
server(local_address_
, 46664);
915 server
.PopulateStaticFileListT
<UaTemplateFileResponse
>(kPages
,
916 arraysize(kPages
), GetCFTestFilePath());
918 ASSERT_TRUE(LaunchBrowser(IE
, server
.FormatHttpPath(kPages
[0]).c_str()));
920 loop().RunFor(kChromeFrameLongNavigationTimeout
);
922 test_server::SimpleWebServer
* ws
= server
.web_server();
923 const test_server::ConnectionList
& connections
= ws
->connections();
924 test_server::ConnectionList::const_iterator it
= connections
.begin();
925 int requests_for_first_page
= 0;
926 for (; it
!= connections
.end(); ++it
) {
927 test_server::Connection
* c
= (*it
);
928 const test_server::Request
& r
= c
->request();
929 if (!r
.path().empty() &&
930 ASCIIToWide(r
.path().substr(1)).compare(kPages
[0]) == 0) {
931 requests_for_first_page
++;
932 std::string
ua(GetHeaderValue(r
.headers(), "User-Agent"));
933 EXPECT_NE(std::string::npos
, ua
.find("chromeframe"));
936 EXPECT_GT(requests_for_first_page
, 1);
939 // See bug 36694 for details. http://crbug.com/36694
940 TEST_F(ChromeFrameTestWithWebServer
, FullTabModeIE_TestDownloadFromForm
) {
941 chrome_frame_test::MockWindowObserver win_observer_mock
;
942 win_observer_mock
.WatchWindow("File Download", "");
943 win_observer_mock
.WatchWindow("View Downloads*", "");
945 // The content of our HTML test page. This will be returned whenever
946 // we reply to a GET request.
947 static const char kHtml
[] =
949 "<title>ChromeFrame Form Download Test</title>\n"
950 // To see how this test runs with only IE (no CF in the picture), comment
951 // out this meta tag. The outcome of the test should be identical.
952 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />\n"
954 "<script language=\"javascript\">\n"
955 "function SubmitForm() {\n"
956 " var form = document.forms['myform'];\n"
957 " form.action = document.location;\n"
962 "<body onload=\"SubmitForm();\">\n"
963 "<form method=\"post\" action=\"foo.html\" id=\"myform\">\n"
964 " <input type=\"hidden\" name=\"Field1\" value=\"myvalue\" />\n"
965 " <input type=\"button\" name=\"btn\" value=\"Test Download\" "
966 "onclick=\"return SubmitForm();\" id=\"Button1\"/>\n"
967 "</form></body></html>\n";
969 // The content of our HTML test page. This will be returned whenever
970 // we reply to a POST request.
971 static const char kText
[] =
972 "This is a text file (in case you were wondering).";
974 // This http response class will return an HTML document that contains
975 // a form whenever it receives a GET request. Whenever it gets a POST
976 // request, it will respond with a text file that needs to be downloaded
977 // (content-disposition is "attachment").
978 class CustomResponse
: public test_server::ResponseForPath
{
980 explicit CustomResponse(const char* path
)
981 : test_server::ResponseForPath(path
), is_post_(false),
982 post_requests_(0), get_requests_(0) {
985 virtual bool GetContentType(std::string
* content_type
) const {
990 virtual size_t ContentLength() const {
992 return sizeof(kHtml
) - 1;
995 virtual bool GetCustomHeaders(std::string
* headers
) const {
998 *headers
= StringPrintf(
999 "HTTP/1.1 200 OK\r\n"
1000 "Content-Disposition: attachment;filename=\"test.txt\"\r\n"
1001 "Content-Type: application/text\r\n"
1002 "Connection: close\r\n"
1003 "Content-Length: %i\r\n\r\n", sizeof(kText
) - 1);
1007 virtual bool Matches(const test_server::Request
& r
) const {
1008 bool match
= __super::Matches(r
);
1010 is_post_
= LowerCaseEqualsASCII(r
.method().c_str(), "post");
1015 virtual void WriteContents(net::StreamListenSocket
* socket
) const {
1017 socket
->Send(kText
, sizeof(kText
) - 1, false);
1019 socket
->Send(kHtml
, sizeof(kHtml
) - 1, false);
1023 virtual void IncrementAccessCounter() {
1024 __super::IncrementAccessCounter();
1032 size_t get_request_count() const {
1033 return get_requests_
;
1036 size_t post_request_count() const {
1037 return get_requests_
;
1041 mutable bool is_post_
;
1042 size_t post_requests_
;
1043 size_t get_requests_
;
1046 EXPECT_CALL(win_observer_mock
, OnWindowOpen(_
))
1047 .Times(testing::AtMost(1))
1048 .WillOnce(chrome_frame_test::DoCloseWindow());
1050 EXPECT_CALL(win_observer_mock
, OnWindowClose(_
))
1051 .Times(testing::AtMost(1))
1052 .WillOnce(QUIT_LOOP(loop()));
1054 SimpleWebServerTest
server(local_address_
, 46664);
1055 CustomResponse
* response
= new CustomResponse("/form.html");
1056 server
.web_server()->AddResponse(response
);
1058 std::wstring
url(server
.FormatHttpPath(L
"form.html"));
1060 ASSERT_TRUE(LaunchBrowser(IE
, url
.c_str()));
1061 loop().RunFor(kChromeFrameLongNavigationTimeout
);
1063 EXPECT_EQ(1, response
->get_request_count());
1064 EXPECT_EQ(1, response
->post_request_count());