Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / api / tab_capture / tab_capture_apitest.cc
blob1d744a5de8ebfd5d6c073adeb1316e6c3f926814
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 "base/basictypes.h"
6 #include "base/command_line.h"
7 #include "base/location.h"
8 #include "base/single_thread_task_runner.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/tab_helper.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
17 #include "chrome/browser/ui/tabs/tab_utils.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/chrome_version_info.h"
20 #include "content/public/browser/render_frame_host.h"
21 #include "content/public/browser/render_process_host.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "content/public/test/test_utils.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "extensions/common/switches.h"
26 #include "extensions/test/extension_test_message_listener.h"
27 #include "extensions/test/result_catcher.h"
29 #if defined(OS_WIN)
30 #include "base/win/windows_version.h"
31 #endif
33 namespace extensions {
35 namespace {
37 const char kExtensionId[] = "ddchlicdkolnonkihahngkmmmjnjlkkf";
39 class TabCaptureApiTest : public ExtensionApiTest {
40 public:
41 void SetUpCommandLine(base::CommandLine* command_line) override {
42 ExtensionApiTest::SetUpCommandLine(command_line);
43 // Specify smallish window size to make testing of tab capture less CPU
44 // intensive.
45 command_line->AppendSwitchASCII(::switches::kWindowSize, "300,300");
46 command_line->AppendSwitch(::switches::kEnableTabAudioMuting);
49 void AddExtensionToCommandLineWhitelist() {
50 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
51 switches::kWhitelistedExtensionID, kExtensionId);
54 protected:
55 void SimulateMouseClickInCurrentTab() {
56 content::SimulateMouseClick(
57 browser()->tab_strip_model()->GetActiveWebContents(),
59 blink::WebMouseEvent::ButtonLeft);
63 class TabCaptureApiPixelTest : public TabCaptureApiTest {
64 public:
65 void SetUp() override {
66 if (!IsTooIntensiveForThisPlatform())
67 EnablePixelOutput();
68 TabCaptureApiTest::SetUp();
71 protected:
72 bool IsTooIntensiveForThisPlatform() const {
73 #if defined(OS_WIN)
74 if (base::win::GetVersion() < base::win::VERSION_VISTA)
75 return true;
76 #endif
78 // The tests are too slow to succeed with OSMesa on the bots.
79 if (UsingOSMesa())
80 return true;
82 #if defined(NDEBUG)
83 return false;
84 #else
85 // TODO(miu): Look into enabling these tests for the Debug build bots once
86 // they prove to be stable again on the Release bots.
87 // http://crbug.com/396413
88 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
89 "run-tab-capture-api-pixel-tests");
90 #endif
94 // Tests API behaviors, including info queries, and constraints violations.
95 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, ApiTests) {
96 AddExtensionToCommandLineWhitelist();
97 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "api_tests.html")) << message_;
100 // Tests that tab capture video frames can be received in a VIDEO element.
101 IN_PROC_BROWSER_TEST_F(TabCaptureApiPixelTest, EndToEndWithoutRemoting) {
102 if (IsTooIntensiveForThisPlatform()) {
103 LOG(WARNING) << "Skipping this CPU-intensive test on this platform/build.";
104 return;
106 AddExtensionToCommandLineWhitelist();
107 ASSERT_TRUE(RunExtensionSubtest(
108 "tab_capture", "end_to_end.html?method=local&colorDeviation=10"))
109 << message_;
112 // Tests that video frames are captured, transported via WebRTC, and finally
113 // received in a VIDEO element. More allowance is provided for color deviation
114 // because of the additional layers of video processing performed within
115 // WebRTC.
116 IN_PROC_BROWSER_TEST_F(TabCaptureApiPixelTest, EndToEndThroughWebRTC) {
117 if (IsTooIntensiveForThisPlatform()) {
118 LOG(WARNING) << "Skipping this CPU-intensive test on this platform/build.";
119 return;
121 AddExtensionToCommandLineWhitelist();
122 ASSERT_TRUE(RunExtensionSubtest(
123 "tab_capture", "end_to_end.html?method=webrtc&colorDeviation=50"))
124 << message_;
127 // http://crbug.com/177163
128 #if defined(OS_WIN) && !defined(NDEBUG)
129 #define MAYBE_GetUserMediaTest DISABLED_GetUserMediaTest
130 #else
131 #define MAYBE_GetUserMediaTest GetUserMediaTest
132 #endif
133 // Tests that getUserMedia() is NOT a way to start tab capture.
134 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_GetUserMediaTest) {
135 ExtensionTestMessageListener listener("ready", true);
137 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "get_user_media_test.html"))
138 << message_;
140 EXPECT_TRUE(listener.WaitUntilSatisfied());
142 content::OpenURLParams params(GURL("about:blank"), content::Referrer(),
143 NEW_FOREGROUND_TAB,
144 ui::PAGE_TRANSITION_LINK, false);
145 content::WebContents* web_contents = browser()->OpenURL(params);
147 content::RenderFrameHost* const main_frame = web_contents->GetMainFrame();
148 ASSERT_TRUE(main_frame);
149 listener.Reply(base::StringPrintf("web-contents-media-stream://%i:%i",
150 main_frame->GetProcess()->GetID(),
151 main_frame->GetRoutingID()));
153 ResultCatcher catcher;
154 catcher.RestrictToBrowserContext(browser()->profile());
155 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
158 // http://crbug.com/177163
159 #if defined(OS_WIN) && !defined(NDEBUG)
160 #define MAYBE_ActiveTabPermission DISABLED_ActiveTabPermission
161 #else
162 #define MAYBE_ActiveTabPermission ActiveTabPermission
163 #endif
164 // Make sure tabCapture.capture only works if the tab has been granted
165 // permission via an extension icon click or the extension is whitelisted.
166 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_ActiveTabPermission) {
167 ExtensionTestMessageListener before_open_tab("ready1", true);
168 ExtensionTestMessageListener before_grant_permission("ready2", true);
169 ExtensionTestMessageListener before_open_new_tab("ready3", true);
170 ExtensionTestMessageListener before_whitelist_extension("ready4", true);
172 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
173 "active_tab_permission_test.html"))
174 << message_;
176 // Open a new tab and make sure capture is denied.
177 EXPECT_TRUE(before_open_tab.WaitUntilSatisfied());
178 content::OpenURLParams params(GURL("http://google.com"), content::Referrer(),
179 NEW_FOREGROUND_TAB,
180 ui::PAGE_TRANSITION_LINK, false);
181 content::WebContents* web_contents = browser()->OpenURL(params);
182 before_open_tab.Reply("");
184 // Grant permission and make sure capture succeeds.
185 EXPECT_TRUE(before_grant_permission.WaitUntilSatisfied());
186 const Extension* extension = ExtensionRegistry::Get(
187 web_contents->GetBrowserContext())->enabled_extensions().GetByID(
188 kExtensionId);
189 TabHelper::FromWebContents(web_contents)
190 ->active_tab_permission_granter()->GrantIfRequested(extension);
191 before_grant_permission.Reply("");
193 // Open a new tab and make sure capture is denied.
194 EXPECT_TRUE(before_open_new_tab.WaitUntilSatisfied());
195 browser()->OpenURL(params);
196 before_open_new_tab.Reply("");
198 // Add extension to whitelist and make sure capture succeeds.
199 EXPECT_TRUE(before_whitelist_extension.WaitUntilSatisfied());
200 AddExtensionToCommandLineWhitelist();
201 before_whitelist_extension.Reply("");
203 ResultCatcher catcher;
204 catcher.RestrictToBrowserContext(browser()->profile());
205 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
208 // http://crbug.com/177163
209 #if defined(OS_WIN) && !defined(NDEBUG)
210 #define MAYBE_FullscreenEvents DISABLED_FullscreenEvents
211 #else
212 #define MAYBE_FullscreenEvents FullscreenEvents
213 #endif
214 // Tests that fullscreen transitions during a tab capture session dispatch
215 // events to the onStatusChange listener. The test loads a page that toggles
216 // fullscreen mode, using the Fullscreen Javascript API, in response to mouse
217 // clicks.
218 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_FullscreenEvents) {
219 AddExtensionToCommandLineWhitelist();
221 ExtensionTestMessageListener capture_started("tab_capture_started", false);
222 ExtensionTestMessageListener entered_fullscreen("entered_fullscreen", false);
224 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "fullscreen_test.html"))
225 << message_;
226 EXPECT_TRUE(capture_started.WaitUntilSatisfied());
228 // Click on the page to trigger the Javascript that will toggle the tab into
229 // fullscreen mode.
230 SimulateMouseClickInCurrentTab();
231 EXPECT_TRUE(entered_fullscreen.WaitUntilSatisfied());
233 // Click again to exit fullscreen mode.
234 SimulateMouseClickInCurrentTab();
236 // Wait until the page examines its results and calls chrome.test.succeed().
237 ResultCatcher catcher;
238 catcher.RestrictToBrowserContext(browser()->profile());
239 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
242 // Times out on Win dbg bots: http://crbug.com/177163
243 // Flaky on MSan bots: http://crbug.com/294431
244 #if (defined(OS_WIN) && !defined(NDEBUG)) || defined(MEMORY_SANITIZER)
245 #define MAYBE_GrantForChromePages DISABLED_GrantForChromePages
246 #else
247 #define MAYBE_GrantForChromePages GrantForChromePages
248 #endif
249 // Make sure tabCapture API can be granted for Chrome:// pages.
250 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_GrantForChromePages) {
251 ExtensionTestMessageListener before_open_tab("ready1", true);
252 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
253 "active_tab_chrome_pages.html"))
254 << message_;
255 EXPECT_TRUE(before_open_tab.WaitUntilSatisfied());
257 // Open a tab on a chrome:// page and make sure we can capture.
258 content::OpenURLParams params(GURL("chrome://version"), content::Referrer(),
259 NEW_FOREGROUND_TAB,
260 ui::PAGE_TRANSITION_LINK, false);
261 content::WebContents* web_contents = browser()->OpenURL(params);
262 const Extension* extension = ExtensionRegistry::Get(
263 web_contents->GetBrowserContext())->enabled_extensions().GetByID(
264 kExtensionId);
265 TabHelper::FromWebContents(web_contents)
266 ->active_tab_permission_granter()->GrantIfRequested(extension);
267 before_open_tab.Reply("");
269 ResultCatcher catcher;
270 catcher.RestrictToBrowserContext(browser()->profile());
271 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
274 // http://crbug.com/177163
275 #if defined(OS_WIN) && !defined(NDEBUG)
276 #define MAYBE_CaptureInSplitIncognitoMode DISABLED_CaptureInSplitIncognitoMode
277 #else
278 #define MAYBE_CaptureInSplitIncognitoMode CaptureInSplitIncognitoMode
279 #endif
280 // Tests that a tab in incognito mode can be captured.
281 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_CaptureInSplitIncognitoMode) {
282 AddExtensionToCommandLineWhitelist();
283 ASSERT_TRUE(RunExtensionSubtest("tab_capture",
284 "start_tab_capture.html",
285 kFlagEnableIncognito | kFlagUseIncognito))
286 << message_;
289 // http://crbug.com/177163
290 #if defined(OS_WIN) && !defined(NDEBUG)
291 #define MAYBE_Constraints DISABLED_Constraints
292 #else
293 #define MAYBE_Constraints Constraints
294 #endif
295 // Tests that valid constraints allow tab capture to start, while invalid ones
296 // do not.
297 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_Constraints) {
298 AddExtensionToCommandLineWhitelist();
299 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "constraints.html"))
300 << message_;
303 // http://crbug.com/177163
304 #if defined(OS_WIN) && !defined(NDEBUG)
305 #define MAYBE_TabIndicator DISABLED_TabIndicator
306 #else
307 #define MAYBE_TabIndicator TabIndicator
308 #endif
309 // Tests that the tab indicator (in the tab strip) is shown during tab capture.
310 IN_PROC_BROWSER_TEST_F(TabCaptureApiTest, MAYBE_TabIndicator) {
311 ASSERT_EQ(TAB_MEDIA_STATE_NONE,
312 chrome::GetTabMediaStateForContents(
313 browser()->tab_strip_model()->GetActiveWebContents()));
315 // Run an extension test that just turns on tab capture, which should cause
316 // the indicator to turn on.
317 AddExtensionToCommandLineWhitelist();
318 ASSERT_TRUE(RunExtensionSubtest("tab_capture", "start_tab_capture.html"))
319 << message_;
321 // A TabStripModelObserver that quits the MessageLoop whenever the UI's model
322 // is sent an event that changes the indicator status.
323 class IndicatorChangeObserver : public TabStripModelObserver {
324 public:
325 explicit IndicatorChangeObserver(Browser* browser)
326 : last_media_state_(chrome::GetTabMediaStateForContents(
327 browser->tab_strip_model()->GetActiveWebContents())) {}
329 TabMediaState last_media_state() const { return last_media_state_; }
331 void TabChangedAt(content::WebContents* contents,
332 int index,
333 TabChangeType change_type) override {
334 const TabMediaState media_state =
335 chrome::GetTabMediaStateForContents(contents);
336 const bool has_changed = media_state != last_media_state_;
337 last_media_state_ = media_state;
338 if (has_changed) {
339 base::ThreadTaskRunnerHandle::Get()->PostTask(
340 FROM_HERE, base::MessageLoop::QuitClosure());
344 private:
345 TabMediaState last_media_state_;
348 // Run the browser until the indicator turns on.
349 IndicatorChangeObserver observer(browser());
350 browser()->tab_strip_model()->AddObserver(&observer);
351 const base::TimeTicks start_time = base::TimeTicks::Now();
352 while (observer.last_media_state() != TAB_MEDIA_STATE_CAPTURING) {
353 if (base::TimeTicks::Now() - start_time >
354 base::TimeDelta::FromSeconds(10)) {
355 EXPECT_EQ(TAB_MEDIA_STATE_CAPTURING, observer.last_media_state());
356 browser()->tab_strip_model()->RemoveObserver(&observer);
357 return;
359 content::RunMessageLoop();
361 browser()->tab_strip_model()->RemoveObserver(&observer);
364 } // namespace
366 } // namespace extensions