Home | History | Annotate | Download | only in test
      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 "chrome_frame/test/test_with_web_server.h"
      6 
      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"
     31 
     32 using chrome_frame_test::kChromeFrameLongNavigationTimeout;
     33 using chrome_frame_test::kChromeFrameVeryLongNavigationTimeout;
     34 
     35 using testing::_;
     36 using testing::StrCaseEq;
     37 
     38 const wchar_t kDocRoot[] = L"chrome_frame\\test\\data";
     39 
     40 namespace {
     41 
     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";
     55   }
     56   return ss.str();
     57 }
     58 
     59 std::string GetMockHttpHeaders(const base::FilePath& mock_http_headers_path) {
     60   std::string headers;
     61   base::ReadFileToString(mock_http_headers_path, &headers);
     62   return headers;
     63 }
     64 
     65 class ChromeFrameTestEnvironment: public testing::Environment {
     66  public:
     67   virtual ~ChromeFrameTestEnvironment() {}
     68   virtual void SetUp() OVERRIDE {
     69     ScopedChromeFrameRegistrar::RegisterDefaults();
     70   }
     71 };
     72 
     73 ::testing::Environment* const chrome_frame_env =
     74     ::testing::AddGlobalTestEnvironment(new ChromeFrameTestEnvironment);
     75 
     76 }  // namespace
     77 
     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_;
     89 
     90 ChromeFrameTestWithWebServer::ChromeFrameTestWithWebServer() {
     91 }
     92 
     93 // static
     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"));
     99 
    100   test_file_path_ = chrome_frame_source_path
    101       .Append(FILE_PATH_LITERAL("test"))
    102       .Append(FILE_PATH_LITERAL("data"));
    103 
    104   results_dir_ = chrome_frame_test::GetTestDataFolder().AppendASCII("dump");
    105 
    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;
    110 
    111   CFInstance_src_path = chrome_frame_source_path.AppendASCII("CFInstance.js");
    112   CFInstance_path_ = test_file_path_.AppendASCII("CFInstance.js");
    113 
    114   ASSERT_TRUE(base::CopyFile(CFInstance_src_path, CFInstance_path_));
    115 
    116   CFInstall_src_path = chrome_frame_source_path.AppendASCII("CFInstall.js");
    117   CFInstall_path_ = test_file_path_.AppendASCII("CFInstall.js");
    118 
    119   ASSERT_TRUE(base::CopyFile(CFInstall_src_path, CFInstall_path_));
    120 
    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_);
    129 }
    130 
    131 // static
    132 void ChromeFrameTestWithWebServer::TearDownTestCase() {
    133   delete server_mock_;
    134   server_mock_ = NULL;
    135   delete listener_mock_;
    136   listener_mock_ = NULL;
    137   local_address_.clear();
    138   delete loop_;
    139   loop_ = NULL;
    140   base::DeleteFile(CFInstall_path_, false);
    141   base::DeleteFile(CFInstance_path_, false);
    142   if (temp_dir_.IsValid())
    143     EXPECT_TRUE(temp_dir_.Delete());
    144 }
    145 
    146 // static
    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");
    152   }
    153   return chrome_user_data_dir_;
    154 }
    155 
    156 void ChromeFrameTestWithWebServer::SetUp() {
    157   // Make sure that we are not accidentally enabling gcf protocol.
    158   SetConfigBool(kAllowUnsafeURLs, false);
    159 
    160   server_mock().ClearResults();
    161   server_mock().ExpectAndServeAnyRequests(CFInvocation(CFInvocation::NONE));
    162   server_mock().set_expected_result("OK");
    163 }
    164 
    165 void ChromeFrameTestWithWebServer::TearDown() {
    166   CloseBrowser();
    167   loop().RunUntilIdle();
    168   testing::Mock::VerifyAndClear(listener_mock_);
    169   testing::Mock::VerifyAndClear(server_mock_);
    170 }
    171 
    172 bool ChromeFrameTestWithWebServer::LaunchBrowser(BrowserKind browser,
    173                                                  const wchar_t* page) {
    174   std::wstring url = page;
    175 
    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);
    180   }
    181 
    182   browser_ = browser;
    183   if (browser == IE) {
    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));
    189   } else {
    190     NOTREACHED();
    191   }
    192 
    193   return browser_handle_.IsValid();
    194 }
    195 
    196 void ChromeFrameTestWithWebServer::CloseBrowser() {
    197   if (!browser_handle_.IsValid())
    198     return;
    199 
    200   int attempts = 0;
    201   if (browser_ == IE) {
    202     attempts = chrome_frame_test::CloseAllIEWindows();
    203   } else {
    204     attempts = chrome_frame_test::CloseVisibleWindowsOnAllThreads(
    205                                                                browser_handle_);
    206   }
    207 
    208   if (attempts > 0) {
    209     DWORD wait = ::WaitForSingleObject(browser_handle_, 20000);
    210     if (wait == WAIT_OBJECT_0) {
    211       browser_handle_.Close();
    212     } else {
    213       LOG(ERROR) << "WaitForSingleObject returned " << wait;
    214     }
    215   } else {
    216     LOG(ERROR) << "No attempts to close browser windows";
    217   }
    218 
    219   if (browser_handle_.IsValid()) {
    220     DWORD exit_code = 0;
    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);
    225     }
    226     browser_handle_.Close();
    227   }
    228 }
    229 
    230 bool ChromeFrameTestWithWebServer::BringBrowserToTop() {
    231   return simulate_input::EnsureProcessInForeground(
    232       GetProcessId(browser_handle_));
    233 }
    234 
    235 bool ChromeFrameTestWithWebServer::WaitForTestToComplete(
    236     base::TimeDelta duration) {
    237   loop().RunFor(duration);
    238   return !loop().WasTimedOut();
    239 }
    240 
    241 bool ChromeFrameTestWithWebServer::WaitForOnLoad(int milliseconds) {
    242   return false;
    243 }
    244 
    245 const wchar_t kPostedResultSubstring[] = L"/writefile/";
    246 
    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";
    252     return;
    253   }
    254 
    255   int tries = 0;
    256   ExpectAndHandlePostedResult();
    257   // Retry tests that timeout once; see http://crbug.com/96449.
    258   do {
    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());
    267       break;
    268     }
    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.
    273     CloseBrowser();
    274     LOG(ERROR) << "Retrying test once since it timed out.";
    275   } while (true);
    276   loop().set_snapshot_on_timeout(true);
    277 }
    278 
    279 void ChromeFrameTestWithWebServer::SimpleBrowserTest(BrowserKind browser,
    280     const wchar_t* page) {
    281   SimpleBrowserTestExpectedResult(browser, page, "OK");
    282 }
    283 
    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);
    290 }
    291 
    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);
    297 
    298   static FileVersionInfo* version_info =
    299       FileVersionInfo::CreateFileVersionInfo(plugin_path);
    300 
    301   std::wstring version;
    302   if (version_info)
    303     version = version_info->product_version();
    304 
    305   // If we can't find the Chrome Frame DLL in the src tree, we turn to
    306   // the directory where chrome is installed.
    307   if (!version_info) {
    308     BrowserDistribution* dist = BrowserDistribution::GetDistribution();
    309     Version ver_system;
    310     InstallUtil::GetChromeVersion(dist, true, &ver_system);
    311     Version ver_user;
    312     InstallUtil::GetChromeVersion(dist, false, &ver_system);
    313     ASSERT_TRUE(ver_system.IsValid() || ver_user.IsValid());
    314 
    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);
    321     if (version_info)
    322       version = version_info->product_version();
    323   }
    324 
    325   server_mock().set_expected_result(WideToUTF8(version));
    326 
    327   EXPECT_TRUE(version_info);
    328   EXPECT_FALSE(version.empty());
    329 
    330   SimpleBrowserTestExpectedResult(browser, page, WideToASCII(version).c_str());
    331 }
    332 
    333 // MockWebServer methods
    334 void MockWebServer::ExpectAndServeRequest(CFInvocation invocation,
    335                                           const std::wstring& url) {
    336   ExpectAndServeRequestWithCardinality(invocation, url, testing::Exactly(1));
    337 }
    338 
    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), _))
    343       .Times(cardinality)
    344       .WillRepeatedly(SendResponse(this, invocation));
    345 }
    346 
    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));
    351 }
    352 
    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));
    357 }
    358 
    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));
    363 }
    364 
    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", "");
    372 }
    373 
    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(
    383         wcslen(kEchoHeader),
    384         request_uri.length() - wcslen(kEchoHeader));
    385 
    386     std::string header_value = http_utils::GetHttpHeaderFromHeaderList(
    387         WideToUTF8(header), request.headers());
    388     connection->Send(header_value, "");
    389     return;
    390   }
    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);
    396   }
    397   base::FilePath file_path = root_dir_;
    398   if (path.size())
    399     file_path = file_path.Append(path.substr(1));  // remove first '/'
    400 
    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",
    409                                                              headers);
    410     } else {
    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,
    415                                   content_type);
    416     }
    417 
    418     EXPECT_FALSE(headers.empty());
    419 
    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.";
    426     }
    427   } else {
    428     VLOG(1) << "Going to send 404 for non-existent file ("
    429             << WideToUTF8(file_path.value()) << ")";
    430     headers = "HTTP/1.1 404 Not Found";
    431     body = "";
    432   }
    433   connection->Send(headers, body);
    434 }
    435 
    436 const wchar_t kPostMessageBasicPage[] = L"postmessage_basic_host.html";
    437 
    438 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PostMessageBasic) {
    439   SimpleBrowserTest(IE, kPostMessageBasicPage);
    440 }
    441 
    442 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_MIMEFilterBasic) {
    443   const wchar_t kMIMEFilterBasicPage[] =
    444       L"chrome_frame_mime_filter_test.html";
    445 
    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.
    448   //
    449   // HKCU\Software\Microsoft\Internet Explorer\Main
    450   // Value name: EnablePreBinding (REG_DWORD)
    451   // Value: 0
    452   SimpleBrowserTest(IE, kMIMEFilterBasicPage);
    453 }
    454 
    455 // Times out: http://crbug.com/163728
    456 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_Resize) {
    457   SimpleBrowserTest(IE, L"chrome_frame_resize.html");
    458 }
    459 
    460 const wchar_t kNavigateURLAbsolutePage[] =
    461     L"navigateurl_absolute_host.html";
    462 
    463 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_NavigateURLAbsolute) {
    464   SimpleBrowserTest(IE, kNavigateURLAbsolutePage);
    465 }
    466 
    467 const wchar_t kNavigateURLRelativePage[] =
    468     L"navigateurl_relative_host.html";
    469 
    470 // Flaky, crbug.com/160497.
    471 TEST_F(ChromeFrameTestWithWebServer,
    472        DISABLED_WidgetModeIE_NavigateURLRelative) {
    473   SimpleBrowserTest(IE, kNavigateURLRelativePage);
    474 }
    475 
    476 const wchar_t kNavigateSimpleObjectFocus[] = L"simple_object_focus.html";
    477 
    478 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_ObjectFocus) {
    479   SimpleBrowserTest(IE, kNavigateSimpleObjectFocus);
    480 }
    481 
    482 const wchar_t kiframeBasicPage[] = L"iframe_basic_host.html";
    483 
    484 
    485 // Flaky, crbug.com/160497.
    486 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_iframeBasic) {
    487   SimpleBrowserTest(IE, kiframeBasicPage);
    488 }
    489 
    490 const wchar_t kSrcPropertyTestPage[] = L"src_property_host.html";
    491 
    492 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_SrcProperty) {
    493   SimpleBrowserTest(IE, kSrcPropertyTestPage);
    494 }
    495 
    496 const wchar_t kCFInstanceBasicTestPage[] = L"CFInstance_basic_host.html";
    497 
    498 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceBasic) {
    499   SimpleBrowserTest(IE, kCFInstanceBasicTestPage);
    500 }
    501 
    502 const wchar_t kCFISingletonPage[] = L"CFInstance_singleton_host.html";
    503 
    504 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceSingleton) {
    505   SimpleBrowserTest(IE, kCFISingletonPage);
    506 }
    507 
    508 const wchar_t kCFIDelayPage[] = L"CFInstance_delay_host.html";
    509 
    510 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDelay) {
    511   SimpleBrowserTest(IE, kCFIDelayPage);
    512 }
    513 
    514 const wchar_t kCFIFallbackPage[] = L"CFInstance_fallback_host.html";
    515 
    516 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceFallback) {
    517   SimpleBrowserTest(IE, kCFIFallbackPage);
    518 }
    519 
    520 const wchar_t kCFINoSrcPage[] = L"CFInstance_no_src_host.html";
    521 
    522 // Flaky, crbug.com/160497.
    523 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_CFInstanceNoSrc) {
    524   SimpleBrowserTest(IE, kCFINoSrcPage);
    525 }
    526 
    527 const wchar_t kCFIIfrOnLoadPage[] = L"CFInstance_iframe_onload_host.html";
    528 
    529 // disabled since it's unlikely that we care about this case
    530 TEST_F(ChromeFrameTestWithWebServer,
    531        DISABLED_WidgetModeIE_CFInstanceIfrOnLoad) {
    532   SimpleBrowserTest(IE, kCFIIfrOnLoadPage);
    533 }
    534 
    535 const wchar_t kCFIZeroSizePage[] = L"CFInstance_zero_size_host.html";
    536 
    537 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceZeroSize) {
    538   SimpleBrowserTest(IE, kCFIZeroSizePage);
    539 }
    540 
    541 const wchar_t kCFIIfrPostPage[] = L"CFInstance_iframe_post_host.html";
    542 
    543 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceIfrPost) {
    544   SimpleBrowserTest(IE, kCFIIfrPostPage);
    545 }
    546 
    547 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceIfrPost) {
    548   SimpleBrowserTest(CHROME, kCFIIfrPostPage);
    549 }
    550 
    551 const wchar_t kCFIPostPage[] = L"CFInstance_post_host.html";
    552 
    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";
    556     return;
    557   }
    558   SimpleBrowserTest(IE, kCFIPostPage);
    559 }
    560 
    561 // This test randomly fails on the ChromeFrame builder.
    562 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstancePost) {
    563   SimpleBrowserTest(CHROME, kCFIPostPage);
    564 }
    565 
    566 const wchar_t kCFIRPCPage[] = L"CFInstance_rpc_host.html";
    567 
    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";
    571     return;
    572   }
    573   SimpleBrowserTest(IE, kCFIRPCPage);
    574 }
    575 
    576 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPC) {
    577   SimpleBrowserTest(CHROME, kCFIRPCPage);
    578 }
    579 
    580 const wchar_t kCFIRPCInternalPage[] =
    581     L"CFInstance_rpc_internal_host.html";
    582 
    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";
    586     return;
    587   }
    588   SimpleBrowserTest(IE, kCFIRPCInternalPage);
    589 }
    590 
    591 TEST_F(ChromeFrameTestWithWebServer, WidgetModeChrome_CFInstanceRPCInternal) {
    592   SimpleBrowserTest(CHROME, kCFIRPCInternalPage);
    593 }
    594 
    595 const wchar_t kCFIDefaultCtorPage[] =
    596     L"CFInstance_default_ctor_host.html";
    597 
    598 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_CFInstanceDefaultCtor) {
    599   SimpleBrowserTest(IE, kCFIDefaultCtorPage);
    600 }
    601 
    602 const wchar_t kCFInstallBasicTestPage[] = L"CFInstall_basic.html";
    603 
    604 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallBasic) {
    605   SimpleBrowserTest(IE, kCFInstallBasicTestPage);
    606 }
    607 
    608 const wchar_t kCFInstallPlaceTestPage[] = L"CFInstall_place.html";
    609 
    610 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallPlace) {
    611   SimpleBrowserTest(IE, kCFInstallPlaceTestPage);
    612 }
    613 
    614 const wchar_t kCFInstallOverlayTestPage[] = L"CFInstall_overlay.html";
    615 
    616 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallOverlay) {
    617   SimpleBrowserTest(IE, kCFInstallOverlayTestPage);
    618 }
    619 
    620 const wchar_t kCFInstallDismissTestPage[] = L"CFInstall_dismiss.html";
    621 
    622 TEST_F(ChromeFrameTestWithWebServer, FullTabIE_CFInstallDismiss) {
    623   SimpleBrowserTest(IE, kCFInstallDismissTestPage);
    624 }
    625 
    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);
    630 }
    631 
    632 const wchar_t kFullTabHttpHeaderPage[] = L"chrome_frame_http_header.html";
    633 
    634 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderBasic) {
    635   SimpleBrowserTest(IE, kFullTabHttpHeaderPage);
    636 }
    637 
    638 const wchar_t kFullTabHttpHeaderPageIFrame[] =
    639     L"chrome_frame_http_header_host.html";
    640 
    641 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderIFrame) {
    642   SimpleBrowserTest(IE, kFullTabHttpHeaderPageIFrame);
    643 }
    644 
    645 const wchar_t kFullTabHttpHeaderPageFrameset[] =
    646     L"chrome_frame_http_header_frameset.html";
    647 
    648 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_CFHttpHeaderFrameSet) {
    649   SimpleBrowserTest(IE, kFullTabHttpHeaderPageFrameset);
    650 }
    651 
    652 const wchar_t kVersionPage[] = L"version.html";
    653 
    654 // Flaky, crbug.com/160497.
    655 TEST_F(ChromeFrameTestWithWebServer, DISABLED_WidgetModeIE_Version) {
    656   VersionTest(IE, kVersionPage);
    657 }
    658 
    659 const wchar_t kEventListenerPage[] = L"event_listener.html";
    660 
    661 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_EventListener) {
    662   SimpleBrowserTest(IE, kEventListenerPage);
    663 }
    664 
    665 const wchar_t kPrivilegedApisPage[] = L"privileged_apis_host.html";
    666 
    667 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_PrivilegedApis) {
    668   SimpleBrowserTest(IE, kPrivilegedApisPage);
    669 }
    670 
    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);
    675 }
    676 
    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);
    684 }
    685 
    686 const wchar_t kPersistentCookieTest[] =
    687     L"persistent_cookie_test_page.html";
    688 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_PersistentCookieTest) {
    689   SimpleBrowserTest(IE, kPersistentCookieTest);
    690 }
    691 
    692 const wchar_t kNavigateOutPage[] = L"navigate_out.html";
    693 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_NavigateOut) {
    694   SimpleBrowserTest(IE, kNavigateOutPage);
    695 }
    696 
    697 const wchar_t kReferrerMainTest[] = L"referrer_main.html";
    698 
    699 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ReferrerTest) {
    700   SimpleBrowserTest(IE, kReferrerMainTest);
    701 }
    702 
    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);
    707 }
    708 
    709 const wchar_t kSubIFrameTestPage[] = L"full_tab_sub_iframe_main.html";
    710 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SubIFrame) {
    711   SimpleBrowserTest(IE, kSubIFrameTestPage);
    712 }
    713 
    714 const wchar_t kXMLHttpRequestTestUrl[] =
    715     L"xmlhttprequest_test.html";
    716 
    717 // Flaky, crbug.com/160497.
    718 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_XHRTest) {
    719   SimpleBrowserTest(IE, kXMLHttpRequestTestUrl);
    720 }
    721 
    722 const wchar_t kInstallFlowTestUrl[] =
    723     L"install_flow_test.html";
    724 
    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());
    730 
    731     ASSERT_TRUE(LaunchBrowser(IE, kInstallFlowTestUrl));
    732 
    733     loop().RunFor(kChromeFrameLongNavigationTimeout);
    734 
    735     ScopedChromeFrameRegistrar::RegisterAtPath(
    736         GetChromeFrameBuildPath().value(),
    737         chrome_frame_test::GetTestBedType());
    738 
    739     ExpectAndHandlePostedResult();
    740     loop().RunFor(kChromeFrameLongNavigationTimeout);
    741 
    742     chrome_frame_test::CloseAllIEWindows();
    743     ASSERT_EQ("OK", server_mock().posted_result());
    744   }
    745 }
    746 
    747 const wchar_t kMultipleCFInstancesTestUrl[] =
    748     L"multiple_cf_instances_main.html";
    749 
    750 TEST_F(ChromeFrameTestWithWebServer, WidgetModeIE_MultipleCFInstances) {
    751   SimpleBrowserTest(IE, kMultipleCFInstancesTestUrl);
    752 }
    753 
    754 const wchar_t kXHRHeaderTestUrl[] =
    755     L"xmlhttprequest_header_test.html";
    756 
    757 // Marking as flaky since it occasionally times out. crbug.com/127395.
    758 TEST_F(ChromeFrameTestWithWebServer, DISABLED_FullTabModeIE_XHRHeaderTest) {
    759   SimpleBrowserTest(IE, kXHRHeaderTestUrl);
    760 }
    761 
    762 const wchar_t kDeleteCookieTest[] =
    763     L"fulltab_delete_cookie_test.html";
    764 
    765 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_DeleteCookieTest) {
    766   SimpleBrowserTest(IE, kDeleteCookieTest);
    767 }
    768 
    769 const wchar_t kAnchorUrlNavigate[] =
    770     L"fulltab_anchor_url_navigate.html#chrome_frame";
    771 
    772 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_AnchorUrlNavigateTest) {
    773   SimpleBrowserTest(IE, kAnchorUrlNavigate);
    774 }
    775 
    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",
    785   };
    786 
    787   SimpleWebServerTest server(local_address_, 46664);
    788   server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
    789       arraysize(kPages), GetCFTestFilePath());
    790 
    791   ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
    792 
    793   loop().RunFor(kChromeFrameLongNavigationTimeout);
    794 
    795   const test_server::Request* request = NULL;
    796   server.FindRequest("/quit?OK", &request);
    797   ASSERT_TRUE(request != NULL);
    798   EXPECT_EQ("OK", request->arguments());
    799 
    800   if (request->arguments().compare("OK") == 0) {
    801     // Check how many requests we got for the cf page.  Also expect it to be
    802     // a POST.
    803     int requests = server.GetRequestCountForPage(kPages[1], "POST");
    804     EXPECT_EQ(1, requests);
    805   }
    806 }
    807 
    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",
    817   };
    818 
    819   SimpleWebServerTest server(local_address_, 46664);
    820 
    821   server.PopulateStaticFileListT<test_server::FileResponse>(kPages,
    822       arraysize(kPages), GetCFTestFilePath());
    823 
    824   ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
    825 
    826   loop().RunFor(kChromeFrameVeryLongNavigationTimeout);
    827 
    828   const test_server::Request* request = NULL;
    829   server.FindRequest("/quit?OK", &request);
    830   ASSERT_TRUE(request != NULL);
    831   EXPECT_EQ("OK", request->arguments());
    832 
    833   if (request->arguments().compare("OK") == 0) {
    834     // Check how many requests we got for the cf page and check that it was
    835     // a GET.
    836     int requests = server.GetRequestCountForPage(kPages[1], "GET");
    837     EXPECT_EQ(1, requests);
    838   }
    839 }
    840 
    841 const wchar_t kSetCookieTest[] =
    842     L"fulltab_set_cookie_test.html";
    843 
    844 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_SetCookieTest) {
    845   SimpleBrowserTest(IE, kSetCookieTest);
    846 }
    847 
    848 const wchar_t kXHRConditionalHeaderTestUrl[] =
    849     L"xmlhttprequest_conditional_header_test.html";
    850 
    851 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_XHRConditionalHeaderTest) {
    852   SimpleBrowserTest(IE, kXHRConditionalHeaderTestUrl);
    853 }
    854 
    855 const wchar_t kWindowCloseTestUrl[] =
    856     L"window_close.html";
    857 
    858 TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_WindowClose) {
    859   SimpleBrowserTest(IE, kWindowCloseTestUrl);
    860 }
    861 
    862 std::string GetHeaderValue(const std::string& headers,
    863                            const char* header_name) {
    864   net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(),
    865                                     "\r\n");
    866   while (it.GetNext()) {
    867     if (lstrcmpiA(it.name().c_str(), header_name) == 0) {
    868       return it.values();
    869     }
    870   }
    871   return "";
    872 }
    873 
    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 {
    879  public:
    880   typedef test_server::FileResponse SuperClass;
    881 
    882   UaTemplateFileResponse(const char* request_path,
    883                          const base::FilePath& file_path)
    884       : test_server::FileResponse(request_path, file_path), request_id_(0) {
    885   }
    886 
    887   virtual bool Matches(const test_server::Request& r) const {
    888     bool ret = SuperClass::Matches(r);
    889     if (ret)
    890       ua_ = GetHeaderValue(r.headers(), "User-Agent");
    891     return ret;
    892   }
    893 
    894   virtual size_t ContentLength() const {
    895     const char kRequestIdTemplate[] = "$request_id$";
    896     const char kUserAgentTemplate[] = "$UA$";
    897 
    898     size_t length = SuperClass::ContentLength();
    899     DCHECK(length);
    900     content_.assign(reinterpret_cast<const char*>(file_->data()),
    901                     file_->length());
    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_));
    909     }
    910     return content_.length();
    911   }
    912 
    913   virtual void WriteContents(net::StreamListenSocket* socket) const {
    914     DCHECK(content_.length());
    915     socket->Send(content_.c_str(), content_.length(), false);
    916     request_id_++;
    917   }
    918 
    919  protected:
    920   mutable std::string ua_;
    921   mutable std::string content_;
    922   mutable int request_id_;
    923 };
    924 
    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.
    929 //
    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",
    936   };
    937 
    938   SimpleWebServerTest server(local_address_, 46664);
    939   server.PopulateStaticFileListT<UaTemplateFileResponse>(kPages,
    940       arraysize(kPages), GetCFTestFilePath());
    941 
    942   ASSERT_TRUE(LaunchBrowser(IE, server.FormatHttpPath(kPages[0]).c_str()));
    943 
    944   loop().RunFor(kChromeFrameLongNavigationTimeout);
    945 
    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"));
    958     }
    959   }
    960   EXPECT_GT(requests_for_first_page, 1);
    961 }
    962 
    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*", "");
    968 
    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[] =
    972       "<html><head>\n"
    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"
    977       "</head>\n"
    978       "<script language=\"javascript\">\n"
    979       "function SubmitForm() {\n"
    980       "  var form = document.forms['myform'];\n"
    981       "  form.action = document.location;\n"
    982       "  form.submit();\n"
    983       "  return true;\n"
    984       "}\n"
    985       "</script>\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";
    992 
    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).";
    997 
    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 {
   1003    public:
   1004     explicit CustomResponse(const char* path)
   1005       : test_server::ResponseForPath(path), is_post_(false),
   1006         post_requests_(0), get_requests_(0) {
   1007     }
   1008 
   1009     virtual bool GetContentType(std::string* content_type) const {
   1010       DCHECK(!is_post_);
   1011       return false;
   1012     }
   1013 
   1014     virtual size_t ContentLength() const {
   1015       DCHECK(!is_post_);
   1016       return sizeof(kHtml) - 1;
   1017     }
   1018 
   1019     virtual bool GetCustomHeaders(std::string* headers) const {
   1020       if (!is_post_)
   1021         return false;
   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);
   1028       return true;
   1029     }
   1030 
   1031     virtual bool Matches(const test_server::Request& r) const {
   1032       bool match = __super::Matches(r);
   1033       if (match) {
   1034         is_post_ = LowerCaseEqualsASCII(r.method().c_str(), "post");
   1035       }
   1036       return match;
   1037     }
   1038 
   1039     virtual void WriteContents(net::StreamListenSocket* socket) const {
   1040       if (is_post_) {
   1041         socket->Send(kText, sizeof(kText) - 1, false);
   1042       } else {
   1043         socket->Send(kHtml, sizeof(kHtml) - 1, false);
   1044       }
   1045     }
   1046 
   1047     virtual void IncrementAccessCounter() {
   1048       __super::IncrementAccessCounter();
   1049       if (is_post_) {
   1050         post_requests_++;
   1051       } else {
   1052         get_requests_++;
   1053       }
   1054     }
   1055 
   1056     size_t get_request_count() const {
   1057       return get_requests_;
   1058     }
   1059 
   1060     size_t post_request_count() const {
   1061       return get_requests_;
   1062     }
   1063 
   1064    protected:
   1065     mutable bool is_post_;
   1066     size_t post_requests_;
   1067     size_t get_requests_;
   1068   };
   1069 
   1070   EXPECT_CALL(win_observer_mock, OnWindowOpen(_))
   1071       .Times(testing::AtMost(1))
   1072       .WillOnce(chrome_frame_test::DoCloseWindow());
   1073 
   1074   EXPECT_CALL(win_observer_mock, OnWindowClose(_))
   1075       .Times(testing::AtMost(1))
   1076       .WillOnce(QUIT_LOOP(loop()));
   1077 
   1078   SimpleWebServerTest server(local_address_, 46664);
   1079   CustomResponse* response = new CustomResponse("/form.html");
   1080   server.web_server()->AddResponse(response);
   1081 
   1082   std::wstring url(server.FormatHttpPath(L"form.html"));
   1083 
   1084   ASSERT_TRUE(LaunchBrowser(IE, url.c_str()));
   1085   loop().RunFor(kChromeFrameLongNavigationTimeout);
   1086 
   1087   EXPECT_EQ(1, response->get_request_count());
   1088   EXPECT_EQ(1, response->post_request_count());
   1089 }
   1090 
   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";
   1098 
   1099   SimpleBrowserTest(IE, kLargePageLoadPage);
   1100 }
   1101