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/prefs/pref_service.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
10 #include "chrome/browser/devtools/device/self_device_provider.h"
11 #include "chrome/browser/devtools/remote_debugging_server.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/in_process_browser_test.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/browser_test_utils.h"
21 #include "content/public/test/test_utils.h"
24 const char kPortForwardingTestPage
[] =
25 "files/devtools/port_forwarding/main.html";
27 const int kDefaultDebuggingPort
= 9223;
28 const int kAlternativeDebuggingPort
= 9224;
32 class PortForwardingTest
: public InProcessBrowserTest
{
33 virtual int GetRemoteDebuggingPort() {
34 return kDefaultDebuggingPort
;
37 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
38 InProcessBrowserTest::SetUpCommandLine(command_line
);
39 command_line
->AppendSwitchASCII(switches::kRemoteDebuggingPort
,
40 base::IntToString(GetRemoteDebuggingPort()));
44 class Listener
: public DevToolsAndroidBridge::PortForwardingListener
{
46 explicit Listener(Profile
* profile
)
48 skip_empty_devices_(true) {
49 DevToolsAndroidBridge::Factory::GetForProfile(profile_
)->
50 AddPortForwardingListener(this);
53 ~Listener() override
{
54 DevToolsAndroidBridge::Factory::GetForProfile(profile_
)->
55 RemovePortForwardingListener(this);
58 void PortStatusChanged(const ForwardingStatus
& status
) override
{
59 if (status
.empty() && skip_empty_devices_
)
61 base::MessageLoop::current()->PostTask(
62 FROM_HERE
, base::MessageLoop::QuitClosure());
65 void set_skip_empty_devices(bool skip_empty_devices
) {
66 skip_empty_devices_
= skip_empty_devices
;
71 bool skip_empty_devices_
;
75 IN_PROC_BROWSER_TEST_F(PortForwardingTest
,
76 LoadPageWithStyleAnsScript
) {
77 Profile
* profile
= browser()->profile();
79 AndroidDeviceManager::DeviceProviders device_providers
;
80 device_providers
.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort
));
81 DevToolsAndroidBridge::Factory::GetForProfile(profile
)->
82 set_device_providers_for_test(device_providers
);
84 ASSERT_TRUE(test_server()->Start());
85 GURL original_url
= test_server()->GetURL(kPortForwardingTestPage
);
87 std::string
forwarding_port("8000");
88 GURL
forwarding_url(original_url
.scheme() + "://" +
89 original_url
.host() + ":" + forwarding_port
+ original_url
.path());
91 PrefService
* prefs
= profile
->GetPrefs();
92 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, true);
94 base::DictionaryValue config
;
96 forwarding_port
, original_url
.host() + ":" + original_url
.port());
97 prefs
->Set(prefs::kDevToolsPortForwardingConfig
, config
);
99 Listener
wait_for_port_forwarding(profile
);
100 content::RunMessageLoop();
102 RemoteDebuggingServer::EnableTetheringForDebug();
104 ui_test_utils::NavigateToURL(browser(), forwarding_url
);
106 content::RenderViewHost
* rvh
= browser()->tab_strip_model()->
107 GetWebContentsAt(0)->GetRenderViewHost();
111 content::ExecuteScriptAndExtractString(
113 "window.domAutomationController.send(document.title)",
115 ASSERT_EQ("Port forwarding test", result
) << "Document has not loaded.";
118 content::ExecuteScriptAndExtractString(
120 "window.domAutomationController.send(getBodyTextContent())",
122 ASSERT_EQ("content", result
) << "Javascript has not loaded.";
125 content::ExecuteScriptAndExtractString(
127 "window.domAutomationController.send(getBodyMarginLeft())",
129 ASSERT_EQ("100px", result
) << "CSS has not loaded.";
131 // Test that disabling port forwarding is handled normally.
132 wait_for_port_forwarding
.set_skip_empty_devices(false);
133 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, false);
134 content::RunMessageLoop();
137 class PortForwardingDisconnectTest
: public PortForwardingTest
{
138 int GetRemoteDebuggingPort() override
{
139 return kAlternativeDebuggingPort
;
143 IN_PROC_BROWSER_TEST_F(PortForwardingDisconnectTest
, DisconnectOnRelease
) {
144 Profile
* profile
= browser()->profile();
146 AndroidDeviceManager::DeviceProviders device_providers
;
148 scoped_refptr
<SelfAsDeviceProvider
> self_provider(
149 new SelfAsDeviceProvider(kAlternativeDebuggingPort
));
150 device_providers
.push_back(self_provider
);
152 DevToolsAndroidBridge::Factory::GetForProfile(profile
)->
153 set_device_providers_for_test(device_providers
);
155 ASSERT_TRUE(test_server()->Start());
156 GURL original_url
= test_server()->GetURL(kPortForwardingTestPage
);
158 std::string
forwarding_port("8000");
159 GURL
forwarding_url(original_url
.scheme() + "://" +
160 original_url
.host() + ":" + forwarding_port
+ original_url
.path());
162 PrefService
* prefs
= profile
->GetPrefs();
163 prefs
->SetBoolean(prefs::kDevToolsPortForwardingEnabled
, true);
165 base::DictionaryValue config
;
167 forwarding_port
, original_url
.host() + ":" + original_url
.port());
168 prefs
->Set(prefs::kDevToolsPortForwardingConfig
, config
);
170 scoped_ptr
<Listener
> wait_for_port_forwarding(new Listener(profile
));
171 content::RunMessageLoop();
173 self_provider
->set_release_callback_for_test(
174 base::Bind(&base::MessageLoop::PostTask
,
175 base::Unretained(base::MessageLoop::current()),
177 base::MessageLoop::QuitClosure()));
178 wait_for_port_forwarding
.reset();
179 content::RunMessageLoop();