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. 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. 138 std::string me2me_pin() { return me2me_pin_; } 139 140 // Helper to get the name of the remote host to connect to. 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. 156 base::FilePath WebAppCrxPath() { return webapp_crx_; } 157 158 // Helper to get the extension ID of the installed chromoting webapp. 159 std::string ChromotingID() { return extension_->id(); } 160 161 // Is this a appsv2 web app? 162 bool is_platform_app() { 163 return extension_->GetType() == extensions::Manifest::TYPE_PLATFORM_APP; 164 } 165 166 // Are we testing an unpacked extension? 167 bool is_unpacked() { 168 return !webapp_unpacked_.empty(); 169 } 170 171 // The "active" WebContents instance the test needs to interact with. 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. 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. 183 bool NoInstall() { return no_install_; } 184 185 // Helper to construct the starting URL of the installed chromoting webapp. 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. 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. 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. 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. 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. 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. 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