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 #include "base/file_util.h" 6 #include "base/files/file_path.h" 7 #include "chrome/test/remoting/remote_desktop_browsertest.h" 8 #include "chrome/test/remoting/waiter.h" 9 10 namespace remoting { 11 12 class Me2MeBrowserTest : public RemoteDesktopBrowserTest { 13 protected: 14 void TestKeyboardInput(); 15 void TestMouseInput(); 16 17 void ConnectPinlessAndCleanupPairings(bool cleanup_all); 18 bool IsPairingSpinnerHidden(); 19 }; 20 21 IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, 22 MANUAL_Me2Me_Connect_Local_Host) { 23 VerifyInternetAccess(); 24 Install(); 25 LaunchChromotingApp(); 26 27 // Authorize, Authenticate, and Approve. 28 Auth(); 29 ExpandMe2Me(); 30 31 ConnectToLocalHost(false); 32 33 TestKeyboardInput(); 34 TestMouseInput(); 35 36 DisconnectMe2Me(); 37 Cleanup(); 38 } 39 40 IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, 41 MANUAL_Me2Me_Connect_Remote_Host) { 42 VerifyInternetAccess(); 43 Install(); 44 LaunchChromotingApp(); 45 46 // Authorize, Authenticate, and Approve. 47 Auth(); 48 ExpandMe2Me(); 49 50 ConnectToRemoteHost(remote_host_name(), false); 51 52 // TODO(weitaosu): Find a way to verify keyboard input injection. 53 // We cannot use TestKeyboardInput because it assumes 54 // that the client and the host are on the same machine. 55 56 DisconnectMe2Me(); 57 Cleanup(); 58 } 59 60 IN_PROC_BROWSER_TEST_F(Me2MeBrowserTest, 61 MANUAL_Me2Me_Connect_Pinless) { 62 VerifyInternetAccess(); 63 Install(); 64 LaunchChromotingApp(); 65 66 // Authorize, Authenticate, and Approve. 67 Auth(); 68 ExpandMe2Me(); 69 70 ASSERT_FALSE(HtmlElementVisible("paired-client-manager-message")) 71 << "The host must have no pairings before running the pinless test."; 72 73 // Test that cleanup works with either the Delete or Delete all buttons. 74 ConnectPinlessAndCleanupPairings(false); 75 ConnectPinlessAndCleanupPairings(true); 76 77 Cleanup(); 78 } 79 80 // Typing a command which writes to a temp file and then verify the contents of 81 // the file. 82 void Me2MeBrowserTest::TestKeyboardInput() { 83 // Start a terminal window with ctrl+alt+T 84 SimulateKeyPressWithCode(ui::VKEY_T, "KeyT", true, false, true, false); 85 86 // Wait for the keyboard events to be sent to and processed by the host. 87 ASSERT_TRUE(TimeoutWaiter(base::TimeDelta::FromMilliseconds(300)).Wait()); 88 89 base::FilePath temp_file; 90 EXPECT_TRUE(base::CreateTemporaryFile(&temp_file)); 91 92 // Write some text into the temp file. 93 std::string text = "Abigail"; 94 std::string command = "echo -n " + text + " > " + 95 temp_file.MaybeAsASCII() + "\n"; 96 SimulateStringInput(command); 97 SimulateStringInput("exit\n"); 98 99 // Wait for the keyboard events to be sent to and processed by the host. 100 ASSERT_TRUE(TimeoutWaiter(base::TimeDelta::FromSeconds(1)).Wait()); 101 102 // Read the content of the temp file. 103 std::string content; 104 EXPECT_TRUE(base::ReadFileToString(temp_file, &content)); 105 106 EXPECT_EQ(text, content); 107 108 EXPECT_TRUE(base::DeleteFile(temp_file, false)); 109 } 110 111 void Me2MeBrowserTest::TestMouseInput() { 112 SimulateMouseLeftClickAt(10, 50); 113 // TODO: Verify programatically the mouse events are received by the host. 114 // This will be tricky as it depends on the host OS, window manager, desktop 115 // layout, and screen resolution. Until then we need to visually verify that 116 // "Dash Home" is clicked on a Unity window manager. 117 ASSERT_TRUE(TimeoutWaiter(base::TimeDelta::FromSeconds(5)).Wait()); 118 } 119 120 void Me2MeBrowserTest::ConnectPinlessAndCleanupPairings(bool cleanup_all) { 121 // First connection: verify that a PIN is requested, and request pairing. 122 ConnectToLocalHost(true); 123 DisconnectMe2Me(); 124 125 // TODO(jamiewalch): This reload is only needed because there's a bug in the 126 // web-app whereby it doesn't refresh its pairing state correctly. 127 // http://crbug.com/311290 128 LaunchChromotingApp(); 129 ASSERT_TRUE(HtmlElementVisible("paired-client-manager-message")); 130 131 // Second connection: verify that no PIN is requested. 132 ClickOnControl("this-host-connect"); 133 WaitForConnection(); 134 DisconnectMe2Me(); 135 136 // Clean up pairings. 137 ClickOnControl("open-paired-client-manager-dialog"); 138 ASSERT_TRUE(HtmlElementVisible("paired-client-manager-dialog")); 139 140 if (cleanup_all) { 141 ClickOnControl("delete-all-paired-clients"); 142 } else { 143 std::string host_id = ExecuteScriptAndExtractString( 144 "remoting.pairedClientManager.getFirstClientIdForTesting_()"); 145 std::string node_id = "delete-client-" + host_id; 146 ClickOnControl(node_id); 147 } 148 149 // Wait for the "working" spinner to disappear. The spinner is shown by both 150 // methods of deleting a host and is removed when the operation completes. 151 ConditionalTimeoutWaiter waiter( 152 base::TimeDelta::FromSeconds(5), 153 base::TimeDelta::FromMilliseconds(200), 154 base::Bind(&Me2MeBrowserTest::IsPairingSpinnerHidden, this)); 155 EXPECT_TRUE(waiter.Wait()); 156 EXPECT_TRUE(ExecuteScriptAndExtractBool( 157 "document.getElementById('delete-all-paired-clients').disabled")); 158 159 ClickOnControl("close-paired-client-manager-dialog"); 160 ASSERT_FALSE(HtmlElementVisible("paired-client-manager-dialog")); 161 ASSERT_FALSE(HtmlElementVisible("paired-client-manager-message")); 162 } 163 164 bool Me2MeBrowserTest::IsPairingSpinnerHidden() { 165 return !HtmlElementVisible("paired-client-manager-dialog-working"); 166 } 167 168 } // namespace remoting 169