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
10namespace remoting {
11
12class Me2MeBrowserTest : public RemoteDesktopBrowserTest {
13 protected:
14  void TestKeyboardInput();
15  void TestMouseInput();
16
17  void ConnectPinlessAndCleanupPairings(bool cleanup_all);
18  bool IsPairingSpinnerHidden();
19};
20
21IN_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
40IN_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
60IN_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.
82void 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
111void 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
120void 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
164bool Me2MeBrowserTest::IsPairingSpinnerHidden() {
165  return !HtmlElementVisible("paired-client-manager-dialog-working");
166}
167
168}  // namespace remoting
169