1 // Copyright 2014 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/command_line.h"
6 #include "base/compiler_specific.h"
7 #include "base/location.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
13 #include "chrome/browser/devtools/device/tcp_device_provider.h"
14 #include "chrome/browser/devtools/remote_debugging_server.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/test_utils.h"
27 const char kPortForwardingTestPage
[] =
28 "files/devtools/port_forwarding/main.html";
30 const int kDefaultDebuggingPort
= 9223;
31 const int kAlternativeDebuggingPort
= 9224;
35 class PortForwardingTest
: public InProcessBrowserTest
{
36 virtual int GetRemoteDebuggingPort() {
37 return kDefaultDebuggingPort
;
40 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
41 InProcessBrowserTest::SetUpCommandLine(command_line
);
42 command_line
->AppendSwitchASCII(switches::kRemoteDebuggingPort
,
43 base::IntToString(GetRemoteDebuggingPort()));
47 class Listener
: public DevToolsAndroidBridge::PortForwardingListener
{
49 explicit Listener(Profile
* profile
)
51 skip_empty_devices_(true) {
52 DevToolsAndroidBridge::Factory::GetForProfile(profile_
)->
53 AddPortForwardingListener(this);
56 ~Listener() override
{
57 DevToolsAndroidBridge::Factory::GetForProfile(profile_
)->
58 RemovePortForwardingListener(this);
61 void PortStatusChanged(const ForwardingStatus
& status
) override
{
62 if (status
.empty() && skip_empty_devices_
)
64 base::ThreadTaskRunnerHandle::Get()->PostTask(
65 FROM_HERE
, base::MessageLoop::QuitClosure());
68 void set_skip_empty_devices(bool skip_empty_devices
) {
69 skip_empty_devices_
= skip_empty_devices
;
74 bool skip_empty_devices_
;
78 // Flaky on all platforms. https://crbug.com/477696
79 IN_PROC_BROWSER_TEST_F(PortForwardingTest
,
80 DISABLED_LoadPageWithStyleAnsScript
) {
81 Profile
* profile
= browser()->profile();
83 AndroidDeviceManager::DeviceProviders device_providers
;
85 device_providers
.push_back(
86 TCPDeviceProvider::CreateForLocalhost(kDefaultDebuggingPort
));
87 DevToolsAndroidBridge::Factory::GetForProfile(profile
)->
88 set_device_providers_for_test(device_providers
);
90 ASSERT_TRUE(test_server()->Start());
91 GURL original_url
= test_server()->GetURL(kPortForwardingTestPage
);
93 std::string
forwarding_port("8000");
94 GURL
forwarding_url(original_url
.scheme() + "://" +
95 original_url
.host() + ":" + forwarding_port
+ original_url
.path());
97 PrefService
* prefs
= profile
->GetPrefs();
98 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, true);
100 base::DictionaryValue config
;
102 forwarding_port
, original_url
.host() + ":" + original_url
.port());
103 prefs
->Set(prefs::kDevToolsPortForwardingConfig
, config
);
105 Listener
wait_for_port_forwarding(profile
);
106 content::RunMessageLoop();
108 RemoteDebuggingServer::EnableTetheringForDebug();
110 ui_test_utils::NavigateToURL(browser(), forwarding_url
);
112 content::RenderViewHost
* rvh
= browser()->tab_strip_model()->
113 GetWebContentsAt(0)->GetRenderViewHost();
117 content::ExecuteScriptAndExtractString(
119 "window.domAutomationController.send(document.title)",
121 ASSERT_EQ("Port forwarding test", result
) << "Document has not loaded.";
124 content::ExecuteScriptAndExtractString(
126 "window.domAutomationController.send(getBodyTextContent())",
128 ASSERT_EQ("content", result
) << "Javascript has not loaded.";
131 content::ExecuteScriptAndExtractString(
133 "window.domAutomationController.send(getBodyMarginLeft())",
135 ASSERT_EQ("100px", result
) << "CSS has not loaded.";
137 // Test that disabling port forwarding is handled normally.
138 wait_for_port_forwarding
.set_skip_empty_devices(false);
139 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, false);
140 content::RunMessageLoop();
143 class PortForwardingDisconnectTest
: public PortForwardingTest
{
144 int GetRemoteDebuggingPort() override
{
145 return kAlternativeDebuggingPort
;
149 IN_PROC_BROWSER_TEST_F(PortForwardingDisconnectTest
, DisconnectOnRelease
) {
150 Profile
* profile
= browser()->profile();
152 AndroidDeviceManager::DeviceProviders device_providers
;
154 scoped_refptr
<TCPDeviceProvider
> self_provider(
155 TCPDeviceProvider::CreateForLocalhost(kAlternativeDebuggingPort
));
156 device_providers
.push_back(self_provider
);
158 DevToolsAndroidBridge::Factory::GetForProfile(profile
)->
159 set_device_providers_for_test(device_providers
);
161 ASSERT_TRUE(test_server()->Start());
162 GURL original_url
= test_server()->GetURL(kPortForwardingTestPage
);
164 std::string
forwarding_port("8000");
165 GURL
forwarding_url(original_url
.scheme() + "://" +
166 original_url
.host() + ":" + forwarding_port
+ original_url
.path());
168 PrefService
* prefs
= profile
->GetPrefs();
169 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, true);
171 base::DictionaryValue config
;
173 forwarding_port
, original_url
.host() + ":" + original_url
.port());
174 prefs
->Set(prefs::kDevToolsPortForwardingConfig
, config
);
176 scoped_ptr
<Listener
> wait_for_port_forwarding(new Listener(profile
));
177 content::RunMessageLoop();
179 self_provider
->set_release_callback_for_test(
180 base::Bind(&base::MessageLoop::PostTask
,
181 base::Unretained(base::MessageLoop::current()),
183 base::MessageLoop::QuitClosure()));
184 wait_for_port_forwarding
.reset();
185 content::RunMessageLoop();