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_util.h"
9 #include "base/file_version_info.h"
10 #include "base/files/memory_mapped_file.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/path_service.h"
13 #include "base/process/kill.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/test_timeouts.h"
17 #include "base/win/windows_version.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/installer/util/helper.h"
20 #include "chrome/installer/util/install_util.h"
21 #include "chrome/installer/util/product.h"
22 #include "chrome_frame/html_utils.h"
23 #include "chrome_frame/test/chrome_frame_test_utils.h"
24 #include "chrome_frame/test/mock_ie_event_sink_actions.h"
25 #include "chrome_frame/test/mock_ie_event_sink_test.h"
26 #include "chrome_frame/test/test_scrubber.h"
27 #include "chrome_frame/utils.h"
28 #include "net/base/mime_util.h"
29 #include "net/http/http_util.h"
30 #include "net/socket/stream_listen_socket.h"
32 using chrome_frame_test::kChromeFrameLongNavigationTimeout;
33 using chrome_frame_test::kChromeFrameVeryLongNavigationTimeout;
36 using testing::StrCaseEq;
38 const wchar_t kDocRoot[] = L"chrome_frame\\test\\data";
42 // Helper method for creating the appropriate HTTP response headers.
43 std::string CreateHttpHeaders(CFInvocation invocation,
44 bool add_no_cache_header,
45 const std::string& content_type) {
46 std::ostringstream ss;
47 ss << "HTTP/1.1 200 OK\r\n"
48 << "Connection: close\r\n"
49 << "Content-Type: " << content_type << "\r\n";
50 if (invocation.type() == CFInvocation::HTTP_HEADER)
51 ss << "X-UA-Compatible: chrome=1\r\n";
52 if (add_no_cache_header) {
53 ss << "Cache-Control: no-cache\r\n";
54 ss << "Expires: Tue, 15 Nov 1994 08:12:31 GMT\r\n";
59 std::string GetMockHttpHeaders(const base::FilePath& mock_http_headers_path) {
61 base::ReadFileToString(mock_http_headers_path, &headers);
65 class ChromeFrameTestEnvironment: public testing::Environment {
67 virtual ~ChromeFrameTestEnvironment() {}
68 virtual void SetUp() OVERRIDE {
69 ScopedChromeFrameRegistrar::RegisterDefaults();
73 ::testing::Environment* const chrome_frame_env =
74 ::testing::AddGlobalTestEnvironment(new ChromeFrameTestEnvironment);
78 base::FilePath ChromeFrameTestWithWebServer::test_file_path_;
79 base::FilePath ChromeFrameTestWithWebServer::results_dir_;
80 base::FilePath ChromeFrameTestWithWebServer::CFInstall_path_;
81 base::FilePath ChromeFrameTestWithWebServer::CFInstance_path_;
82 base::ScopedTempDir ChromeFrameTestWithWebServer::temp_dir_;
83 base::FilePath ChromeFrameTestWithWebServer::chrome_user_data_dir_;
84 chrome_frame_test::TimedMsgLoop* ChromeFrameTestWithWebServer::loop_;
85 std::string ChromeFrameTestWithWebServer::local_address_;
86 testing::StrictMock<MockWebServerListener>*
87 ChromeFrameTestWithWebServer::listener_mock_;
88 testing::StrictMock<MockWebServer>* ChromeFrameTestWithWebServer::server_mock_;
90 ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer() {
94 void ChromeFrameTestWithWebServer::SetUpTestCase() {
95 base::FilePath chrome_frame_source_path;
96 PathService::Get(base::DIR_SOURCE_ROOT, &chrome_frame_source_path);
97 chrome_frame_source_path = chrome_frame_source_path.Append(
98 FILE_PATH_LITERAL("chrome_frame"));
100 test_file_path_ = chrome_frame_source_path
101 .Append(FILE_PATH_LITERAL("test"))
102 .Append(FILE_PATH_LITERAL("data"));
104 results_dir_ = chrome_frame_test::GetTestDataFolder().AppendASCII("dump");
106 // Copy the CFInstance.js and CFInstall.js files from src\chrome_frame to
107 // src\chrome_frame\test\data.
108 base::FilePath CFInstance_src_path;
109 base::FilePath CFInstall_src_path;
111 CFInstance_src_path = chrome_frame_source_path.AppendASCII("CFInstance.js");
112 CFInstance_path_ = test_file_path_.AppendASCII("CFInstance.js");
114 ASSERT_TRUE(base::CopyFile(CFInstance_src_path, CFInstance_path_));
116 CFInstall_src_path = chrome_frame_source_path.AppendASCII("CFInstall.js");
117 CFInstall_path_ = test_file_path_.AppendASCII("CFInstall.js");
119 ASSERT_TRUE(base::CopyFile(CFInstall_src_path, CFInstall_path_));
121 loop_ = new chrome_frame_test::TimedMsgLoop();
122 loop_->set_snapshot_on_timeout(true);
123 local_address_ = chrome_frame_test::GetLocalIPv4Address();
124 listener_mock_ = new testing::StrictMock<MockWebServerListener>();
125 server_mock_ = new testing::StrictMock<MockWebServer>(
126 1337, ASCIIToWide(local_address_),
127 chrome_frame_test::GetTestDataFolder());
128 server_mock_->set_listener(listener_mock_);
132 void ChromeFrameTestWithWebServer::TearDownTestCase() {
135 delete listener_mock_;
136 listener_mock_ = NULL;
137 local_address_.clear();
140 base::DeleteFile(CFInstall_path_, false);
141 base::DeleteFile(CFInstance_path_, false);
142 if (temp_dir_.IsValid())
143 EXPECT_TRUE(temp_dir_.Delete());
147 const base::FilePath&
148 ChromeFrameTestWithWebServer::GetChromeUserDataDirectory() {
149 if (!temp_dir_.IsValid()) {
150 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
151 chrome_user_data_dir_ = temp_dir_.path().AppendASCII("User Data");
153 return chrome_user_data_dir_;
156 void ChromeFrameTestWithWebServer::SetUp() {
157 // Make sure that we are not accidentally enabling gcf protocol.
158 SetConfigBool(kAllowUnsafeURLs, false);
160 server_mock().ClearResults();
161 server_mock().ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE));
162 server_mock().set_expected_result("OK");
165 void ChromeFrameTestWithWebServer::TearDown() {
167 loop().RunUntilIdle();
168 testing::Mock::VerifyAndClear(listener_mock_);
169 testing::Mock::VerifyAndClear(server_mock_);
172 bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
173 const wchar_t* page) {
174 std::wstring url = page;
176 // We should resolve the URL only if it is a relative url.
177 GURL parsed_url(WideToUTF8(page));
178 if (!parsed_url.has_scheme()) {
179 url = server_mock().Resolve(page);
184 browser_handle_.Set(chrome_frame_test::LaunchIE(url));
185 } else if (browser == CHROME) {
186 const base::FilePath& user_data_dir = GetChromeUserDataDirectory();
187 chrome_frame_test::OverrideDataDirectoryForThisTest(user_data_dir.value());
188 browser_handle_.Set(chrome_frame_test::LaunchChrome(url, user_data_dir));
193 return browser_handle_.IsValid();
196 void ChromeFrameTestWithWebServer::CloseBrowser() {
197 if (!browser_handle_.IsValid())
201 if (browser_ == IE) {
202 attempts = chrome_frame_test::CloseAllIEWindows();
204 attempts = chrome_frame_test::CloseVisibleWindowsOnAllThreads(
209 DWORD wait = ::WaitForSingleObject(browser_handle_, 20000);
210 if (wait == WAIT_OBJECT_0) {
211 browser_handle_.Close();
213 LOG(ERROR) << "WaitForSingleObject returned " << wait;
216 LOG(ERROR) << "No attempts to close browser windows";
219 if (browser_handle_.IsValid()) {
221 if (!::GetExitCodeProcess(browser_handle_, &exit_code) ||
222 exit_code == STILL_ACTIVE) {
223 LOG(ERROR) << L"Forcefully killing browser process. Exit:" << exit_code;
224 base::KillProcess(browser_handle_, 0, true);
226 browser_handle_.Close();
230 bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
231 return simulate_input::EnsureProcessInForeground(
232 GetProcessId(browser_handle_));
235 bool ChromeFrameTestWithWebServer::WaitForTestToComplete(
236 base::TimeDelta duration) {
237 loop().RunFor(duration);
238 return !loop().WasTimedOut();
241 bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds) {
245 const wchar_t kPostedResultSubstring[] = L"/writefile/";
247 void ChromeFrameTestWithWebServer::SimpleBrowserTestExpectedResult(
248 BrowserKind browser, const wchar_t* page, const char* result) {
249 if (browser == IE && chrome_frame_test::GetInstalledIEVersion() >= IE_9) {
250 LOG(INFO) << "Temporarily disabling IE9 web server tests. "
251 "See http://crbug.com/143699";
256 ExpectAndHandlePostedResult();
257 // Retry tests that timeout once; see http://crbug.com/96449.
259 // NOTE: Failed ASSERTs cause this function to exit immediately.
260 // Don't take a snapshot on the first try.
261 loop().set_snapshot_on_timeout(tries != 0);
262 ASSERT_TRUE(LaunchBrowser(browser, page));
263 if (WaitForTestToComplete(TestTimeouts::action_max_timeout())) {
264 // The test exited without timing out. Confirm that the expected response
265 // was posted and return.
266 ASSERT_EQ(result, server_mock().posted_result());
269 ASSERT_EQ(std::string(), server_mock().posted_result())
270 << "Test timed out yet provided a result.";
271 ASSERT_EQ(0, tries++) << "Failing test due to two timeouts.";
272 // Close the browser and try a second time.
274 LOG(ERROR) << "Retrying test once since it timed out.";
276 loop().set_snapshot_on_timeout(true);
279 void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
280 const wchar_t* page) {
281 SimpleBrowserTestExpectedResult(browser, page, "OK");
284 void ChromeFrameTestWithWebServer::ExpectAndHandlePostedResult() {
285 EXPECT_CALL(listener_mock(), OnExpectedResponse())
286 .WillRepeatedly(QUIT_LOOP_SOON(loop(),
287 base::TimeDelta::FromMilliseconds(100)));
288 server_mock().ExpectAndHandlePostedResult(CFInvocation(CFInvocation::NONE),
289 kPostedResultSubstring);
292 void ChromeFrameTestWithWebServer::VersionTest(BrowserKind browser,
293 const wchar_t* page) {
294 base::FilePath plugin_path;
295 PathService::Get(base::DIR_MODULE, &plugin_path);
296 plugin_path = plugin_path.Append(kChromeFrameDllName);
298 static FileVersionInfo* version_info =
299 FileVersionInfo::CreateFileVersionInfo(plugin_path);
301 std::wstring version;
303 version = version_info->product_version();
305 // If we can't find the Chrome Frame DLL in the src tree, we turn to
306 // the directory where chrome is installed.
308 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
310 InstallUtil::GetChromeVersion(dist, true, &ver_system);
312 InstallUtil::GetChromeVersion(dist, false, &ver_system);
313 ASSERT_TRUE(ver_system.IsValid() || ver_user.IsValid());
315 bool system_install = ver_system.IsValid();
316 base::FilePath cf_dll_path(installer::GetChromeInstallPath(system_install, dist));
317 cf_dll_path = cf_dll_path.Append(UTF8ToWide(
318 ver_system.IsValid() ? ver_system.GetString() : ver_user.GetString()));
319 cf_dll_path = cf_dll_path.Append(kChromeFrameDllName);
320 version_info = FileVersionInfo::CreateFileVersionInfo(cf_dll_path);
322 version = version_info->product_version();
325 server_mock().set_expected_result(WideToUTF8(version));
327 EXPECT_TRUE(version_info);
328 EXPECT_FALSE(version.empty());
330 SimpleBrowserTestExpectedResult(browser, page, WideToASCII(version).c_str());
333 // MockWebServer methods
334 void MockWebServer::ExpectAndServeRequest(CFInvocation invocation,
335 const std::wstring& url) {
336 ExpectAndServeRequestWithCardinality(invocation, url, testing::Exactly(1));
339 void MockWebServer::ExpectAndServeRequestWithCardinality(
340 CFInvocation invocation, const std::wstring& url,
341 testing::Cardinality cardinality) {
342 EXPECT_CALL(*this, Get(_, chrome_frame_test::UrlPathEq(url), _))
344 .WillRepeatedly(SendResponse(this, invocation));
347 void MockWebServer::ExpectAndServeRequestAllowCache(CFInvocation invocation,
348 const std::wstring &url) {
349 EXPECT_CALL(*this, Get(_, chrome_frame_test::UrlPathEq(url), _))
350 .WillOnce(SendResponse(this, invocation));
353 void MockWebServer::ExpectAndServeRequestAnyNumberTimes(
354 CFInvocation invocation, const std::wstring& path_prefix) {
355 EXPECT_CALL(*this, Get(_, testing::StartsWith(path_prefix), _))
356 .WillRepeatedly(SendResponse(this, invocation));
359 void MockWebServer::ExpectAndHandlePostedResult(
360 CFInvocation invocation, const std::wstring& post_suffix) {
361 EXPECT_CALL(*this, Post(_, testing::HasSubstr(post_suffix), _))
362 .WillRepeatedly(HandlePostedResponseHelper(this, invocation));
365 void MockWebServer::HandlePostedResponse(
366 test_server::ConfigurableConnection* connection,
367 const test_server::Request& request) {
368 posted_result_ = request.content();
369 if (listener_ && posted_result_ == expected_result_)
370 listener_->OnExpectedResponse();
371 connection->Send("HTTP/1.1 200 OK\r\n", "");
374 void MockWebServer::SendResponseHelper(
375 test_server::ConfigurableConnection* connection,
376 const std::wstring& request_uri,
377 const test_server::Request& request,
378 CFInvocation invocation,
379 bool add_no_cache_header) {
380 static const wchar_t kEchoHeader[] = L"/echoheader?";
381 if (request_uri.find(kEchoHeader) != std::wstring::npos) {
382 std::wstring header = request_uri.substr(
384 request_uri.length() - wcslen(kEchoHeader));
386 std::string header_value = http_utils::GetHttpHeaderFromHeaderList(
387 WideToUTF8(header), request.headers());
388 connection->Send(header_value, "");
391 // Convert |request_uri| to a path.
392 std::wstring path = request_uri;
393 size_t query_index = request_uri.find(L"?");
394 if (query_index != std::string::npos) {
395 path = path.erase(query_index);
397 base::FilePath file_path = root_dir_;
399 file_path = file_path.Append(path.substr(1)); // remove first '/'
401 std::string headers, body;
402 std::string content_type;
403 if (base::PathExists(file_path) &&
404 !base::DirectoryExists(file_path)) {
405 base::FilePath mock_http_headers(file_path.value() + L".mock-http-headers");
406 if (base::PathExists(mock_http_headers)) {
407 headers = GetMockHttpHeaders(mock_http_headers);
408 content_type = http_utils::GetHttpHeaderFromHeaderList("Content-type",
411 EXPECT_TRUE(net::GetMimeTypeFromFile(file_path, &content_type));
412 VLOG(1) << "Going to send file (" << WideToUTF8(file_path.value())
413 << ") with content type (" << content_type << ")";
414 headers = CreateHttpHeaders(invocation, add_no_cache_header,
418 EXPECT_FALSE(headers.empty());
420 EXPECT_TRUE(base::ReadFileToString(file_path, &body))
421 << "Could not read file (" << WideToUTF8(file_path.value()) << ")";
422 if (invocation.type() == CFInvocation::META_TAG &&
423 StartsWithASCII(content_type, "text/html", false)) {
424 EXPECT_TRUE(chrome_frame_test::AddCFMetaTag(&body)) << "Could not add "
425 << "meta tag to HTML file.";
428 VLOG(1) << "Going to send 404 for non-existent file ("
429 << WideToUTF8(file_path.value()) << ")";
430 headers = "HTTP/1.1 404 Not Found";
433 connection->Send(headers, body);
436 const wchar_t kPostMessageBasicPage[] = L"postmessage_basic_host.html";
438 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PostMessageBasic) {
439 SimpleBrowserTest(IE, kPostMessageBasicPage);
442 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_MIMEFilterBasic) {
443 const wchar_t kMIMEFilterBasicPage[] =
444 L"chrome_frame_mime_filter_test.html";
446 // If this test fails for IE8 then it is possible that prebinding is enabled.
447 // A known workaround is to disable it until CF properly handles it.
449 // HKCU\Software\Microsoft\Internet Explorer\Main
450 // Value name: EnablePreBinding (REG_DWORD)
452 SimpleBrowserTest(IE, kMIMEFilterBasicPage);
455 // Times out: http://crbug.com/163728
456 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_Resize) {
457 SimpleBrowserTest(IE, L"chrome_frame_resize.html");
460 const wchar_t kNavigateURLAbsolutePage[] =
461 L"navigateurl_absolute_host.html";
463 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLAbsolute) {
464 SimpleBrowserTest(IE, kNavigateURLAbsolutePage);
467 const wchar_t kNavigateURLRelativePage[] =
468 L"navigateurl_relative_host.html";
470 // Flaky, crbug.com/160497.
471 TEST_F(ChromeFrameTestWithWebServer,
472 DISABLED_WidgetModeIE_NavigateURLRelative) {
473 SimpleBrowserTest(IE, kNavigateURLRelativePage);
476 const wchar_t kNavigateSimpleObjectFocus[] = L"simple_object_focus.html";
478 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_ObjectFocus) {
479 SimpleBrowserTest(IE, kNavigateSimpleObjectFocus);
482 const wchar_t kiframeBasicPage[] = L"iframe_basic_host.html";
485 // Flaky, crbug.com/160497.
486 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_iframeBasic) {
487 SimpleBrowserTest(IE, kiframeBasicPage);
490 const wchar_t kSrcPropertyTestPage[] = L"src_property_host.html";
492 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_SrcProperty) {
493 SimpleBrowserTest(IE, kSrcPropertyTestPage);
496 const wchar_t kCFInstanceBasicTestPage[] = L"CFInstance_basic_host.html";
498 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceBasic) {
499 SimpleBrowserTest(IE, kCFInstanceBasicTestPage);
502 const wchar_t kCFISingletonPage[] = L"CFInstance_singleton_host.html";
504 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceSingleton) {
505 SimpleBrowserTest(IE, kCFISingletonPage);
508 const wchar_t kCFIDelayPage[] = L"CFInstance_delay_host.html";
510 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDelay) {
511 SimpleBrowserTest(IE, kCFIDelayPage);
514 const wchar_t kCFIFallbackPage[] = L"CFInstance_fallback_host.html";
516 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceFallback) {
517 SimpleBrowserTest(IE, kCFIFallbackPage);
520 const wchar_t kCFINoSrcPage[] = L"CFInstance_no_src_host.html";
522 // Flaky, crbug.com/160497.
523 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceNoSrc) {
524 SimpleBrowserTest(IE, kCFINoSrcPage);
527 const wchar_t kCFIIfrOnLoadPage[] = L"CFInstance_iframe_onload_host.html";
529 // disabled since it's unlikely that we care about this case
530 TEST_F(ChromeFrameTestWithWebServer,
531 DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
532 SimpleBrowserTest(IE, kCFIIfrOnLoadPage);
535 const wchar_t kCFIZeroSizePage[] = L"CFInstance_zero_size_host.html";
537 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceZeroSize) {
538 SimpleBrowserTest(IE, kCFIZeroSizePage);
541 const wchar_t kCFIIfrPostPage[] = L"CFInstance_iframe_post_host.html";
543 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceIfrPost) {
544 SimpleBrowserTest(IE, kCFIIfrPostPage);
547 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceIfrPost) {
548 SimpleBrowserTest(CHROME, kCFIIfrPostPage);
551 const wchar_t kCFIPostPage[] = L"CFInstance_post_host.html";
553 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstancePost) {
554 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
555 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
558 SimpleBrowserTest(IE, kCFIPostPage);
561 // This test randomly fails on the ChromeFrame builder.
562 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstancePost) {
563 SimpleBrowserTest(CHROME, kCFIPostPage);
566 const wchar_t kCFIRPCPage[] = L"CFInstance_rpc_host.html";
568 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPC) {
569 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
570 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
573 SimpleBrowserTest(IE, kCFIRPCPage);
576 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPC) {
577 SimpleBrowserTest(CHROME, kCFIRPCPage);
580 const wchar_t kCFIRPCInternalPage[] =
581 L"CFInstance_rpc_internal_host.html";
583 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceRPCInternal) {
584 if (chrome_frame_test::GetInstalledIEVersion() == IE_9) {
585 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9";
588 SimpleBrowserTest(IE, kCFIRPCInternalPage);
591 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPCInternal) {
592 SimpleBrowserTest(CHROME, kCFIRPCInternalPage);
595 const wchar_t kCFIDefaultCtorPage[] =
596 L"CFInstance_default_ctor_host.html";
598 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDefaultCtor) {
599 SimpleBrowserTest(IE, kCFIDefaultCtorPage);
602 const wchar_t kCFInstallBasicTestPage[] = L"CFInstall_basic.html";
604 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallBasic) {
605 SimpleBrowserTest(IE, kCFInstallBasicTestPage);
608 const wchar_t kCFInstallPlaceTestPage[] = L"CFInstall_place.html";
610 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallPlace) {
611 SimpleBrowserTest(IE, kCFInstallPlaceTestPage);
614 const wchar_t kCFInstallOverlayTestPage[] = L"CFInstall_overlay.html";
616 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallOverlay) {
617 SimpleBrowserTest(IE, kCFInstallOverlayTestPage);
620 const wchar_t kCFInstallDismissTestPage[] = L"CFInstall_dismiss.html";
622 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallDismiss) {
623 SimpleBrowserTest(IE, kCFInstallDismissTestPage);
626 const wchar_t kInitializeHiddenPage[] = L"initialize_hidden.html";
627 // Times out: http://crbug.com/163728
628 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_InitializeHidden) {
629 SimpleBrowserTest(IE, kInitializeHiddenPage);
632 const wchar_t kFullTabHttpHeaderPage[] = L"chrome_frame_http_header.html";
634 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderBasic) {
635 SimpleBrowserTest(IE, kFullTabHttpHeaderPage);
638 const wchar_t kFullTabHttpHeaderPageIFrame[] =
639 L"chrome_frame_http_header_host.html";
641 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderIFrame) {
642 SimpleBrowserTest(IE, kFullTabHttpHeaderPageIFrame);
645 const wchar_t kFullTabHttpHeaderPageFrameset[] =
646 L"chrome_frame_http_header_frameset.html";
648 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderFrameSet) {
649 SimpleBrowserTest(IE, kFullTabHttpHeaderPageFrameset);
652 const wchar_t kVersionPage[] = L"version.html";
654 // Flaky, crbug.com/160497.
655 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_Version) {
656 VersionTest(IE, kVersionPage);
659 const wchar_t kEventListenerPage[] = L"event_listener.html";
661 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_EventListener) {
662 SimpleBrowserTest(IE, kEventListenerPage);
665 const wchar_t kPrivilegedApisPage[] = L"privileged_apis_host.html";
667 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PrivilegedApis) {
668 SimpleBrowserTest(IE, kPrivilegedApisPage);
671 const wchar_t kMetaTagPage[] = L"meta_tag.html";
672 // Flaky, crbug.com/160497.
673 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_MetaTag) {
674 SimpleBrowserTest(IE, kMetaTagPage);
677 // Times out: http://crbug.com/163728
678 const wchar_t kCFProtocolPage[] = L"cf_protocol.html";
679 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_CFProtocol) {
680 // Temporarily enable gcf: protocol for this test.
681 SetConfigBool(kAllowUnsafeURLs, true);
682 SimpleBrowserTest(IE, kCFProtocolPage);
683 SetConfigBool(kAllowUnsafeURLs, false);
686 const wchar_t kPersistentCookieTest[] =
687 L"persistent_cookie_test_page.html";
688 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_PersistentCookieTest) {
689 SimpleBrowserTest(IE, kPersistentCookieTest);
692 const wchar_t kNavigateOutPage[] = L"navigate_out.html";
693 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_NavigateOut) {
694 SimpleBrowserTest(IE, kNavigateOutPage);
697 const wchar_t kReferrerMainTest[] = L"referrer_main.html";
699 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ReferrerTest) {
700 SimpleBrowserTest(IE, kReferrerMainTest);
703 // Times out: http://crbug.com/163728
704 const wchar_t kSubFrameTestPage[] = L"full_tab_sub_frame_main.html";
705 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_SubFrame) {
706 SimpleBrowserTest(IE, kSubFrameTestPage);
709 const wchar_t kSubIFrameTestPage[] = L"full_tab_sub_iframe_main.html";
710 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SubIFrame) {
711 SimpleBrowserTest(IE, kSubIFrameTestPage);
714 const wchar_t kXMLHttpRequestTestUrl[] =
715 L"xmlhttprequest_test.html";
717 // Flaky, crbug.com/160497.
718 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_XHRTest) {
719 SimpleBrowserTest(IE, kXMLHttpRequestTestUrl);
722 const wchar_t kInstallFlowTestUrl[] =
723 L"install_flow_test.html";
725 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_InstallFlowTest) {
726 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
727 ScopedChromeFrameRegistrar::UnregisterAtPath(
728 GetChromeFrameBuildPath().value(),
729 chrome_frame_test::GetTestBedType());
731 ASSERT_TRUE(LaunchBrowser(IE, kInstallFlowTestUrl));
733 loop().RunFor(kChromeFrameLongNavigationTimeout);
735 ScopedChromeFrameRegistrar::RegisterAtPath(
736 GetChromeFrameBuildPath().value(),
737 chrome_frame_test::GetTestBedType());
739 ExpectAndHandlePostedResult();
740 loop().RunFor(kChromeFrameLongNavigationTimeout);
742 chrome_frame_test::CloseAllIEWindows();
743 ASSERT_EQ("OK", server_mock().posted_result());
747 const wchar_t kMultipleCFInstancesTestUrl[] =
748 L"multiple_cf_instances_main.html";
750 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_MultipleCFInstances) {
751 SimpleBrowserTest(IE, kMultipleCFInstancesTestUrl);
754 const wchar_t kXHRHeaderTestUrl[] =
755 L"xmlhttprequest_header_test.html";
757 // Marking as flaky since it occasionally times out. crbug.com/127395.
758 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_XHRHeaderTest) {
759 SimpleBrowserTest(IE, kXHRHeaderTestUrl);
762 const wchar_t kDeleteCookieTest[] =
763 L"fulltab_delete_cookie_test.html";
765 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_DeleteCookieTest) {
766 SimpleBrowserTest(IE, kDeleteCookieTest);
769 const wchar_t kAnchorUrlNavigate[] =
770 L"fulltab_anchor_url_navigate.html#chrome_frame";
772 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_AnchorUrlNavigateTest) {
773 SimpleBrowserTest(IE, kAnchorUrlNavigate);
776 // Test whether POST-ing a form from an mshtml page to a CF page will cause
777 // the request to get reissued. It should not.
778 // https://code.google.com/p/chromium/issues/detail?id=143699
779 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_TestPostReissue) {
780 // The order of pages in this array is assumed to be mshtml, cf, script.
781 const wchar_t* kPages[] = {
782 L"full_tab_post_mshtml.html",
783 L"full_tab_post_target_cf.html",
784 L"chrome_frame_tester_helpers.js",
787 SimpleWebServerTest server(local_address_, 46664);
788 server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
789 arraysize(kPages), GetCFTestFilePath());
791 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
793 loop().RunFor(kChromeFrameLongNavigationTimeout);
795 const test_server::Request* request = NULL;
796 server.FindRequest("/quit?OK", &request);
797 ASSERT_TRUE(request != NULL);
798 EXPECT_EQ("OK", request->arguments());
800 if (request->arguments().compare("OK") == 0) {
801 // Check how many requests we got for the cf page. Also expect it to be
803 int requests = server.GetRequestCountForPage(kPages[1], "POST");
804 EXPECT_EQ(1, requests);
808 // Test whether following a link from an mshtml page to a CF page will cause
809 // multiple network requests. It should not.
810 // Flaky, crbug.com/160497.
811 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_TestMultipleGet) {
812 // The order of pages in this array is assumed to be mshtml, cf, script.
813 const wchar_t* kPages[] = {
814 L"full_tab_get_mshtml.html",
815 L"full_tab_get_target_cf.html",
816 L"chrome_frame_tester_helpers.js",
819 SimpleWebServerTest server(local_address_, 46664);
821 server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
822 arraysize(kPages), GetCFTestFilePath());
824 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
826 loop().RunFor(kChromeFrameVeryLongNavigationTimeout);
828 const test_server::Request* request = NULL;
829 server.FindRequest("/quit?OK", &request);
830 ASSERT_TRUE(request != NULL);
831 EXPECT_EQ("OK", request->arguments());
833 if (request->arguments().compare("OK") == 0) {
834 // Check how many requests we got for the cf page and check that it was
836 int requests = server.GetRequestCountForPage(kPages[1], "GET");
837 EXPECT_EQ(1, requests);
841 const wchar_t kSetCookieTest[] =
842 L"fulltab_set_cookie_test.html";
844 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SetCookieTest) {
845 SimpleBrowserTest(IE, kSetCookieTest);
848 const wchar_t kXHRConditionalHeaderTestUrl[] =
849 L"xmlhttprequest_conditional_header_test.html";
851 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_XHRConditionalHeaderTest) {
852 SimpleBrowserTest(IE, kXHRConditionalHeaderTestUrl);
855 const wchar_t kWindowCloseTestUrl[] =
856 L"window_close.html";
858 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowClose) {
859 SimpleBrowserTest(IE, kWindowCloseTestUrl);
862 std::string GetHeaderValue(const std::string& headers,
863 const char* header_name) {
864 net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(),
866 while (it.GetNext()) {
867 if (lstrcmpiA(it.name().c_str(), header_name) == 0) {
874 // Specialized implementation of test_server::FileResponse that supports
875 // adding the request's User-Agent header to the returned document.
876 // The class also supports $request_id$ which will be replaced with an
877 // id that's incremented each time the response is sent over a socket.
878 class UaTemplateFileResponse : public test_server::FileResponse {
880 typedef test_server::FileResponse SuperClass;
882 UaTemplateFileResponse(const char* request_path,
883 const base::FilePath& file_path)
884 : test_server::FileResponse(request_path, file_path), request_id_(0) {
887 virtual bool Matches(const test_server::Request& r) const {
888 bool ret = SuperClass::Matches(r);
890 ua_ = GetHeaderValue(r.headers(), "User-Agent");
894 virtual size_t ContentLength() const {
895 const char kRequestIdTemplate[] = "$request_id$";
896 const char kUserAgentTemplate[] = "$UA$";
898 size_t length = SuperClass::ContentLength();
900 content_.assign(reinterpret_cast<const char*>(file_->data()),
902 size_t i = content_.find(kUserAgentTemplate);
903 if (i != std::string::npos)
904 content_.replace(i, arraysize(kUserAgentTemplate) - 1, ua_);
905 i = content_.find(kRequestIdTemplate);
906 if (i != std::string::npos) {
907 content_.replace(i, arraysize(kRequestIdTemplate) - 1,
908 base::StringPrintf("%i", request_id_));
910 return content_.length();
913 virtual void WriteContents(net::StreamListenSocket* socket) const {
914 DCHECK(content_.length());
915 socket->Send(content_.c_str(), content_.length(), false);
920 mutable std::string ua_;
921 mutable std::string content_;
922 mutable int request_id_;
925 // This test simulates a URL that on first request returns a document
926 // that should be rendered in mshtml, then pops up a sign-in page that
927 // after signing in, refreshes the original page that should then return
928 // a page that needs to be rendered in GCF.
930 // This test currently fails because GCF does not add the chromeframe header
931 // to requests that mshtml initiates via IInternetSession::CreateBinding.
932 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_RefreshMshtmlTest) {
933 const wchar_t* kPages[] = {
934 L"mshtml_refresh_test.html",
935 L"mshtml_refresh_test_popup.html",
938 SimpleWebServerTest server(local_address_, 46664);
939 server.PopulateStaticFileListT<UaTemplateFileResponse>(kPages,
940 arraysize(kPages), GetCFTestFilePath());
942 ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
944 loop().RunFor(kChromeFrameLongNavigationTimeout);
946 test_server::SimpleWebServer* ws = server.web_server();
947 const test_server::ConnectionList& connections = ws->connections();
948 test_server::ConnectionList::const_iterator it = connections.begin();
949 int requests_for_first_page = 0;
950 for (; it != connections.end(); ++it) {
951 test_server::Connection* c = (*it);
952 const test_server::Request& r = c->request();
953 if (!r.path().empty() &&
954 ASCIIToWide(r.path().substr(1)).compare(kPages[0]) == 0) {
955 requests_for_first_page++;
956 std::string ua(GetHeaderValue(r.headers(), "User-Agent"));
957 EXPECT_NE(std::string::npos, ua.find("chromeframe"));
960 EXPECT_GT(requests_for_first_page, 1);
963 // See bug 36694 for details. http://crbug.com/36694
964 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_TestDownloadFromForm) {
965 chrome_frame_test::MockWindowObserver win_observer_mock;
966 win_observer_mock.WatchWindow("File Download", "");
967 win_observer_mock.WatchWindow("View Downloads*", "");
969 // The content of our HTML test page. This will be returned whenever
970 // we reply to a GET request.
971 static const char kHtml[] =
973 "<title>ChromeFrame Form Download Test</title>\n"
974 // To see how this test runs with only IE (no CF in the picture), comment
975 // out this meta tag. The outcome of the test should be identical.
976 "<meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\" />\n"
978 "<script language=\"javascript\">\n"
979 "function SubmitForm() {\n"
980 " var form = document.forms['myform'];\n"
981 " form.action = document.location;\n"
986 "<body onload=\"SubmitForm();\">\n"
987 "<form method=\"post\" action=\"foo.html\" id=\"myform\">\n"
988 " <input type=\"hidden\" name=\"Field1\" value=\"myvalue\" />\n"
989 " <input type=\"button\" name=\"btn\" value=\"Test Download\" "
990 "onclick=\"return SubmitForm();\" id=\"Button1\"/>\n"
991 "</form></body></html>\n";
993 // The content of our HTML test page. This will be returned whenever
994 // we reply to a POST request.
995 static const char kText[] =
996 "This is a text file (in case you were wondering).";
998 // This http response class will return an HTML document that contains
999 // a form whenever it receives a GET request. Whenever it gets a POST
1000 // request, it will respond with a text file that needs to be downloaded
1001 // (content-disposition is "attachment").
1002 class CustomResponse : public test_server::ResponseForPath {
1004 explicit CustomResponse(const char* path)
1005 : test_server::ResponseForPath(path), is_post_(false),
1006 post_requests_(0), get_requests_(0) {
1009 virtual bool GetContentType(std::string* content_type) const {
1014 virtual size_t ContentLength() const {
1016 return sizeof(kHtml) - 1;
1019 virtual bool GetCustomHeaders(std::string* headers) const {
1022 *headers = base::StringPrintf(
1023 "HTTP/1.1 200 OK\r\n"
1024 "Content-Disposition: attachment;filename=\"test.txt\"\r\n"
1025 "Content-Type: application/text\r\n"
1026 "Connection: close\r\n"
1027 "Content-Length: %i\r\n\r\n", sizeof(kText) - 1);
1031 virtual bool Matches(const test_server::Request& r) const {
1032 bool match = __super::Matches(r);
1034 is_post_ = LowerCaseEqualsASCII(r.method().c_str(), "post");
1039 virtual void WriteContents(net::StreamListenSocket* socket) const {
1041 socket->Send(kText, sizeof(kText) - 1, false);
1043 socket->Send(kHtml, sizeof(kHtml) - 1, false);
1047 virtual void IncrementAccessCounter() {
1048 __super::IncrementAccessCounter();
1056 size_t get_request_count() const {
1057 return get_requests_;
1060 size_t post_request_count() const {
1061 return get_requests_;
1065 mutable bool is_post_;
1066 size_t post_requests_;
1067 size_t get_requests_;
1070 EXPECT_CALL(win_observer_mock, OnWindowOpen(_))
1071 .Times(testing::AtMost(1))
1072 .WillOnce(chrome_frame_test::DoCloseWindow());
1074 EXPECT_CALL(win_observer_mock, OnWindowClose(_))
1075 .Times(testing::AtMost(1))
1076 .WillOnce(QUIT_LOOP(loop()));
1078 SimpleWebServerTest server(local_address_, 46664);
1079 CustomResponse* response = new CustomResponse("/form.html");
1080 server.web_server()->AddResponse(response);
1082 std::wstring url(server.FormatHttpPath(L"form.html"));
1084 ASSERT_TRUE(LaunchBrowser(IE, url.c_str()));
1085 loop().RunFor(kChromeFrameLongNavigationTimeout);
1087 EXPECT_EQ(1, response->get_request_count());
1088 EXPECT_EQ(1, response->post_request_count());
1091 // This test loads a large page and ensures that the full page contents are
1092 // actually loaded via a self-validating HTML page. This is done due to a bug
1093 // whereby the middle of the response stream would sometimes be truncated when
1094 // loading a CF document. See http://crbug.com/178421 for details.
1095 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_LargePageLoad) {
1096 const wchar_t kLargePageLoadPage[] =
1097 L"chrome_frame_large_page.html";
1099 SimpleBrowserTest(IE, kLargePageLoadPage);