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/test/ppapi/ppapi_test.h"
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/logging.h"
10 #include "base/path_service.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/test/test_timeouts.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/content_settings/host_content_settings_map.h"
17 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
18 #include "chrome/browser/infobars/infobar.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/ui/browser.h"
21 #include "chrome/browser/ui/browser_tabstrip.h"
22 #include "chrome/browser/ui/tabs/tab_strip_model.h"
23 #include "chrome/common/chrome_paths.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/test/base/test_switches.h"
26 #include "chrome/test/base/ui_test_utils.h"
27 #include "content/public/browser/dom_operation_notification_details.h"
28 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/common/content_paths.h"
32 #include "content/public/common/content_switches.h"
33 #include "content/public/test/browser_test_utils.h"
34 #include "content/public/test/test_renderer_host.h"
35 #include "net/base/net_util.h"
36 #include "net/base/test_data_directory.h"
37 #include "ppapi/shared_impl/ppapi_switches.h"
38 #include "ui/gl/gl_switches.h"
40 using content::DomOperationNotificationDetails;
41 using content::RenderViewHost;
45 // Platform-specific filename relative to the chrome executable.
47 const wchar_t library_name[] = L"ppapi_tests.dll";
48 #elif defined(OS_MACOSX)
49 const char library_name[] = "ppapi_tests.plugin";
50 #elif defined(OS_POSIX)
51 const char library_name[] = "libppapi_tests.so";
56 PPAPITestMessageHandler::PPAPITestMessageHandler() {
59 TestMessageHandler::MessageResponse PPAPITestMessageHandler::HandleMessage(
60 const std::string& json) {
62 TrimString(json, "\"", &trimmed);
63 if (trimmed == "...") {
71 void PPAPITestMessageHandler::Reset() {
72 TestMessageHandler::Reset();
76 PPAPITestBase::InfoBarObserver::InfoBarObserver() {
77 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
78 content::NotificationService::AllSources());
81 PPAPITestBase::InfoBarObserver::~InfoBarObserver() {
82 EXPECT_EQ(0u, expected_infobars_.size()) << "Missing an expected infobar";
85 void PPAPITestBase::InfoBarObserver::Observe(
87 const content::NotificationSource& source,
88 const content::NotificationDetails& details) {
89 ASSERT_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, type);
90 InfoBarDelegate* infobar =
91 content::Details<InfoBarAddedDetails>(details).ptr();
92 ConfirmInfoBarDelegate* confirm_infobar_delegate =
93 infobar->AsConfirmInfoBarDelegate();
94 ASSERT_TRUE(confirm_infobar_delegate);
96 ASSERT_FALSE(expected_infobars_.empty()) << "Unexpected infobar";
97 if (expected_infobars_.front())
98 confirm_infobar_delegate->Accept();
100 confirm_infobar_delegate->Cancel();
101 expected_infobars_.pop_front();
103 // TODO(bauerb): We should close the infobar.
106 void PPAPITestBase::InfoBarObserver::ExpectInfoBarAndAccept(
107 bool should_accept) {
108 expected_infobars_.push_back(should_accept);
111 PPAPITestBase::PPAPITestBase() {
114 void PPAPITestBase::SetUpCommandLine(CommandLine* command_line) {
115 // The test sends us the result via a cookie.
116 command_line->AppendSwitch(switches::kEnableFileCookies);
118 // Some stuff is hung off of the testing interface which is not enabled
120 command_line->AppendSwitch(switches::kEnablePepperTesting);
122 // Smooth scrolling confuses the scrollbar test.
123 command_line->AppendSwitch(switches::kDisableSmoothScrolling);
125 // For TestRequestOSFileHandle.
126 command_line->AppendSwitch(switches::kUnlimitedStorage);
127 command_line->AppendSwitchASCII(switches::kAllowNaClFileHandleAPI,
131 void PPAPITestBase::SetUpOnMainThread() {
132 // Always allow access to the PPAPI broker.
133 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
134 CONTENT_SETTINGS_TYPE_PPAPI_BROKER, CONTENT_SETTING_ALLOW);
137 GURL PPAPITestBase::GetTestFileUrl(const std::string& test_case) {
138 base::FilePath test_path;
139 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_path));
140 test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
141 test_path = test_path.Append(FILE_PATH_LITERAL("tests"));
142 test_path = test_path.Append(FILE_PATH_LITERAL("test_case.html"));
144 // Sanity check the file name.
145 EXPECT_TRUE(base::PathExists(test_path));
147 GURL test_url = net::FilePathToFileURL(test_path);
149 GURL::Replacements replacements;
150 std::string query = BuildQuery(std::string(), test_case);
151 replacements.SetQuery(query.c_str(), url_parse::Component(0, query.size()));
152 return test_url.ReplaceComponents(replacements);
155 void PPAPITestBase::RunTest(const std::string& test_case) {
156 GURL url = GetTestFileUrl(test_case);
160 void PPAPITestBase::RunTestAndReload(const std::string& test_case) {
161 GURL url = GetTestFileUrl(test_case);
163 // If that passed, we simply run the test again, which navigates again.
167 void PPAPITestBase::RunTestViaHTTP(const std::string& test_case) {
168 base::FilePath document_root;
169 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
170 base::FilePath http_document_root;
171 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
172 net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
173 net::SpawnedTestServer::kLocalhost,
175 ASSERT_TRUE(http_server.Start());
176 RunTestURL(GetTestURL(http_server, test_case, std::string()));
179 void PPAPITestBase::RunTestWithSSLServer(const std::string& test_case) {
180 base::FilePath http_document_root;
181 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
182 net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
183 net::SpawnedTestServer::kLocalhost,
185 net::SpawnedTestServer ssl_server(net::SpawnedTestServer::TYPE_HTTPS,
186 net::BaseTestServer::SSLOptions(),
188 // Start the servers in parallel.
189 ASSERT_TRUE(http_server.StartInBackground());
190 ASSERT_TRUE(ssl_server.StartInBackground());
191 // Wait until they are both finished before continuing.
192 ASSERT_TRUE(http_server.BlockUntilStarted());
193 ASSERT_TRUE(ssl_server.BlockUntilStarted());
195 uint16_t port = ssl_server.host_port_pair().port();
196 RunTestURL(GetTestURL(http_server,
198 base::StringPrintf("ssl_server_port=%d", port)));
201 void PPAPITestBase::RunTestWithWebSocketServer(const std::string& test_case) {
202 base::FilePath http_document_root;
203 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
204 net::SpawnedTestServer http_server(net::SpawnedTestServer::TYPE_HTTP,
205 net::SpawnedTestServer::kLocalhost,
207 net::SpawnedTestServer ws_server(net::SpawnedTestServer::TYPE_WS,
208 net::SpawnedTestServer::kLocalhost,
209 net::GetWebSocketTestDataDirectory());
210 // Start the servers in parallel.
211 ASSERT_TRUE(http_server.StartInBackground());
212 ASSERT_TRUE(ws_server.StartInBackground());
213 // Wait until they are both finished before continuing.
214 ASSERT_TRUE(http_server.BlockUntilStarted());
215 ASSERT_TRUE(ws_server.BlockUntilStarted());
217 std::string host = ws_server.host_port_pair().HostForURL();
218 uint16_t port = ws_server.host_port_pair().port();
219 RunTestURL(GetTestURL(http_server,
222 "websocket_host=%s&websocket_port=%d",
227 void PPAPITestBase::RunTestIfAudioOutputAvailable(
228 const std::string& test_case) {
232 void PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(
233 const std::string& test_case) {
234 RunTestViaHTTP(test_case);
237 std::string PPAPITestBase::StripPrefixes(const std::string& test_name) {
238 const char* const prefixes[] = {
239 "FAILS_", "FLAKY_", "DISABLED_", "SLOW_" };
240 for (size_t i = 0; i < sizeof(prefixes)/sizeof(prefixes[0]); ++i)
241 if (test_name.find(prefixes[i]) == 0)
242 return test_name.substr(strlen(prefixes[i]));
246 void PPAPITestBase::RunTestURL(const GURL& test_url) {
247 #if defined(OS_WIN) && defined(USE_ASH)
248 // PPAPITests are broken in Ash browser tests (http://crbug.com/263548).
249 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) {
250 LOG(WARNING) << "PPAPITests are disabled for Ash browser tests.";
255 // See comment above TestingInstance in ppapi/test/testing_instance.h.
256 // Basically it sends messages using the DOM automation controller. The
257 // value of "..." means it's still working and we should continue to wait,
258 // any other value indicates completion (in this case it will start with
259 // "PASS" or "FAIL"). This keeps us from timing out on waits for long tests.
260 PPAPITestMessageHandler handler;
261 JavascriptTestObserver observer(
262 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
265 ui_test_utils::NavigateToURL(browser(), test_url);
267 ASSERT_TRUE(observer.Run()) << handler.error_message();
268 EXPECT_STREQ("PASS", handler.message().c_str());
271 GURL PPAPITestBase::GetTestURL(
272 const net::SpawnedTestServer& http_server,
273 const std::string& test_case,
274 const std::string& extra_params) {
275 std::string query = BuildQuery("files/test_case.html?", test_case);
276 if (!extra_params.empty())
277 query = base::StringPrintf("%s&%s", query.c_str(), extra_params.c_str());
279 return http_server.GetURL(query);
282 PPAPITest::PPAPITest() : in_process_(true) {
285 void PPAPITest::SetUpCommandLine(CommandLine* command_line) {
286 PPAPITestBase::SetUpCommandLine(command_line);
288 // Append the switch to register the pepper plugin.
289 // library name = <out dir>/<test_name>.<library_extension>
290 // MIME type = application/x-ppapi-<test_name>
291 base::FilePath plugin_dir;
292 EXPECT_TRUE(PathService::Get(base::DIR_MODULE, &plugin_dir));
294 base::FilePath plugin_lib = plugin_dir.Append(library_name);
295 EXPECT_TRUE(base::PathExists(plugin_lib));
296 base::FilePath::StringType pepper_plugin = plugin_lib.value();
297 pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
298 command_line->AppendSwitchNative(switches::kRegisterPepperPlugins,
300 command_line->AppendSwitchASCII(switches::kAllowNaClSocketAPI, "127.0.0.1");
303 command_line->AppendSwitch(switches::kPpapiInProcess);
306 std::string PPAPITest::BuildQuery(const std::string& base,
307 const std::string& test_case){
308 return base::StringPrintf("%stestcase=%s", base.c_str(), test_case.c_str());
311 OutOfProcessPPAPITest::OutOfProcessPPAPITest() {
315 void OutOfProcessPPAPITest::SetUpCommandLine(CommandLine* command_line) {
316 PPAPITest::SetUpCommandLine(command_line);
317 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
318 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
321 void PPAPINaClTest::SetUpCommandLine(CommandLine* command_line) {
322 PPAPITestBase::SetUpCommandLine(command_line);
324 base::FilePath plugin_lib;
325 EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
326 EXPECT_TRUE(base::PathExists(plugin_lib));
328 // Enable running (non-portable) NaCl outside of the Chrome web store.
329 command_line->AppendSwitch(switches::kEnableNaCl);
330 command_line->AppendSwitchASCII(switches::kAllowNaClSocketAPI, "127.0.0.1");
331 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
332 command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
335 // Append the correct mode and testcase string
336 std::string PPAPINaClNewlibTest::BuildQuery(const std::string& base,
337 const std::string& test_case) {
338 return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
342 // Append the correct mode and testcase string
343 std::string PPAPINaClGLibcTest::BuildQuery(const std::string& base,
344 const std::string& test_case) {
345 return base::StringPrintf("%smode=nacl_glibc&testcase=%s", base.c_str(),
349 // Append the correct mode and testcase string
350 std::string PPAPINaClPNaClTest::BuildQuery(const std::string& base,
351 const std::string& test_case) {
352 return base::StringPrintf("%smode=nacl_pnacl&testcase=%s", base.c_str(),
356 void PPAPINaClTestDisallowedSockets::SetUpCommandLine(
357 CommandLine* command_line) {
358 PPAPITestBase::SetUpCommandLine(command_line);
360 base::FilePath plugin_lib;
361 EXPECT_TRUE(PathService::Get(chrome::FILE_NACL_PLUGIN, &plugin_lib));
362 EXPECT_TRUE(base::PathExists(plugin_lib));
364 // Enable running (non-portable) NaCl outside of the Chrome web store.
365 command_line->AppendSwitch(switches::kEnableNaCl);
368 // Append the correct mode and testcase string
369 std::string PPAPINaClTestDisallowedSockets::BuildQuery(
370 const std::string& base,
371 const std::string& test_case) {
372 return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base.c_str(),
376 void PPAPIBrokerInfoBarTest::SetUpOnMainThread() {
377 // The default content setting for the PPAPI broker is ASK. We purposefully
378 // don't call PPAPITestBase::SetUpOnMainThread() to keep it that way.