Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chrome / test / media_router / media_router_integration_browsertest.cc
blob470afee19f51e5389705d6946daae187c9b1f995
1 // Copyright 2015 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/media_router/media_router_integration_browsertest.h"
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/json/json_file_value_serializer.h"
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
12 #include "base/path_service.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/ui/views/frame/browser_view.h"
19 #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.h"
20 #include "chrome/common/url_constants.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/test/browser_test_utils.h"
23 #include "content/public/test/test_navigation_observer.h"
24 #include "content/public/test/test_utils.h"
25 #include "net/base/filename_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 namespace media_router {
31 namespace {
32 // The path relative to <chromium src>/out/<build config> for media router
33 // browser test resources.
34 const base::FilePath::StringPieceType kResourcePath = FILE_PATH_LITERAL(
35 "media_router/browser_test_resources/");
36 // The javascript snippets.
37 const std::string kCheckSessionScript = "checkSession();";
38 const std::string kCheckSessionFailedScript = "checkSessionFailedToStart();";
39 const std::string kStartSessionScript = "startSession();";
40 const std::string kStopSessionScript = "stopSession()";
41 const std::string kWaitDeviceScript = "waitUntilDeviceAvailable();";
43 std::string GetStartedSessionId(content::WebContents* web_contents) {
44 std::string session_id;
45 CHECK(content::ExecuteScriptAndExtractString(
46 web_contents, "window.domAutomationController.send(startedSession.id)",
47 &session_id));
48 return session_id;
51 std::string GetDefaultRequestSessionId(content::WebContents* web_contents) {
52 std::string session_id;
53 CHECK(content::ExecuteScriptAndExtractString(
54 web_contents,
55 "window.domAutomationController.send(defaultRequestSessionId)",
56 &session_id));
57 return session_id;
60 } // namespace
62 MediaRouterIntegrationBrowserTest::MediaRouterIntegrationBrowserTest() {
65 MediaRouterIntegrationBrowserTest::~MediaRouterIntegrationBrowserTest() {
68 void MediaRouterIntegrationBrowserTest::TearDownOnMainThread() {
69 MediaRouterBaseBrowserTest::TearDownOnMainThread();
70 test_navigation_observer_.reset();
73 void MediaRouterIntegrationBrowserTest::ExecuteJavaScriptAPI(
74 content::WebContents* web_contents,
75 const std::string& script) {
76 std::string result(ExecuteScriptAndExtractString(web_contents, script));
78 // Read the test result, the test result set by javascript is a
79 // JSON string with the following format:
80 // {"passed": "<true/false>", "errorMessage": "<error_message>"}
81 scoped_ptr<base::Value> value =
82 base::JSONReader::Read(result, base::JSON_ALLOW_TRAILING_COMMAS);
84 // Convert to dictionary.
85 base::DictionaryValue* dict_value = nullptr;
86 ASSERT_TRUE(value->GetAsDictionary(&dict_value));
88 // Extract the fields.
89 bool passed = false;
90 ASSERT_TRUE(dict_value->GetBoolean("passed", &passed));
91 std::string error_message;
92 ASSERT_TRUE(dict_value->GetString("errorMessage", &error_message));
94 ASSERT_TRUE(passed) << error_message;
97 void MediaRouterIntegrationBrowserTest::OpenTestPage(
98 base::FilePath::StringPieceType file_name) {
99 base::FilePath full_path = GetResourceFile(file_name);
100 ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(full_path));
103 void MediaRouterIntegrationBrowserTest::OpenTestPageInNewTab(
104 base::FilePath::StringPieceType file_name) {
105 base::FilePath full_path = GetResourceFile(file_name);
106 ui_test_utils::NavigateToURLWithDisposition(
107 browser(), net::FilePathToFileURL(full_path), NEW_FOREGROUND_TAB,
108 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
111 void MediaRouterIntegrationBrowserTest::StartSession(
112 content::WebContents* web_contents) {
113 test_navigation_observer_.reset(
114 new content::TestNavigationObserver(web_contents, 1));
115 test_navigation_observer_->StartWatchingNewWebContents();
116 ExecuteJavaScriptAPI(web_contents, kStartSessionScript);
117 test_navigation_observer_->Wait();
118 test_navigation_observer_->StopWatchingNewWebContents();
121 void MediaRouterIntegrationBrowserTest::ChooseSink(
122 content::WebContents* web_contents,
123 const std::string& sink_id,
124 const std::string& current_route) {
125 content::WebContents* dialog_contents = GetMRDialog(web_contents);
126 std::string route;
127 if (current_route.empty()) {
128 route = "null";
129 } else {
130 route = current_route;
131 std::string script = base::StringPrintf(
132 "window.document.getElementById('media-router-container')."
133 "currentRoute_ = %s", route.c_str());
134 ASSERT_TRUE(content::ExecuteScript(dialog_contents, script));
136 std::string script = base::StringPrintf(
137 "window.document.getElementById('media-router-container')."
138 "showOrCreateRoute_({'id': '%s', 'name': ''}, %s)",
139 sink_id.c_str(), route.c_str());
140 ASSERT_TRUE(content::ExecuteScript(dialog_contents, script));
143 content::WebContents* MediaRouterIntegrationBrowserTest::GetMRDialog(
144 content::WebContents* web_contents) {
145 MediaRouterDialogControllerImpl* controller =
146 MediaRouterDialogControllerImpl::GetOrCreateForWebContents(web_contents);
147 content::WebContents* dialog_contents = controller->GetMediaRouterDialog();
148 CHECK(dialog_contents);
149 return dialog_contents;
152 void MediaRouterIntegrationBrowserTest::SetTestData(
153 base::FilePath::StringPieceType test_data_file) {
154 base::FilePath full_path = GetResourceFile(test_data_file);
155 JSONFileValueDeserializer deserializer(full_path);
156 int error_code = 0;
157 std::string error_message;
158 scoped_ptr<base::Value> value(
159 deserializer.Deserialize(&error_code, &error_message));
160 CHECK(value.get()) << "Deserialize failed: " << error_message;
161 std::string test_data_str;
162 ASSERT_TRUE(base::JSONWriter::Write(*value, &test_data_str));
163 ExecuteScriptInBackgroundPageNoWait(
164 extension_id_,
165 base::StringPrintf("localStorage['testdata'] = '%s'",
166 test_data_str.c_str()));
169 content::WebContents* MediaRouterIntegrationBrowserTest::OpenMRDialog(
170 content::WebContents* web_contents) {
171 MediaRouterDialogControllerImpl* controller =
172 MediaRouterDialogControllerImpl::GetOrCreateForWebContents(web_contents);
173 test_navigation_observer_.reset(
174 new content::TestNavigationObserver(web_contents, 1));
175 test_navigation_observer_->StartWatchingNewWebContents();
176 CHECK(controller->ShowMediaRouterDialog());
177 test_navigation_observer_->Wait();
178 test_navigation_observer_->StopWatchingNewWebContents();
179 content::WebContents* dialog_contents = controller->GetMediaRouterDialog();
180 CHECK(dialog_contents);
181 return dialog_contents;
184 base::FilePath MediaRouterIntegrationBrowserTest::GetResourceFile(
185 base::FilePath::StringPieceType relative_path) const {
186 base::FilePath base_dir;
187 // ASSERT_TRUE can only be used in void returning functions.
188 // Use CHECK instead in non-void returning functions.
189 CHECK(PathService::Get(base::DIR_MODULE, &base_dir));
190 base::FilePath full_path =
191 base_dir.Append(kResourcePath).Append(relative_path);
192 CHECK(PathExists(full_path));
193 return full_path;
196 int MediaRouterIntegrationBrowserTest::ExecuteScriptAndExtractInt(
197 const content::ToRenderFrameHost& adapter, const std::string& script) {
198 int result;
199 CHECK(content::ExecuteScriptAndExtractInt(adapter, script, &result));
200 return result;
203 std::string MediaRouterIntegrationBrowserTest::ExecuteScriptAndExtractString(
204 const content::ToRenderFrameHost& adapter, const std::string& script) {
205 std::string result;
206 CHECK(content::ExecuteScriptAndExtractString(adapter, script, &result));
207 return result;
210 bool MediaRouterIntegrationBrowserTest::IsRouteCreatedOnUI() {
211 content::WebContents* web_contents =
212 browser()->tab_strip_model()->GetActiveWebContents();
213 content::WebContents* dialog_contents = GetMRDialog(web_contents);
214 std::string script;
215 script = base::StringPrintf(
216 "domAutomationController.send(window.document.getElementById("
217 "'media-router-container').routeList.length)");
218 return ExecuteScriptAndExtractInt(dialog_contents, script) == 1;
221 void MediaRouterIntegrationBrowserTest::WaitUntilRouteCreated() {
222 ASSERT_TRUE(ConditionalWait(
223 base::TimeDelta::FromSeconds(10), base::TimeDelta::FromSeconds(1),
224 base::Bind(&MediaRouterIntegrationBrowserTest::IsRouteCreatedOnUI,
225 base::Unretained(this))));
228 IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, MANUAL_Basic) {
229 OpenTestPage(FILE_PATH_LITERAL("basic_test.html"));
230 content::WebContents* web_contents =
231 browser()->tab_strip_model()->GetActiveWebContents();
232 ASSERT_TRUE(web_contents);
233 ExecuteJavaScriptAPI(web_contents, kWaitDeviceScript);
234 StartSession(web_contents);
235 ChooseSink(web_contents, "id1", "");
236 ExecuteJavaScriptAPI(web_contents, kCheckSessionScript);
237 Wait(base::TimeDelta::FromSeconds(5));
239 std::string session_id(GetStartedSessionId(web_contents));
240 EXPECT_FALSE(session_id.empty());
242 std::string default_request_session_id(
243 GetDefaultRequestSessionId(web_contents));
244 EXPECT_EQ(session_id, default_request_session_id);
246 ExecuteJavaScriptAPI(web_contents, kStopSessionScript);
249 IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest,
250 MANUAL_Fail_No_Provider) {
251 SetTestData(FILE_PATH_LITERAL("no_provider.json"));
252 OpenTestPage(FILE_PATH_LITERAL("no_provider.html"));
253 content::WebContents* web_contents =
254 browser()->tab_strip_model()->GetActiveWebContents();
255 ASSERT_TRUE(web_contents);
256 ExecuteJavaScriptAPI(web_contents, kWaitDeviceScript);
257 StartSession(web_contents);
258 ChooseSink(web_contents, "id1", "");
259 ExecuteJavaScriptAPI(web_contents, kCheckSessionFailedScript);
262 IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest,
263 MANUAL_Fail_Create_Route) {
264 SetTestData(FILE_PATH_LITERAL("fail_create_route.json"));
265 OpenTestPage(FILE_PATH_LITERAL("fail_create_route.html"));
266 content::WebContents* web_contents =
267 browser()->tab_strip_model()->GetActiveWebContents();
268 ASSERT_TRUE(web_contents);
269 ExecuteJavaScriptAPI(web_contents, kWaitDeviceScript);
270 StartSession(web_contents);
271 ChooseSink(web_contents, "id1", "");
272 ExecuteJavaScriptAPI(web_contents, kCheckSessionFailedScript);
275 IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest,
276 MANUAL_ReconnectSession) {
277 OpenTestPage(FILE_PATH_LITERAL("basic_test.html"));
278 content::WebContents* web_contents =
279 browser()->tab_strip_model()->GetActiveWebContents();
280 ASSERT_TRUE(web_contents);
281 ExecuteJavaScriptAPI(web_contents, kWaitDeviceScript);
282 StartSession(web_contents);
283 ChooseSink(web_contents, "id1", "");
284 ExecuteJavaScriptAPI(web_contents, kCheckSessionScript);
285 std::string session_id(GetStartedSessionId(web_contents));
287 OpenTestPageInNewTab(FILE_PATH_LITERAL("basic_test.html"));
288 content::WebContents* new_web_contents =
289 browser()->tab_strip_model()->GetActiveWebContents();
290 ASSERT_TRUE(new_web_contents);
291 ASSERT_NE(web_contents, new_web_contents);
292 ExecuteJavaScriptAPI(
293 new_web_contents,
294 base::StringPrintf("reconnectSession('%s');", session_id.c_str()));
295 std::string reconnected_session_id;
296 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
297 new_web_contents,
298 "window.domAutomationController.send(reconnectedSession.id)",
299 &reconnected_session_id));
300 ASSERT_EQ(session_id, reconnected_session_id);
303 IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest,
304 MANUAL_Fail_ReconnectSession) {
305 OpenTestPage(FILE_PATH_LITERAL("basic_test.html"));
306 content::WebContents* web_contents =
307 browser()->tab_strip_model()->GetActiveWebContents();
308 ASSERT_TRUE(web_contents);
309 ExecuteJavaScriptAPI(web_contents, kWaitDeviceScript);
310 content::TestNavigationObserver test_navigation_observer(web_contents, 1);
311 StartSession(web_contents);
312 ChooseSink(web_contents, "id1", "");
313 ExecuteJavaScriptAPI(web_contents, kCheckSessionScript);
314 std::string session_id(GetStartedSessionId(web_contents));
316 SetTestData(FILE_PATH_LITERAL("fail_reconnect_session.json"));
317 OpenTestPage(FILE_PATH_LITERAL("fail_reconnect_session.html"));
318 content::WebContents* new_web_contents =
319 browser()->tab_strip_model()->GetActiveWebContents();
320 ASSERT_TRUE(new_web_contents);
321 ExecuteJavaScriptAPI(
322 new_web_contents,
323 base::StringPrintf("checkReconnectSessionFails('%s');",
324 session_id.c_str()));
327 } // namespace media_router