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/files/file_util.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/test_switches.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "components/content_settings/core/browser/host_content_settings_map.h"
22 #include "components/infobars/core/confirm_infobar_delegate.h"
23 #include "components/infobars/core/infobar.h"
24 #include "components/nacl/common/nacl_switches.h"
25 #include "content/public/browser/dom_operation_notification_details.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/content_switches.h"
29 #include "media/base/media_switches.h"
30 #include "net/base/filename_util.h"
31 #include "net/base/test_data_directory.h"
32 #include "ppapi/shared_impl/ppapi_switches.h"
33 #include "ppapi/shared_impl/test_harness_utils.h"
34 #include "ui/gl/gl_switches.h"
36 using content::DomOperationNotificationDetails
;
37 using content::RenderViewHost
;
38 using content::TestMessageHandler
;
42 void AddPrivateSwitches(base::CommandLine
* command_line
) {
43 // For TestRequestOSFileHandle.
44 command_line
->AppendSwitch(switches::kUnlimitedStorage
);
45 command_line
->AppendSwitchASCII(switches::kAllowNaClFileHandleAPI
,
51 PPAPITestMessageHandler::PPAPITestMessageHandler() {
54 TestMessageHandler::MessageResponse
PPAPITestMessageHandler::HandleMessage(
55 const std::string
& json
) {
57 base::TrimString(json
, "\"", &trimmed
);
64 void PPAPITestMessageHandler::Reset() {
65 TestMessageHandler::Reset();
69 PPAPITestBase::InfoBarObserver::InfoBarObserver(PPAPITestBase
* test_base
)
70 : test_base_(test_base
),
71 expecting_infobar_(false),
72 should_accept_(false) {
73 registrar_
.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED
,
74 content::NotificationService::AllSources());
77 PPAPITestBase::InfoBarObserver::~InfoBarObserver() {
78 EXPECT_FALSE(expecting_infobar_
) << "Missing an expected infobar";
81 void PPAPITestBase::InfoBarObserver::ExpectInfoBarAndAccept(
83 ASSERT_FALSE(expecting_infobar_
);
84 expecting_infobar_
= true;
85 should_accept_
= should_accept
;
88 void PPAPITestBase::InfoBarObserver::Observe(
90 const content::NotificationSource
& source
,
91 const content::NotificationDetails
& details
) {
92 ASSERT_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED
, type
);
93 // It's not safe to remove the infobar here, since other observers (e.g. the
94 // InfoBarContainer) may still need to access it. Instead, post a task to
95 // do all necessary infobar manipulation as soon as this call stack returns.
96 base::MessageLoop::current()->PostTask(
97 FROM_HERE
, base::Bind(&InfoBarObserver::VerifyInfoBarState
,
98 base::Unretained(this)));
101 void PPAPITestBase::InfoBarObserver::VerifyInfoBarState() {
102 content::WebContents
* web_contents
=
103 test_base_
->browser()->tab_strip_model()->GetActiveWebContents();
104 ASSERT_TRUE(web_contents
!= NULL
);
105 InfoBarService
* infobar_service
=
106 InfoBarService::FromWebContents(web_contents
);
107 ASSERT_TRUE(infobar_service
!= NULL
);
109 EXPECT_EQ(expecting_infobar_
? 1U : 0U, infobar_service
->infobar_count());
110 if (!expecting_infobar_
)
112 expecting_infobar_
= false;
114 infobars::InfoBar
* infobar
= infobar_service
->infobar_at(0);
115 ConfirmInfoBarDelegate
* delegate
=
116 infobar
->delegate()->AsConfirmInfoBarDelegate();
117 ASSERT_TRUE(delegate
!= NULL
);
123 infobar_service
->RemoveInfoBar(infobar
);
126 PPAPITestBase::PPAPITestBase() {
129 void PPAPITestBase::SetUp() {
131 InProcessBrowserTest::SetUp();
134 void PPAPITestBase::SetUpCommandLine(base::CommandLine
* command_line
) {
135 // The test sends us the result via a cookie.
136 command_line
->AppendSwitch(switches::kEnableFileCookies
);
138 // Some stuff is hung off of the testing interface which is not enabled
140 command_line
->AppendSwitch(switches::kEnablePepperTesting
);
142 // Smooth scrolling confuses the scrollbar test.
143 command_line
->AppendSwitch(switches::kDisableSmoothScrolling
);
146 void PPAPITestBase::SetUpOnMainThread() {
147 // Always allow access to the PPAPI broker.
148 browser()->profile()->GetHostContentSettingsMap()->SetDefaultContentSetting(
149 CONTENT_SETTINGS_TYPE_PPAPI_BROKER
, CONTENT_SETTING_ALLOW
);
152 GURL
PPAPITestBase::GetTestFileUrl(const std::string
& test_case
) {
153 base::FilePath test_path
;
154 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &test_path
));
155 test_path
= test_path
.Append(FILE_PATH_LITERAL("ppapi"));
156 test_path
= test_path
.Append(FILE_PATH_LITERAL("tests"));
157 test_path
= test_path
.Append(FILE_PATH_LITERAL("test_case.html"));
159 // Sanity check the file name.
160 EXPECT_TRUE(base::PathExists(test_path
));
162 GURL test_url
= net::FilePathToFileURL(test_path
);
164 GURL::Replacements replacements
;
165 std::string query
= BuildQuery(std::string(), test_case
);
166 replacements
.SetQuery(query
.c_str(), url::Component(0, query
.size()));
167 return test_url
.ReplaceComponents(replacements
);
170 void PPAPITestBase::RunTest(const std::string
& test_case
) {
171 GURL url
= GetTestFileUrl(test_case
);
175 void PPAPITestBase::RunTestViaHTTP(const std::string
& test_case
) {
176 base::FilePath document_root
;
177 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root
));
178 net::SpawnedTestServer
http_server(net::SpawnedTestServer::TYPE_HTTP
,
179 net::SpawnedTestServer::kLocalhost
,
181 ASSERT_TRUE(http_server
.Start());
182 RunTestURL(GetTestURL(http_server
, test_case
, std::string()));
185 void PPAPITestBase::RunTestWithSSLServer(const std::string
& test_case
) {
186 base::FilePath http_document_root
;
187 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root
));
188 net::SpawnedTestServer
http_server(net::SpawnedTestServer::TYPE_HTTP
,
189 net::SpawnedTestServer::kLocalhost
,
191 net::SpawnedTestServer
ssl_server(net::SpawnedTestServer::TYPE_HTTPS
,
192 net::BaseTestServer::SSLOptions(),
194 // Start the servers in parallel.
195 ASSERT_TRUE(http_server
.StartInBackground());
196 ASSERT_TRUE(ssl_server
.StartInBackground());
197 // Wait until they are both finished before continuing.
198 ASSERT_TRUE(http_server
.BlockUntilStarted());
199 ASSERT_TRUE(ssl_server
.BlockUntilStarted());
201 uint16_t port
= ssl_server
.host_port_pair().port();
202 RunTestURL(GetTestURL(http_server
,
204 base::StringPrintf("ssl_server_port=%d", port
)));
207 void PPAPITestBase::RunTestWithWebSocketServer(const std::string
& test_case
) {
208 base::FilePath http_document_root
;
209 ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root
));
210 net::SpawnedTestServer
http_server(net::SpawnedTestServer::TYPE_HTTP
,
211 net::SpawnedTestServer::kLocalhost
,
213 net::SpawnedTestServer
ws_server(net::SpawnedTestServer::TYPE_WS
,
214 net::SpawnedTestServer::kLocalhost
,
215 net::GetWebSocketTestDataDirectory());
216 // Start the servers in parallel.
217 ASSERT_TRUE(http_server
.StartInBackground());
218 ASSERT_TRUE(ws_server
.StartInBackground());
219 // Wait until they are both finished before continuing.
220 ASSERT_TRUE(http_server
.BlockUntilStarted());
221 ASSERT_TRUE(ws_server
.BlockUntilStarted());
223 std::string host
= ws_server
.host_port_pair().HostForURL();
224 uint16_t port
= ws_server
.host_port_pair().port();
225 RunTestURL(GetTestURL(http_server
,
228 "websocket_host=%s&websocket_port=%d",
233 void PPAPITestBase::RunTestIfAudioOutputAvailable(
234 const std::string
& test_case
) {
238 void PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(
239 const std::string
& test_case
) {
240 RunTestViaHTTP(test_case
);
243 void PPAPITestBase::RunTestURL(const GURL
& test_url
) {
244 #if defined(OS_WIN) && defined(USE_ASH)
245 // PPAPITests are broken in Ash browser tests (http://crbug.com/263548).
246 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
247 switches::kAshBrowserTests
)) {
248 LOG(WARNING
) << "PPAPITests are disabled for Ash browser tests.";
253 // See comment above TestingInstance in ppapi/test/testing_instance.h.
254 // Basically it sends messages using the DOM automation controller. The
255 // value of "..." means it's still working and we should continue to wait,
256 // any other value indicates completion (in this case it will start with
257 // "PASS" or "FAIL"). This keeps us from timing out on waits for long tests.
258 PPAPITestMessageHandler handler
;
259 content::JavascriptTestObserver
observer(
260 browser()->tab_strip_model()->GetActiveWebContents(),
263 ui_test_utils::NavigateToURL(browser(), test_url
);
265 ASSERT_TRUE(observer
.Run()) << handler
.error_message();
266 EXPECT_STREQ("PASS", handler
.message().c_str());
269 GURL
PPAPITestBase::GetTestURL(
270 const net::SpawnedTestServer
& http_server
,
271 const std::string
& test_case
,
272 const std::string
& extra_params
) {
273 std::string query
= BuildQuery("files/test_case.html?", test_case
);
274 if (!extra_params
.empty())
275 query
= base::StringPrintf("%s&%s", query
.c_str(), extra_params
.c_str());
277 return http_server
.GetURL(query
);
280 PPAPITest::PPAPITest() : in_process_(true) {
283 void PPAPITest::SetUpCommandLine(base::CommandLine
* command_line
) {
284 PPAPITestBase::SetUpCommandLine(command_line
);
286 base::FilePath plugin_dir
;
287 EXPECT_TRUE(PathService::Get(base::DIR_MODULE
, &plugin_dir
));
289 base::FilePath plugin_lib
= plugin_dir
.Append(ppapi::GetTestLibraryName());
290 EXPECT_TRUE(base::PathExists(plugin_lib
));
292 // Append the switch to register the pepper plugin.
293 // library path = <out dir>/<test_name>.<library_extension>
294 // library name = "PPAPI Tests"
296 // MIME type = application/x-ppapi-<test_name>
297 base::FilePath::StringType pepper_plugin
= plugin_lib
.value();
298 pepper_plugin
.append(FILE_PATH_LITERAL("#PPAPI Tests"));
299 pepper_plugin
.append(FILE_PATH_LITERAL("#")); // No description.
300 pepper_plugin
.append(FILE_PATH_LITERAL("#1.2.3"));
301 pepper_plugin
.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
302 command_line
->AppendSwitchNative(switches::kRegisterPepperPlugins
,
305 command_line
->AppendSwitchASCII(switches::kAllowNaClSocketAPI
, "127.0.0.1");
307 command_line
->AppendSwitch(switches::kPpapiInProcess
);
310 std::string
PPAPITest::BuildQuery(const std::string
& base
,
311 const std::string
& test_case
){
312 return base::StringPrintf("%stestcase=%s", base
.c_str(), test_case
.c_str());
315 void PPAPIPrivateTest::SetUpCommandLine(base::CommandLine
* command_line
) {
316 PPAPITest::SetUpCommandLine(command_line
);
317 AddPrivateSwitches(command_line
);
320 OutOfProcessPPAPITest::OutOfProcessPPAPITest() {
324 void OutOfProcessPPAPITest::SetUpCommandLine(base::CommandLine
* command_line
) {
325 PPAPITest::SetUpCommandLine(command_line
);
326 command_line
->AppendSwitch(switches::kUseFakeDeviceForMediaStream
);
327 command_line
->AppendSwitch(switches::kUseFakeUIForMediaStream
);
330 void OutOfProcessPPAPIPrivateTest::SetUpCommandLine(
331 base::CommandLine
* command_line
) {
332 OutOfProcessPPAPITest::SetUpCommandLine(command_line
);
333 AddPrivateSwitches(command_line
);
336 void PPAPINaClTest::SetUpCommandLine(base::CommandLine
* command_line
) {
337 #if !defined(DISABLE_NACL)
338 PPAPITestBase::SetUpCommandLine(command_line
);
340 // Enable running (non-portable) NaCl outside of the Chrome web store.
341 command_line
->AppendSwitch(switches::kEnableNaCl
);
342 command_line
->AppendSwitchASCII(switches::kAllowNaClSocketAPI
, "127.0.0.1");
343 command_line
->AppendSwitch(switches::kUseFakeDeviceForMediaStream
);
344 command_line
->AppendSwitch(switches::kUseFakeUIForMediaStream
);
348 void PPAPINaClTest::SetUpOnMainThread() {
351 void PPAPINaClTest::RunTest(const std::string
& test_case
) {
352 #if !defined(DISABLE_NACL)
353 PPAPITestBase::RunTest(test_case
);
357 void PPAPINaClTest::RunTestViaHTTP(const std::string
& test_case
) {
358 #if !defined(DISABLE_NACL)
359 PPAPITestBase::RunTestViaHTTP(test_case
);
363 void PPAPINaClTest::RunTestWithSSLServer(const std::string
& test_case
) {
364 #if !defined(DISABLE_NACL)
365 PPAPITestBase::RunTestWithSSLServer(test_case
);
369 void PPAPINaClTest::RunTestWithWebSocketServer(const std::string
& test_case
) {
370 #if !defined(DISABLE_NACL)
371 PPAPITestBase::RunTestWithWebSocketServer(test_case
);
375 void PPAPINaClTest::RunTestIfAudioOutputAvailable(
376 const std::string
& test_case
) {
377 #if !defined(DISABLE_NACL)
378 PPAPITestBase::RunTestIfAudioOutputAvailable(test_case
);
382 void PPAPINaClTest::RunTestViaHTTPIfAudioOutputAvailable(
383 const std::string
& test_case
) {
384 #if !defined(DISABLE_NACL)
385 PPAPITestBase::RunTestViaHTTPIfAudioOutputAvailable(test_case
);
389 // Append the correct mode and testcase string
390 std::string
PPAPINaClNewlibTest::BuildQuery(const std::string
& base
,
391 const std::string
& test_case
) {
392 return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base
.c_str(),
396 void PPAPIPrivateNaClNewlibTest::SetUpCommandLine(
397 base::CommandLine
* command_line
) {
398 PPAPINaClNewlibTest::SetUpCommandLine(command_line
);
399 AddPrivateSwitches(command_line
);
402 // Append the correct mode and testcase string
403 std::string
PPAPINaClGLibcTest::BuildQuery(const std::string
& base
,
404 const std::string
& test_case
) {
405 return base::StringPrintf("%smode=nacl_glibc&testcase=%s", base
.c_str(),
409 void PPAPIPrivateNaClGLibcTest::SetUpCommandLine(
410 base::CommandLine
* command_line
) {
411 PPAPINaClGLibcTest::SetUpCommandLine(command_line
);
412 AddPrivateSwitches(command_line
);
415 // Append the correct mode and testcase string
416 std::string
PPAPINaClPNaClTest::BuildQuery(const std::string
& base
,
417 const std::string
& test_case
) {
418 return base::StringPrintf("%smode=nacl_pnacl&testcase=%s", base
.c_str(),
422 void PPAPIPrivateNaClPNaClTest::SetUpCommandLine(
423 base::CommandLine
* command_line
) {
424 PPAPINaClPNaClTest::SetUpCommandLine(command_line
);
425 AddPrivateSwitches(command_line
);
428 void PPAPINaClPNaClNonSfiTest::SetUpCommandLine(
429 base::CommandLine
* command_line
) {
430 #if !defined(DISABLE_NACL)
431 PPAPINaClTest::SetUpCommandLine(command_line
);
432 command_line
->AppendSwitch(switches::kEnableNaClNonSfiMode
);
436 std::string
PPAPINaClPNaClNonSfiTest::BuildQuery(
437 const std::string
& base
,
438 const std::string
& test_case
) {
439 return base::StringPrintf("%smode=nacl_pnacl_nonsfi&testcase=%s",
440 base
.c_str(), test_case
.c_str());
443 void PPAPIPrivateNaClPNaClNonSfiTest::SetUpCommandLine(
444 base::CommandLine
* command_line
) {
445 PPAPINaClPNaClNonSfiTest::SetUpCommandLine(command_line
);
446 AddPrivateSwitches(command_line
);
449 void PPAPINaClTestDisallowedSockets::SetUpCommandLine(
450 base::CommandLine
* command_line
) {
451 PPAPITestBase::SetUpCommandLine(command_line
);
453 // Enable running (non-portable) NaCl outside of the Chrome web store.
454 command_line
->AppendSwitch(switches::kEnableNaCl
);
457 // Append the correct mode and testcase string
458 std::string
PPAPINaClTestDisallowedSockets::BuildQuery(
459 const std::string
& base
,
460 const std::string
& test_case
) {
461 return base::StringPrintf("%smode=nacl_newlib&testcase=%s", base
.c_str(),
465 void PPAPIBrokerInfoBarTest::SetUpOnMainThread() {
466 // The default content setting for the PPAPI broker is ASK. We purposefully
467 // don't call PPAPITestBase::SetUpOnMainThread() to keep it that way.