Suppression for crbug/241044.
[chromium-blink-merge.git] / chrome / test / chromedriver / commands_unittest.cc
blobdcfc06f2fb3fbcc9ab142a6dd2b68250f202595c
1 // Copyright (c) 2012 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.
5 #include <string>
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/synchronization/lock.h"
13 #include "base/values.h"
14 #include "chrome/test/chromedriver/chrome/status.h"
15 #include "chrome/test/chromedriver/chrome/stub_chrome.h"
16 #include "chrome/test/chromedriver/chrome/stub_web_view.h"
17 #include "chrome/test/chromedriver/chrome/web_view.h"
18 #include "chrome/test/chromedriver/command_executor_impl.h"
19 #include "chrome/test/chromedriver/commands.h"
20 #include "chrome/test/chromedriver/element_commands.h"
21 #include "chrome/test/chromedriver/fake_session_accessor.h"
22 #include "chrome/test/chromedriver/session_commands.h"
23 #include "chrome/test/chromedriver/window_commands.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/webdriver/atoms.h"
27 TEST(CommandsTest, GetStatus) {
28 base::DictionaryValue params;
29 scoped_ptr<base::Value> value;
30 std::string session_id;
31 ASSERT_EQ(
32 kOk, ExecuteGetStatus(params, std::string(), &value, &session_id).code());
33 base::DictionaryValue* dict;
34 ASSERT_TRUE(value->GetAsDictionary(&dict));
35 base::Value* unused;
36 ASSERT_TRUE(dict->Get("os.name", &unused));
37 ASSERT_TRUE(dict->Get("os.version", &unused));
38 ASSERT_TRUE(dict->Get("os.arch", &unused));
39 ASSERT_TRUE(dict->Get("build.version", &unused));
42 namespace {
44 Status ExecuteStubQuit(
45 int* count,
46 const base::DictionaryValue& params,
47 const std::string& session_id,
48 scoped_ptr<base::Value>* value,
49 std::string* out_session_id) {
50 if (*count == 0) {
51 EXPECT_STREQ("id", session_id.c_str());
52 } else {
53 EXPECT_STREQ("id2", session_id.c_str());
55 (*count)++;
56 return Status(kOk);
59 } // namespace
61 TEST(CommandsTest, QuitAll) {
62 SessionMap map;
63 Session session("id");
64 Session session2("id2");
65 map.Set(session.id,
66 scoped_refptr<SessionAccessor>(new FakeSessionAccessor(&session)));
67 map.Set(session2.id,
68 scoped_refptr<SessionAccessor>(new FakeSessionAccessor(&session2)));
70 int count = 0;
71 Command cmd = base::Bind(&ExecuteStubQuit, &count);
72 base::DictionaryValue params;
73 scoped_ptr<base::Value> value;
74 std::string session_id;
75 Status status =
76 ExecuteQuitAll(cmd, &map, params, std::string(), &value, &session_id);
77 ASSERT_EQ(kOk, status.code());
78 ASSERT_FALSE(value.get());
79 ASSERT_EQ(2, count);
82 TEST(CommandsTest, Quit) {
83 SessionMap map;
84 Session session("id", scoped_ptr<Chrome>(new StubChrome()));
85 ASSERT_TRUE(session.thread.Start());
86 scoped_refptr<FakeSessionAccessor> session_accessor(
87 new FakeSessionAccessor(&session));
88 map.Set(session.id, session_accessor);
89 base::DictionaryValue params;
90 scoped_ptr<base::Value> value;
91 std::string out_session_id;
92 ASSERT_EQ(kOk,
93 ExecuteSessionCommand(&map, base::Bind(ExecuteQuit, &map), params,
94 session.id, &value, &out_session_id).code());
95 ASSERT_FALSE(map.Has(session.id));
96 ASSERT_TRUE(session_accessor->IsSessionDeleted());
97 ASSERT_FALSE(value.get());
100 namespace {
102 class FailsToQuitChrome : public StubChrome {
103 public:
104 FailsToQuitChrome() {}
105 virtual ~FailsToQuitChrome() {}
107 // Overridden from Chrome:
108 virtual Status Quit() OVERRIDE {
109 return Status(kUnknownError);
113 } // namespace
115 TEST(CommandsTest, QuitFails) {
116 SessionMap map;
117 Session session("id", scoped_ptr<Chrome>(new FailsToQuitChrome()));
118 ASSERT_TRUE(session.thread.Start());
119 scoped_refptr<FakeSessionAccessor> session_accessor(
120 new FakeSessionAccessor(&session));
121 map.Set(session.id, session_accessor);
122 base::DictionaryValue params;
123 scoped_ptr<base::Value> value;
124 std::string out_session_id;
125 ASSERT_EQ(kUnknownError,
126 ExecuteSessionCommand(&map, base::Bind(ExecuteQuit, &map), params,
127 session.id, &value, &out_session_id).code());
128 ASSERT_FALSE(map.Has(session.id));
129 ASSERT_TRUE(session_accessor->IsSessionDeleted());
130 ASSERT_FALSE(value.get());
133 namespace {
135 enum TestScenario {
136 kElementExistsQueryOnce = 0,
137 kElementExistsQueryTwice,
138 kElementNotExistsQueryOnce,
139 kElementExistsTimeout
142 class FindElementWebView : public StubWebView {
143 public:
144 FindElementWebView(bool only_one, TestScenario scenario)
145 : StubWebView("1"), only_one_(only_one), scenario_(scenario),
146 current_count_(0) {
147 switch (scenario_) {
148 case kElementExistsQueryOnce:
149 case kElementExistsQueryTwice:
150 case kElementExistsTimeout: {
151 if (only_one_) {
152 base::DictionaryValue element;
153 element.SetString("ELEMENT", "1");
154 result_.reset(element.DeepCopy());
155 } else {
156 base::DictionaryValue element1;
157 element1.SetString("ELEMENT", "1");
158 base::DictionaryValue element2;
159 element2.SetString("ELEMENT", "2");
160 base::ListValue list;
161 list.Append(element1.DeepCopy());
162 list.Append(element2.DeepCopy());
163 result_.reset(list.DeepCopy());
165 break;
167 case kElementNotExistsQueryOnce: {
168 if (only_one_)
169 result_.reset(base::Value::CreateNullValue());
170 else
171 result_.reset(new base::ListValue());
172 break;
176 virtual ~FindElementWebView() {}
178 void Verify(const std::string& expected_frame,
179 const base::ListValue* expected_args,
180 const base::Value* actrual_result) {
181 EXPECT_EQ(expected_frame, frame_);
182 std::string function;
183 if (only_one_)
184 function = webdriver::atoms::asString(webdriver::atoms::FIND_ELEMENT);
185 else
186 function = webdriver::atoms::asString(webdriver::atoms::FIND_ELEMENTS);
187 EXPECT_EQ(function, function_);
188 ASSERT_TRUE(args_.get());
189 EXPECT_TRUE(expected_args->Equals(args_.get()));
190 ASSERT_TRUE(actrual_result);
191 EXPECT_TRUE(result_->Equals(actrual_result));
194 // Overridden from WebView:
195 virtual Status CallFunction(const std::string& frame,
196 const std::string& function,
197 const base::ListValue& args,
198 scoped_ptr<base::Value>* result) OVERRIDE {
199 ++current_count_;
200 if (scenario_ == kElementExistsTimeout ||
201 (scenario_ == kElementExistsQueryTwice && current_count_ == 1)) {
202 // Always return empty result when testing timeout.
203 if (only_one_)
204 result->reset(base::Value::CreateNullValue());
205 else
206 result->reset(new base::ListValue());
207 } else {
208 switch (scenario_) {
209 case kElementExistsQueryOnce:
210 case kElementNotExistsQueryOnce: {
211 EXPECT_EQ(1, current_count_);
212 break;
214 case kElementExistsQueryTwice: {
215 EXPECT_EQ(2, current_count_);
216 break;
218 default: {
219 break;
223 result->reset(result_->DeepCopy());
224 frame_ = frame;
225 function_ = function;
226 args_.reset(args.DeepCopy());
228 return Status(kOk);
231 private:
232 bool only_one_;
233 TestScenario scenario_;
234 int current_count_;
235 std::string frame_;
236 std::string function_;
237 scoped_ptr<base::ListValue> args_;
238 scoped_ptr<base::Value> result_;
241 } // namespace
243 TEST(CommandsTest, SuccessfulFindElement) {
244 FindElementWebView web_view(true, kElementExistsQueryTwice);
245 Session session("id");
246 session.implicit_wait = 1000;
247 session.SwitchToSubFrame("frame_id1", std::string());
248 base::DictionaryValue params;
249 params.SetString("using", "id");
250 params.SetString("value", "a");
251 scoped_ptr<base::Value> result;
252 ASSERT_EQ(kOk,
253 ExecuteFindElement(1, &session, &web_view, params, &result).code());
254 base::DictionaryValue param;
255 param.SetString("id", "a");
256 base::ListValue expected_args;
257 expected_args.Append(param.DeepCopy());
258 web_view.Verify("frame_id1", &expected_args, result.get());
261 TEST(CommandsTest, FailedFindElement) {
262 FindElementWebView web_view(true, kElementNotExistsQueryOnce);
263 Session session("id");
264 base::DictionaryValue params;
265 params.SetString("using", "id");
266 params.SetString("value", "a");
267 scoped_ptr<base::Value> result;
268 ASSERT_EQ(kNoSuchElement,
269 ExecuteFindElement(1, &session, &web_view, params, &result).code());
272 TEST(CommandsTest, SuccessfulFindElements) {
273 FindElementWebView web_view(false, kElementExistsQueryTwice);
274 Session session("id");
275 session.implicit_wait = 1000;
276 session.SwitchToSubFrame("frame_id2", std::string());
277 base::DictionaryValue params;
278 params.SetString("using", "name");
279 params.SetString("value", "b");
280 scoped_ptr<base::Value> result;
281 ASSERT_EQ(
282 kOk,
283 ExecuteFindElements(1, &session, &web_view, params, &result).code());
284 base::DictionaryValue param;
285 param.SetString("name", "b");
286 base::ListValue expected_args;
287 expected_args.Append(param.DeepCopy());
288 web_view.Verify("frame_id2", &expected_args, result.get());
291 TEST(CommandsTest, FailedFindElements) {
292 Session session("id");
293 FindElementWebView web_view(false, kElementNotExistsQueryOnce);
294 base::DictionaryValue params;
295 params.SetString("using", "id");
296 params.SetString("value", "a");
297 scoped_ptr<base::Value> result;
298 ASSERT_EQ(
299 kOk,
300 ExecuteFindElements(1, &session, &web_view, params, &result).code());
301 base::ListValue* list;
302 ASSERT_TRUE(result->GetAsList(&list));
303 ASSERT_EQ(0U, list->GetSize());
306 TEST(CommandsTest, SuccessfulFindChildElement) {
307 FindElementWebView web_view(true, kElementExistsQueryTwice);
308 Session session("id");
309 session.implicit_wait = 1000;
310 session.SwitchToSubFrame("frame_id3", std::string());
311 base::DictionaryValue params;
312 params.SetString("using", "tag name");
313 params.SetString("value", "div");
314 std::string element_id = "1";
315 scoped_ptr<base::Value> result;
316 ASSERT_EQ(
317 kOk,
318 ExecuteFindChildElement(
319 1, &session, &web_view, element_id, params, &result).code());
320 base::DictionaryValue locator_param;
321 locator_param.SetString("tag name", "div");
322 base::DictionaryValue root_element_param;
323 root_element_param.SetString("ELEMENT", element_id);
324 base::ListValue expected_args;
325 expected_args.Append(locator_param.DeepCopy());
326 expected_args.Append(root_element_param.DeepCopy());
327 web_view.Verify("frame_id3", &expected_args, result.get());
330 TEST(CommandsTest, FailedFindChildElement) {
331 Session session("id");
332 FindElementWebView web_view(true, kElementNotExistsQueryOnce);
333 base::DictionaryValue params;
334 params.SetString("using", "id");
335 params.SetString("value", "a");
336 std::string element_id = "1";
337 scoped_ptr<base::Value> result;
338 ASSERT_EQ(
339 kNoSuchElement,
340 ExecuteFindChildElement(
341 1, &session, &web_view, element_id, params, &result).code());
344 TEST(CommandsTest, SuccessfulFindChildElements) {
345 FindElementWebView web_view(false, kElementExistsQueryTwice);
346 Session session("id");
347 session.implicit_wait = 1000;
348 session.SwitchToSubFrame("frame_id4", std::string());
349 base::DictionaryValue params;
350 params.SetString("using", "class name");
351 params.SetString("value", "c");
352 std::string element_id = "1";
353 scoped_ptr<base::Value> result;
354 ASSERT_EQ(
355 kOk,
356 ExecuteFindChildElements(
357 1, &session, &web_view, element_id, params, &result).code());
358 base::DictionaryValue locator_param;
359 locator_param.SetString("class name", "c");
360 base::DictionaryValue root_element_param;
361 root_element_param.SetString("ELEMENT", element_id);
362 base::ListValue expected_args;
363 expected_args.Append(locator_param.DeepCopy());
364 expected_args.Append(root_element_param.DeepCopy());
365 web_view.Verify("frame_id4", &expected_args, result.get());
368 TEST(CommandsTest, FailedFindChildElements) {
369 Session session("id");
370 FindElementWebView web_view(false, kElementNotExistsQueryOnce);
371 base::DictionaryValue params;
372 params.SetString("using", "id");
373 params.SetString("value", "a");
374 std::string element_id = "1";
375 scoped_ptr<base::Value> result;
376 ASSERT_EQ(
377 kOk,
378 ExecuteFindChildElements(
379 1, &session, &web_view, element_id, params, &result).code());
380 base::ListValue* list;
381 ASSERT_TRUE(result->GetAsList(&list));
382 ASSERT_EQ(0U, list->GetSize());
385 TEST(CommandsTest, TimeoutInFindElement) {
386 Session session("id");
387 FindElementWebView web_view(true, kElementExistsTimeout);
388 session.implicit_wait = 2;
389 base::DictionaryValue params;
390 params.SetString("using", "id");
391 params.SetString("value", "a");
392 params.SetString("id", "1");
393 scoped_ptr<base::Value> result;
394 ASSERT_EQ(kNoSuchElement,
395 ExecuteFindElement(1, &session, &web_view, params, &result).code());
398 namespace {
400 class ErrorCallFunctionWebView : public StubWebView {
401 public:
402 explicit ErrorCallFunctionWebView(StatusCode code)
403 : StubWebView("1"), code_(code) {}
404 virtual ~ErrorCallFunctionWebView() {}
406 // Overridden from WebView:
407 virtual Status CallFunction(const std::string& frame,
408 const std::string& function,
409 const base::ListValue& args,
410 scoped_ptr<base::Value>* result) OVERRIDE {
411 return Status(code_);
414 private:
415 StatusCode code_;
418 } // namespace
420 TEST(CommandsTest, ErrorFindElement) {
421 Session session("id");
422 ErrorCallFunctionWebView web_view(kUnknownError);
423 base::DictionaryValue params;
424 params.SetString("using", "id");
425 params.SetString("value", "a");
426 scoped_ptr<base::Value> value;
427 ASSERT_EQ(kUnknownError,
428 ExecuteFindElement(1, &session, &web_view, params, &value).code());
429 ASSERT_EQ(kUnknownError,
430 ExecuteFindElements(1, &session, &web_view, params, &value).code());
433 TEST(CommandsTest, ErrorFindChildElement) {
434 Session session("id");
435 ErrorCallFunctionWebView web_view(kStaleElementReference);
436 base::DictionaryValue params;
437 params.SetString("using", "id");
438 params.SetString("value", "a");
439 std::string element_id = "1";
440 scoped_ptr<base::Value> result;
441 ASSERT_EQ(
442 kStaleElementReference,
443 ExecuteFindChildElement(
444 1, &session, &web_view, element_id, params, &result).code());
445 ASSERT_EQ(
446 kStaleElementReference,
447 ExecuteFindChildElements(
448 1, &session, &web_view, element_id, params, &result).code());