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
3 // found in the LICENSE file.
4
5 #ifndef CHROME_TEST_REMOTING_REMOTE_DESKTOP_BROWSERTEST_H_
6 #define CHROME_TEST_REMOTING_REMOTE_DESKTOP_BROWSERTEST_H_
7
8 #include "chrome/browser/apps/app_browsertest_util.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/ui/tabs/tab_strip_model.h"
11 #include "chrome/test/base/ui_test_utils.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/test/browser_test_utils.h"
14 #include "net/dns/mock_host_resolver.h"
15
16 namespace {
17 // Command line arguments specific to the chromoting browser tests.
18 const char kOverrideUserDataDir[] = "override-user-data-dir";
19 const char kNoCleanup[] = "no-cleanup";
20 const char kNoInstall[] = "no-install";
21 const char kWebAppCrx[] = "webapp-crx";
22 const char kWebAppUnpacked[] = "webapp-unpacked";
23 const char kUsername[] = "username";
24 const char kkPassword[] = "password";
25 const char kMe2MePin[] = "me2me-pin";
26 const char kRemoteHostName[] = "remote-host-name";
27
28 // ASSERT_TRUE can only be used in void returning functions. This version
29 // should be used in non-void-returning functions.
_ASSERT_TRUE(bool condition)30 inline void _ASSERT_TRUE(bool condition) {
31 ASSERT_TRUE(condition);
32 return;
33 }
34
35 } // namespace
36
37 using extensions::Extension;
38
39 namespace remoting {
40
41 class RemoteDesktopBrowserTest : public extensions::PlatformAppBrowserTest {
42 public:
43 RemoteDesktopBrowserTest();
44 virtual ~RemoteDesktopBrowserTest();
45
46 // InProcessBrowserTest Overrides
47 virtual void SetUp() OVERRIDE;
48 virtual void SetUpOnMainThread() OVERRIDE;
49
50 protected:
51 // InProcessBrowserTest Overrides
52 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE;
53
54 // InProcessBrowserTest Overrides
55 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
56
57 // The following helpers each perform a simple task.
58
59 // Verify the test has access to the internet (specifically google.com)
60 void VerifyInternetAccess();
61
62 // Install the chromoting extension from a crx file.
63 void InstallChromotingAppCrx();
64
65 // Install the unpacked chromoting extension.
66 void InstallChromotingAppUnpacked();
67
68 // Uninstall the chromoting extension.
69 void UninstallChromotingApp();
70
71 // Test whether the chromoting extension is installed.
72 void VerifyChromotingLoaded(bool expected);
73
74 // Launch the chromoting app.
75 void LaunchChromotingApp();
76
77 // Authorize: grant extended access permission to the user's computer.
78 void Authorize();
79
80 // Authenticate: sign in to google using the credentials provided.
81 void Authenticate();
82
83 // Approve: grant the chromoting app necessary permissions.
84 void Approve();
85
86 // Click on "Get Started" in the Me2Me section and show the host list.
87 void ExpandMe2Me();
88
89 // Disconnect the active Me2Me session.
90 void DisconnectMe2Me();
91
92 // Simulate a key event.
93 void SimulateKeyPressWithCode(ui::KeyboardCode keyCode, const char* code);
94
95 void SimulateKeyPressWithCode(ui::KeyboardCode keyCode,
96 const char* code,
97 bool control,
98 bool shift,
99 bool alt,
100 bool command);
101
102 // Simulate typing a character
103 void SimulateCharInput(char c);
104
105 // Simulate typing a string
106 void SimulateStringInput(const std::string& input);
107
108 // Helper to simulate a left button mouse click.
109 void SimulateMouseLeftClickAt(int x, int y);
110
111 // Helper to simulate a mouse click.
112 void SimulateMouseClickAt(
113 int modifiers, blink::WebMouseEvent::Button button, int x, int y);
114
115 // The following helpers each perform a composite task.
116
117 // Install the chromoting extension
118 void Install();
119
120 // Clean up after the test.
121 void Cleanup();
122
123 // Perform all the auth steps: authorization, authenticattion, etc.
124 // It starts from the chromoting main page unauthenticated and ends up back
125 // on the chromoting main page authenticated and ready to go.
126 void Auth();
127
128 // Connect to the local host through Me2Me.
129 void ConnectToLocalHost(bool remember_pin);
130
131 // Connect to a remote host through Me2Me.
132 void ConnectToRemoteHost(const std::string& host_name, bool remember_pin);
133
134 // Enter the pin number and connect.
135 void EnterPin(const std::string& name, bool remember_pin);
136
137 // Helper to get the pin number used for me2me authentication.
me2me_pin()138 std::string me2me_pin() { return me2me_pin_; }
139
140 // Helper to get the name of the remote host to connect to.
remote_host_name()141 std::string remote_host_name() { return remote_host_name_; }
142
143 // Change behavior of the default host resolver to allow DNS lookup
144 // to proceed instead of being blocked by the test infrastructure.
145 void EnableDNSLookupForThisTest(
146 net::RuleBasedHostResolverProc* host_resolver);
147
148 // We need to reset the DNS lookup when we finish, or the test will fail.
149 void DisableDNSLookupForThisTest();
150
151 void ParseCommandLine();
152
153 // Accessor methods.
154
155 // Helper to get the path to the crx file of the webapp to be tested.
WebAppCrxPath()156 base::FilePath WebAppCrxPath() { return webapp_crx_; }
157
158 // Helper to get the extension ID of the installed chromoting webapp.
ChromotingID()159 std::string ChromotingID() { return extension_->id(); }
160
161 // Is this a appsv2 web app?
is_platform_app()162 bool is_platform_app() {
163 return extension_->GetType() == extensions::Manifest::TYPE_PLATFORM_APP;
164 }
165
166 // Are we testing an unpacked extension?
is_unpacked()167 bool is_unpacked() {
168 return !webapp_unpacked_.empty();
169 }
170
171 // The "active" WebContents instance the test needs to interact with.
active_web_contents()172 content::WebContents* active_web_contents() {
173 DCHECK(!web_contents_stack_.empty());
174 return web_contents_stack_.back();
175 }
176
177 // Whether to perform the cleanup tasks (uninstalling chromoting, etc).
178 // This is useful for diagnostic purposes.
NoCleanup()179 bool NoCleanup() { return no_cleanup_; }
180
181 // Whether to install the chromoting extension before running the test cases.
182 // This is useful for diagnostic purposes.
NoInstall()183 bool NoInstall() { return no_install_; }
184
185 // Helper to construct the starting URL of the installed chromoting webapp.
Chromoting_Main_URL()186 GURL Chromoting_Main_URL() {
187 return GURL("chrome-extension://" + ChromotingID() + "/main.html");
188 }
189
190 // Helper to retrieve the current URL in the active WebContents.
GetCurrentURL()191 GURL GetCurrentURL() {
192 return active_web_contents()->GetURL();
193 }
194
195 // Helpers to execute javascript code on a web page.
196
197 // Helper to execute a javascript code snippet in the active WebContents.
198 void ExecuteScript(const std::string& script);
199
200 // Helper to execute a javascript code snippet in the active WebContents
201 // and wait for page load to complete.
202 void ExecuteScriptAndWaitForAnyPageLoad(const std::string& script);
203
204 // Helper to execute a javascript code snippet in the active WebContents
205 // and extract the boolean result.
ExecuteScriptAndExtractBool(const std::string & script)206 bool ExecuteScriptAndExtractBool(const std::string& script) {
207 return ExecuteScriptAndExtractBool(active_web_contents(), script);
208 }
209
210 // Helper to execute a javascript code snippet and extract the boolean result.
211 static bool ExecuteScriptAndExtractBool(content::WebContents* web_contents,
212 const std::string& script);
213
214 // Helper to execute a javascript code snippet in the active WebContents
215 // and extract the int result.
ExecuteScriptAndExtractInt(const std::string & script)216 int ExecuteScriptAndExtractInt(const std::string& script) {
217 return ExecuteScriptAndExtractInt(active_web_contents(), script);
218 }
219
220 // Helper to execute a javascript code snippet and extract the int result.
221 static int ExecuteScriptAndExtractInt(content::WebContents* web_contents,
222 const std::string& script);
223
224 // Helper to execute a javascript code snippet in the active WebContents
225 // and extract the string result.
ExecuteScriptAndExtractString(const std::string & script)226 std::string ExecuteScriptAndExtractString(const std::string& script) {
227 return ExecuteScriptAndExtractString(active_web_contents(), script);
228 }
229
230 // Helper to execute a javascript code snippet and extract the string result.
231 static std::string ExecuteScriptAndExtractString(
232 content::WebContents* web_contents, const std::string& script);
233
234 // Helper to check whether an html element with the given name exists in
235 // the active WebContents.
HtmlElementExists(const std::string & name)236 bool HtmlElementExists(const std::string& name) {
237 return ExecuteScriptAndExtractBool(
238 "document.getElementById(\"" + name + "\") != null");
239 }
240
241 // Helper to check whether a html element with the given name is visible in
242 // the active WebContents.
243 bool HtmlElementVisible(const std::string& name);
244
245 // Click on the named HTML control in the active WebContents.
246 void ClickOnControl(const std::string& name);
247
248 // Wait for the me2me connection to be established.
249 void WaitForConnection();
250
251 // Checking whether the localHost has been initialized.
252 bool IsLocalHostReady();
253
254 // Callback used by EnterPin to check whether the pin form is visible
255 // and to dismiss the host-needs-update dialog.
256 bool IsPinFormVisible();
257
258 // Callback used by WaitForConnection to check whether the connection
259 // has been established.
260 bool IsSessionConnected();
261
262 // Callback used by Approve to check whether the chromoting app has
263 // successfully authenticated with the Google services.
IsAuthenticated()264 bool IsAuthenticated() {
265 return IsAuthenticatedInWindow(active_web_contents());
266 }
267
268 // If the "Host version out-of-date" form is visible, dismiss it.
269 void DismissHostVersionWarningIfVisible();
270
271 // Callback used by Approve to check whether the chromoting app has
272 // successfully authenticated with the Google services.
273 static bool IsAuthenticatedInWindow(content::WebContents* web_contents);
274
275 private:
276 // Fields
277
278 // This test needs to make live DNS requests for access to
279 // GAIA and sync server URLs under google.com. We use a scoped version
280 // to override the default resolver while the test is active.
281 scoped_ptr<net::ScopedDefaultHostResolverProc> mock_host_resolver_override_;
282
283 // Stores all the WebContents instance in a stack so that we can easily
284 // return to the previous instance.
285 // The active WebContents instance is always stored at the top of the stack.
286 // Initially the stack contains the WebContents instance created by
287 // InProcessBrowserTest as the initial context to run test in.
288 // Whenever a WebContents instance is spawned and needs attention we
289 // push it onto the stack and that becomes the active instance.
290 // And once we are done with the current WebContents instance
291 // we pop it off the stack, returning to the previous instance.
292 std::vector<content::WebContents*> web_contents_stack_;
293
294 bool no_cleanup_;
295 bool no_install_;
296 const Extension* extension_;
297 base::FilePath webapp_crx_;
298 base::FilePath webapp_unpacked_;
299 std::string username_;
300 std::string password_;
301 std::string me2me_pin_;
302 std::string remote_host_name_;
303 };
304
305 } // namespace remoting
306
307 #endif // CHROME_TEST_REMOTING_REMOTE_DESKTOP_BROWSERTEST_H_
308