Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(722)

Side by Side Diff: chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc

Issue 59113003: Add a browser test to automatically run end-to-end Hangout Services test. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix string16 issue. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/test/data/extensions/hangout_services_test.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/json/json_writer.h" 5 #include "base/json/json_writer.h"
6 #include "base/message_loop/message_loop.h" 6 #include "base/message_loop/message_loop.h"
7 #include "base/strings/string_util.h"
7 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
8 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/platform_thread.h" 11 #include "base/threading/platform_thread.h"
10 #include "base/time/time.h" 12 #include "base/time/time.h"
11 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h" 13 #include "chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_privat e_api.h"
14 #include "chrome/browser/extensions/component_loader.h"
12 #include "chrome/browser/extensions/extension_apitest.h" 15 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/extension_function_test_utils.h" 16 #include "chrome/browser/extensions/extension_function_test_utils.h"
14 #include "chrome/browser/extensions/extension_tab_util.h" 17 #include "chrome/browser/extensions/extension_tab_util.h"
15 #include "chrome/browser/ui/browser.h" 18 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" 19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/extensions/permissions/permissions_data.h" 20 #include "chrome/common/extensions/permissions/permissions_data.h"
18 #include "chrome/test/base/in_process_browser_test.h" 21 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/ui_test_utils.h" 22 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/browser/media_device_id.h" 23 #include "content/public/browser/media_device_id.h"
21 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
25 #include "content/public/test/browser_test_utils.h"
22 #include "extensions/common/permissions/permission_set.h" 26 #include "extensions/common/permissions/permission_set.h"
23 #include "media/audio/audio_manager.h" 27 #include "media/audio/audio_manager.h"
24 #include "net/test/embedded_test_server/embedded_test_server.h" 28 #include "net/test/embedded_test_server/embedded_test_server.h"
25 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
26 30
27 using base::JSONWriter; 31 using base::JSONWriter;
28 using content::RenderViewHost; 32 using content::RenderViewHost;
29 using content::WebContents; 33 using content::WebContents;
30 using media::AudioDeviceNames; 34 using media::AudioDeviceNames;
31 using media::AudioManager; 35 using media::AudioManager;
32 36
33 namespace extensions { 37 namespace extensions {
34 38
35 using extension_function_test_utils::RunFunctionAndReturnError; 39 using extension_function_test_utils::RunFunctionAndReturnError;
36 using extension_function_test_utils::RunFunctionAndReturnSingleResult; 40 using extension_function_test_utils::RunFunctionAndReturnSingleResult;
37 41
38 class WebrtcAudioPrivateTest : public ExtensionApiTest { 42 class AudioWaitingExtensionTest : public ExtensionApiTest {
43 protected:
44 void WaitUntilAudioIsPlaying(WebContents* tab) {
45 // Wait for audio to start playing. We gate this on there being one
46 // or more AudioOutputController objects for our tab.
47 bool audio_playing = false;
48 for (size_t remaining_tries = 50; remaining_tries > 0; --remaining_tries) {
49 tab->GetRenderViewHost()->GetAudioOutputControllers(
50 base::Bind(OnAudioControllers, &audio_playing));
51 base::MessageLoop::current()->RunUntilIdle();
52 if (audio_playing)
53 break;
54
55 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
56 }
57
58 if (!audio_playing)
59 FAIL() << "Audio did not start playing within ~5 seconds.";
60 }
61
62 // Used by the test above to wait until audio is playing.
63 static void OnAudioControllers(
64 bool* audio_playing,
65 const RenderViewHost::AudioOutputControllerList& list) {
66 if (!list.empty())
67 *audio_playing = true;
68 }
69 };
70
71 class WebrtcAudioPrivateTest : public AudioWaitingExtensionTest {
39 public: 72 public:
40 WebrtcAudioPrivateTest() : enumeration_event_(false, false) { 73 WebrtcAudioPrivateTest() : enumeration_event_(false, false) {
41 } 74 }
42 75
43 protected: 76 protected:
44 std::string InvokeGetActiveSink(int tab_id) { 77 std::string InvokeGetActiveSink(int tab_id) {
45 ListValue parameters; 78 ListValue parameters;
46 parameters.AppendInteger(tab_id); 79 parameters.AppendInteger(tab_id);
47 std::string parameter_string; 80 std::string parameter_string;
48 JSONWriter::Write(&parameters, &parameter_string); 81 JSONWriter::Write(&parameters, &parameter_string);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 191
159 scoped_refptr<WebrtcAudioPrivateSetActiveSinkFunction> function = 192 scoped_refptr<WebrtcAudioPrivateSetActiveSinkFunction> function =
160 new WebrtcAudioPrivateSetActiveSinkFunction(); 193 new WebrtcAudioPrivateSetActiveSinkFunction();
161 std::string error(RunFunctionAndReturnError(function.get(), 194 std::string error(RunFunctionAndReturnError(function.get(),
162 parameter_string, 195 parameter_string,
163 browser())); 196 browser()));
164 EXPECT_EQ(base::StringPrintf("No active stream for tab with id: %d.", tab_id), 197 EXPECT_EQ(base::StringPrintf("No active stream for tab with id: %d.", tab_id),
165 error); 198 error);
166 } 199 }
167 200
168 // Used by the test below to wait until audio is playing.
169 static void OnAudioControllers(
170 bool* audio_playing,
171 const RenderViewHost::AudioOutputControllerList& list) {
172 if (!list.empty())
173 *audio_playing = true;
174 }
175
176 IN_PROC_BROWSER_TEST_F(WebrtcAudioPrivateTest, GetAndSetWithMediaStream) { 201 IN_PROC_BROWSER_TEST_F(WebrtcAudioPrivateTest, GetAndSetWithMediaStream) {
177 // First get the list of output devices, so that we can (if 202 // First get the list of output devices, so that we can (if
178 // available) set the active device to a device other than the one 203 // available) set the active device to a device other than the one
179 // it starts as. This function is not threadsafe and is normally 204 // it starts as. This function is not threadsafe and is normally
180 // called only from the audio IO thread, but we know no other code 205 // called only from the audio IO thread, but we know no other code
181 // is currently running so we call it directly. 206 // is currently running so we call it directly.
182 AudioDeviceNames devices; 207 AudioDeviceNames devices;
183 GetAudioDeviceNames(&AudioManager::GetAudioOutputDeviceNames, &devices); 208 GetAudioDeviceNames(&AudioManager::GetAudioOutputDeviceNames, &devices);
184 209
185 ASSERT_TRUE(StartEmbeddedTestServer()); 210 ASSERT_TRUE(StartEmbeddedTestServer());
186 211
187 // Open a normal page that uses an audio sink. 212 // Open a normal page that uses an audio sink.
188 ui_test_utils::NavigateToURL( 213 ui_test_utils::NavigateToURL(
189 browser(), 214 browser(),
190 GURL(embedded_test_server()->GetURL("/extensions/loop_audio.html"))); 215 GURL(embedded_test_server()->GetURL("/extensions/loop_audio.html")));
191 216
192 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 217 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
193 int tab_id = ExtensionTabUtil::GetTabId(tab); 218 int tab_id = ExtensionTabUtil::GetTabId(tab);
194 219
195 // Wait for audio to start playing. We gate this on there being one 220 WaitUntilAudioIsPlaying(tab);
196 // or more AudioOutputController objects for our tab.
197 bool audio_playing = false;
198 for (size_t remaining_tries = 50; remaining_tries > 0; --remaining_tries) {
199 tab->GetRenderViewHost()->GetAudioOutputControllers(
200 base::Bind(OnAudioControllers, &audio_playing));
201 base::MessageLoop::current()->RunUntilIdle();
202 if (audio_playing)
203 break;
204
205 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
206 }
207
208 if (!audio_playing)
209 FAIL() << "Audio did not start playing within ~5 seconds.";
210 221
211 std::string current_device = InvokeGetActiveSink(tab_id); 222 std::string current_device = InvokeGetActiveSink(tab_id);
212 VLOG(2) << "Before setting, current device: " << current_device; 223 VLOG(2) << "Before setting, current device: " << current_device;
213 EXPECT_NE("", current_device); 224 EXPECT_NE("", current_device);
214 225
215 // Set to each of the other devices in turn. 226 // Set to each of the other devices in turn.
216 for (AudioDeviceNames::const_iterator it = devices.begin(); 227 for (AudioDeviceNames::const_iterator it = devices.begin();
217 it != devices.end(); 228 it != devices.end();
218 ++it) { 229 ++it) {
219 std::string target_device(it->unique_id); 230 std::string target_device(it->unique_id);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 const extensions::Extension* extension = LoadExtension( 297 const extensions::Extension* extension = LoadExtension(
287 test_data_dir_.AppendASCII("webrtc_audio_private_event_listener")); 298 test_data_dir_.AppendASCII("webrtc_audio_private_event_listener"));
288 service->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); 299 service->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
289 300
290 // Check that the extension got the notification. 301 // Check that the extension got the notification.
291 std::string result = ExecuteScriptInBackgroundPage(extension->id(), 302 std::string result = ExecuteScriptInBackgroundPage(extension->id(),
292 "reportIfGot()"); 303 "reportIfGot()");
293 EXPECT_EQ("true", result); 304 EXPECT_EQ("true", result);
294 } 305 }
295 306
307 class HangoutServicesBrowserTest : public AudioWaitingExtensionTest {
308 public:
309 virtual void SetUp() OVERRIDE {
310 // Make sure the Hangout Services component extension gets loaded.
311 ComponentLoader::EnableBackgroundExtensionsForTesting();
312 ExtensionBrowserTest::SetUp();
Henrik Grunell 2013/11/06 08:49:01 Just checking: should it be ExtensionApiTest::SetU
Jói 2013/11/06 11:19:29 Good catch, it should be <superclass>::SetUp(), so
313 }
314 };
315
316 IN_PROC_BROWSER_TEST_F(HangoutServicesBrowserTest,
Henrik Grunell 2013/11/06 08:49:01 If the services test runs other than audio tests,
Jói 2013/11/06 11:19:29 I thought about that, but it doesn't really belong
Henrik Grunell 2013/11/06 11:43:30 I'm fine with that.
317 RunComponentExtensionTest) {
318 // This runs the end-to-end JavaScript test for the Hangout Services
319 // component extension, which uses the webrtcAudioPrivate API among
320 // others.
321 ASSERT_TRUE(StartEmbeddedTestServer());
322 GURL url(embedded_test_server()->GetURL(
323 "/extensions/hangout_services_test.html"));
324 // The "externally connectable" extension permission doesn't seem to
325 // like when we use 127.0.0.1 as the host, but using localhost works.
326 std::string url_spec = url.spec();
327 ReplaceFirstSubstringAfterOffset(&url_spec, 0, "127.0.0.1", "localhost");
328 GURL localhost_url(url_spec);
329 ui_test_utils::NavigateToURL(browser(), localhost_url);
330
331 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
332 WaitUntilAudioIsPlaying(tab);
333
334 ASSERT_TRUE(content::ExecuteScript(tab, "browsertestRunAllTests();"));
335
336 content::TitleWatcher title_watcher(tab, ASCIIToUTF16("success"));
337 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("failure"));
338 string16 result = title_watcher.WaitAndGetTitle();
339 EXPECT_EQ(ASCIIToUTF16("success"), result);
340 }
341
296 } // namespace extensions 342 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/extensions/hangout_services_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698