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