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