Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: chrome/test/chromedriver/devtools_client_impl_unittest.cc

Issue 12848005: [chromedriver] Separate stuff of chrome from chromedriver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments and fix compile error on mac. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include <list>
6 #include <string>
7
8 #include "base/bind.h"
9 #include "base/compiler_specific.h"
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/values.h"
14 #include "chrome/test/chromedriver/devtools_client_impl.h"
15 #include "chrome/test/chromedriver/devtools_event_listener.h"
16 #include "chrome/test/chromedriver/net/sync_websocket.h"
17 #include "chrome/test/chromedriver/net/sync_websocket_factory.h"
18 #include "chrome/test/chromedriver/status.h"
19 #include "googleurl/src/gurl.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace {
23
24 Status CloserFunc() {
25 return Status(kOk);
26 }
27
28 class MockSyncWebSocket : public SyncWebSocket {
29 public:
30 MockSyncWebSocket() : connected_(false), id_(-1), queued_messages_(1) {}
31 virtual ~MockSyncWebSocket() {}
32
33 virtual bool IsConnected() OVERRIDE {
34 return connected_;
35 }
36
37 virtual bool Connect(const GURL& url) OVERRIDE {
38 EXPECT_STREQ("http://url/", url.possibly_invalid_spec().c_str());
39 connected_ = true;
40 return true;
41 }
42
43 virtual bool Send(const std::string& message) OVERRIDE {
44 EXPECT_TRUE(connected_);
45 scoped_ptr<base::Value> value(base::JSONReader::Read(message));
46 base::DictionaryValue* dict = NULL;
47 EXPECT_TRUE(value->GetAsDictionary(&dict));
48 if (!dict)
49 return false;
50 EXPECT_TRUE(dict->GetInteger("id", &id_));
51 std::string method;
52 EXPECT_TRUE(dict->GetString("method", &method));
53 EXPECT_STREQ("method", method.c_str());
54 base::DictionaryValue* params = NULL;
55 EXPECT_TRUE(dict->GetDictionary("params", &params));
56 if (!params)
57 return false;
58 int param = -1;
59 EXPECT_TRUE(params->GetInteger("param", &param));
60 EXPECT_EQ(1, param);
61 return true;
62 }
63
64 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
65 base::DictionaryValue response;
66 response.SetInteger("id", id_);
67 base::DictionaryValue result;
68 result.SetInteger("param", 1);
69 response.Set("result", result.DeepCopy());
70 base::JSONWriter::Write(&response, message);
71 --queued_messages_;
72 return true;
73 }
74
75 virtual bool HasNextMessage() OVERRIDE {
76 return queued_messages_ > 0;
77 }
78
79 protected:
80 bool connected_;
81 int id_;
82 int queued_messages_;
83 };
84
85 template <typename T>
86 scoped_ptr<SyncWebSocket> CreateMockSyncWebSocket() {
87 return scoped_ptr<SyncWebSocket>(new T());
88 }
89
90 } // namespace
91
92 TEST(DevToolsClientImpl, SendCommand) {
93 SyncWebSocketFactory factory =
94 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
95 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
96 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
97 base::DictionaryValue params;
98 params.SetInteger("param", 1);
99 ASSERT_EQ(kOk, client.SendCommand("method", params).code());
100 }
101
102 TEST(DevToolsClientImpl, SendCommandAndGetResult) {
103 SyncWebSocketFactory factory =
104 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
105 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
106 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
107 base::DictionaryValue params;
108 params.SetInteger("param", 1);
109 scoped_ptr<base::DictionaryValue> result;
110 Status status = client.SendCommandAndGetResult("method", params, &result);
111 ASSERT_EQ(kOk, status.code());
112 std::string json;
113 base::JSONWriter::Write(result.get(), &json);
114 ASSERT_STREQ("{\"param\":1}", json.c_str());
115 }
116
117 namespace {
118
119 class MockSyncWebSocket2 : public SyncWebSocket {
120 public:
121 MockSyncWebSocket2() {}
122 virtual ~MockSyncWebSocket2() {}
123
124 virtual bool IsConnected() OVERRIDE {
125 return false;
126 }
127
128 virtual bool Connect(const GURL& url) OVERRIDE {
129 return false;
130 }
131
132 virtual bool Send(const std::string& message) OVERRIDE {
133 EXPECT_TRUE(false);
134 return false;
135 }
136
137 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
138 EXPECT_TRUE(false);
139 return false;
140 }
141
142 virtual bool HasNextMessage() OVERRIDE {
143 return true;
144 }
145 };
146
147 } // namespace
148
149 TEST(DevToolsClientImpl, ConnectIfNecessaryConnectFails) {
150 SyncWebSocketFactory factory =
151 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket2>);
152 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
153 ASSERT_EQ(kDisconnected, client.ConnectIfNecessary().code());
154 }
155
156 namespace {
157
158 class MockSyncWebSocket3 : public SyncWebSocket {
159 public:
160 MockSyncWebSocket3() : connected_(false) {}
161 virtual ~MockSyncWebSocket3() {}
162
163 virtual bool IsConnected() OVERRIDE {
164 return connected_;
165 }
166
167 virtual bool Connect(const GURL& url) OVERRIDE {
168 connected_ = true;
169 return true;
170 }
171
172 virtual bool Send(const std::string& message) OVERRIDE {
173 return false;
174 }
175
176 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
177 EXPECT_TRUE(false);
178 return false;
179 }
180
181 virtual bool HasNextMessage() OVERRIDE {
182 return true;
183 }
184
185 private:
186 bool connected_;
187 };
188
189 } // namespace
190
191 TEST(DevToolsClientImpl, SendCommandSendFails) {
192 SyncWebSocketFactory factory =
193 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket3>);
194 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
195 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
196 base::DictionaryValue params;
197 ASSERT_TRUE(client.SendCommand("method", params).IsError());
198 }
199
200 namespace {
201
202 class MockSyncWebSocket4 : public SyncWebSocket {
203 public:
204 MockSyncWebSocket4() : connected_(false) {}
205 virtual ~MockSyncWebSocket4() {}
206
207 virtual bool IsConnected() OVERRIDE {
208 return connected_;
209 }
210
211 virtual bool Connect(const GURL& url) OVERRIDE {
212 connected_ = true;
213 return true;
214 }
215
216 virtual bool Send(const std::string& message) OVERRIDE {
217 return true;
218 }
219
220 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
221 return false;
222 }
223
224 virtual bool HasNextMessage() OVERRIDE {
225 return true;
226 }
227
228 private:
229 bool connected_;
230 };
231
232 } // namespace
233
234 TEST(DevToolsClientImpl, SendCommandReceiveNextMessageFails) {
235 SyncWebSocketFactory factory =
236 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket4>);
237 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
238 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
239 base::DictionaryValue params;
240 ASSERT_TRUE(client.SendCommand("method", params).IsError());
241 }
242
243 namespace {
244
245 class FakeSyncWebSocket : public SyncWebSocket {
246 public:
247 FakeSyncWebSocket() : connected_(false) {}
248 virtual ~FakeSyncWebSocket() {}
249
250 virtual bool IsConnected() OVERRIDE {
251 return connected_;
252 }
253
254 virtual bool Connect(const GURL& url) OVERRIDE {
255 EXPECT_FALSE(connected_);
256 connected_ = true;
257 return true;
258 }
259
260 virtual bool Send(const std::string& message) OVERRIDE {
261 return true;
262 }
263
264 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
265 return true;
266 }
267
268 virtual bool HasNextMessage() OVERRIDE {
269 return true;
270 }
271
272 private:
273 bool connected_;
274 };
275
276 bool ReturnCommand(
277 const std::string& message,
278 int expected_id,
279 internal::InspectorMessageType* type,
280 internal::InspectorEvent* event,
281 internal::InspectorCommandResponse* command_response) {
282 *type = internal::kCommandResponseMessageType;
283 command_response->id = expected_id;
284 command_response->result.reset(new base::DictionaryValue());
285 return true;
286 }
287
288 bool ReturnBadResponse(
289 const std::string& message,
290 int expected_id,
291 internal::InspectorMessageType* type,
292 internal::InspectorEvent* event,
293 internal::InspectorCommandResponse* command_response) {
294 *type = internal::kCommandResponseMessageType;
295 command_response->id = expected_id;
296 command_response->result.reset(new base::DictionaryValue());
297 return false;
298 }
299
300 bool ReturnCommandBadId(
301 const std::string& message,
302 int expected_id,
303 internal::InspectorMessageType* type,
304 internal::InspectorEvent* event,
305 internal::InspectorCommandResponse* command_response) {
306 *type = internal::kCommandResponseMessageType;
307 command_response->id = expected_id + 100;
308 command_response->result.reset(new base::DictionaryValue());
309 return true;
310 }
311
312 bool ReturnCommandError(
313 const std::string& message,
314 int expected_id,
315 internal::InspectorMessageType* type,
316 internal::InspectorEvent* event,
317 internal::InspectorCommandResponse* command_response) {
318 *type = internal::kCommandResponseMessageType;
319 command_response->id = expected_id;
320 command_response->error = "err";
321 return true;
322 }
323
324 class MockListener : public DevToolsEventListener {
325 public:
326 MockListener() : called_(false) {}
327 virtual ~MockListener() {
328 EXPECT_TRUE(called_);
329 }
330
331 virtual Status OnConnected() OVERRIDE {
332 return Status(kOk);
333 }
334
335 virtual void OnEvent(const std::string& method,
336 const base::DictionaryValue& params) OVERRIDE {
337 called_ = true;
338 EXPECT_STREQ("method", method.c_str());
339 EXPECT_TRUE(params.HasKey("key"));
340 }
341
342 private:
343 bool called_;
344 };
345
346 bool ReturnEventThenResponse(
347 bool* first,
348 const std::string& message,
349 int expected_id,
350 internal::InspectorMessageType* type,
351 internal::InspectorEvent* event,
352 internal::InspectorCommandResponse* command_response) {
353 if (*first) {
354 *type = internal::kEventMessageType;
355 event->method = "method";
356 event->params.reset(new base::DictionaryValue());
357 event->params->SetInteger("key", 1);
358 } else {
359 *type = internal::kCommandResponseMessageType;
360 command_response->id = expected_id;
361 base::DictionaryValue params;
362 command_response->result.reset(new base::DictionaryValue());
363 command_response->result->SetInteger("key", 2);
364 }
365 *first = false;
366 return true;
367 }
368
369 bool ReturnEvent(
370 const std::string& message,
371 int expected_id,
372 internal::InspectorMessageType* type,
373 internal::InspectorEvent* event,
374 internal::InspectorCommandResponse* command_response) {
375 *type = internal::kEventMessageType;
376 event->method = "method";
377 event->params.reset(new base::DictionaryValue());
378 event->params->SetInteger("key", 1);
379 return true;
380 }
381
382 bool ReturnOutOfOrderResponses(
383 int* recurse_count,
384 DevToolsClient* client,
385 const std::string& message,
386 int expected_id,
387 internal::InspectorMessageType* type,
388 internal::InspectorEvent* event,
389 internal::InspectorCommandResponse* command_response) {
390 int key = 0;
391 base::DictionaryValue params;
392 params.SetInteger("param", 1);
393 switch ((*recurse_count)++) {
394 case 0:
395 client->SendCommand("method", params);
396 *type = internal::kEventMessageType;
397 event->method = "method";
398 event->params.reset(new base::DictionaryValue());
399 event->params->SetInteger("key", 1);
400 return true;
401 case 1:
402 command_response->id = expected_id - 1;
403 key = 2;
404 break;
405 case 2:
406 command_response->id = expected_id;
407 key = 3;
408 break;
409 }
410 *type = internal::kCommandResponseMessageType;
411 command_response->result.reset(new base::DictionaryValue());
412 command_response->result->SetInteger("key", key);
413 return true;
414 }
415
416 bool ReturnError(
417 const std::string& message,
418 int expected_id,
419 internal::InspectorMessageType* type,
420 internal::InspectorEvent* event,
421 internal::InspectorCommandResponse* command_response) {
422 return false;
423 }
424
425 Status AlwaysTrue(bool* is_met) {
426 *is_met = true;
427 return Status(kOk);
428 }
429
430 Status AlwaysError(bool* is_met) {
431 return Status(kUnknownError);
432 }
433
434 } // namespace
435
436 TEST(DevToolsClientImpl, SendCommandOnlyConnectsOnce) {
437 SyncWebSocketFactory factory =
438 base::Bind(&CreateMockSyncWebSocket<FakeSyncWebSocket>);
439 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
440 base::Bind(&ReturnCommand));
441 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
442 base::DictionaryValue params;
443 ASSERT_TRUE(client.SendCommand("method", params).IsOk());
444 ASSERT_TRUE(client.SendCommand("method", params).IsOk());
445 }
446
447 TEST(DevToolsClientImpl, SendCommandBadResponse) {
448 SyncWebSocketFactory factory =
449 base::Bind(&CreateMockSyncWebSocket<FakeSyncWebSocket>);
450 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
451 base::Bind(&ReturnBadResponse));
452 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
453 base::DictionaryValue params;
454 ASSERT_TRUE(client.SendCommand("method", params).IsError());
455 }
456
457 TEST(DevToolsClientImpl, SendCommandBadId) {
458 SyncWebSocketFactory factory =
459 base::Bind(&CreateMockSyncWebSocket<FakeSyncWebSocket>);
460 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
461 base::Bind(&ReturnCommandBadId));
462 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
463 base::DictionaryValue params;
464 ASSERT_TRUE(client.SendCommand("method", params).IsError());
465 }
466
467 TEST(DevToolsClientImpl, SendCommandResponseError) {
468 SyncWebSocketFactory factory =
469 base::Bind(&CreateMockSyncWebSocket<FakeSyncWebSocket>);
470 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
471 base::Bind(&ReturnCommandError));
472 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
473 base::DictionaryValue params;
474 ASSERT_TRUE(client.SendCommand("method", params).IsError());
475 }
476
477 TEST(DevToolsClientImpl, SendCommandEventBeforeResponse) {
478 SyncWebSocketFactory factory =
479 base::Bind(&CreateMockSyncWebSocket<FakeSyncWebSocket>);
480 MockListener listener;
481 bool first = true;
482 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
483 base::Bind(&ReturnEventThenResponse, &first));
484 client.AddListener(&listener);
485 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
486 base::DictionaryValue params;
487 scoped_ptr<base::DictionaryValue> result;
488 ASSERT_TRUE(client.SendCommandAndGetResult("method", params, &result).IsOk());
489 ASSERT_TRUE(result);
490 int key;
491 ASSERT_TRUE(result->GetInteger("key", &key));
492 ASSERT_EQ(2, key);
493 }
494
495 TEST(ParseInspectorMessage, NonJson) {
496 internal::InspectorMessageType type;
497 internal::InspectorEvent event;
498 internal::InspectorCommandResponse response;
499 ASSERT_FALSE(internal::ParseInspectorMessage(
500 "hi", 0, &type, &event, &response));
501 }
502
503 TEST(ParseInspectorMessage, NeitherCommandNorEvent) {
504 internal::InspectorMessageType type;
505 internal::InspectorEvent event;
506 internal::InspectorCommandResponse response;
507 ASSERT_FALSE(internal::ParseInspectorMessage(
508 "{}", 0, &type, &event, &response));
509 }
510
511 TEST(ParseInspectorMessage, EventNoParams) {
512 internal::InspectorMessageType type;
513 internal::InspectorEvent event;
514 internal::InspectorCommandResponse response;
515 ASSERT_TRUE(internal::ParseInspectorMessage(
516 "{\"method\":\"method\"}", 0, &type, &event, &response));
517 ASSERT_EQ(internal::kEventMessageType, type);
518 ASSERT_STREQ("method", event.method.c_str());
519 ASSERT_TRUE(event.params->IsType(base::Value::TYPE_DICTIONARY));
520 }
521
522 TEST(ParseInspectorMessage, EventWithParams) {
523 internal::InspectorMessageType type;
524 internal::InspectorEvent event;
525 internal::InspectorCommandResponse response;
526 ASSERT_TRUE(internal::ParseInspectorMessage(
527 "{\"method\":\"method\",\"params\":{\"key\":100}}",
528 0, &type, &event, &response));
529 ASSERT_EQ(internal::kEventMessageType, type);
530 ASSERT_STREQ("method", event.method.c_str());
531 int key;
532 ASSERT_TRUE(event.params->GetInteger("key", &key));
533 ASSERT_EQ(100, key);
534 }
535
536 TEST(ParseInspectorMessage, CommandNoErrorOrResult) {
537 internal::InspectorMessageType type;
538 internal::InspectorEvent event;
539 internal::InspectorCommandResponse response;
540 ASSERT_FALSE(internal::ParseInspectorMessage(
541 "{\"id\":1}", 0, &type, &event, &response));
542 }
543
544 TEST(ParseInspectorMessage, CommandError) {
545 internal::InspectorMessageType type;
546 internal::InspectorEvent event;
547 internal::InspectorCommandResponse response;
548 ASSERT_TRUE(internal::ParseInspectorMessage(
549 "{\"id\":1,\"error\":{}}", 0, &type, &event, &response));
550 ASSERT_EQ(internal::kCommandResponseMessageType, type);
551 ASSERT_EQ(1, response.id);
552 ASSERT_TRUE(response.error.length());
553 ASSERT_FALSE(response.result);
554 }
555
556 TEST(ParseInspectorMessage, Command) {
557 internal::InspectorMessageType type;
558 internal::InspectorEvent event;
559 internal::InspectorCommandResponse response;
560 ASSERT_TRUE(internal::ParseInspectorMessage(
561 "{\"id\":1,\"result\":{\"key\":1}}", 0, &type, &event, &response));
562 ASSERT_EQ(internal::kCommandResponseMessageType, type);
563 ASSERT_EQ(1, response.id);
564 ASSERT_FALSE(response.error.length());
565 int key;
566 ASSERT_TRUE(response.result->GetInteger("key", &key));
567 ASSERT_EQ(1, key);
568 }
569
570 TEST(DevToolsClientImpl, HandleEventsUntil) {
571 MockListener listener;
572 SyncWebSocketFactory factory =
573 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
574 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
575 base::Bind(&ReturnEvent));
576 client.AddListener(&listener);
577 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
578 Status status = client.HandleEventsUntil(base::Bind(&AlwaysTrue));
579 ASSERT_EQ(kOk, status.code());
580 }
581
582 TEST(DevToolsClientImpl, WaitForNextEventCommand) {
583 SyncWebSocketFactory factory =
584 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
585 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
586 base::Bind(&ReturnCommand));
587 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
588 Status status = client.HandleEventsUntil(base::Bind(&AlwaysTrue));
589 ASSERT_EQ(kUnknownError, status.code());
590 }
591
592 TEST(DevToolsClientImpl, WaitForNextEventError) {
593 SyncWebSocketFactory factory =
594 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
595 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
596 base::Bind(&ReturnError));
597 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
598 Status status = client.HandleEventsUntil(base::Bind(&AlwaysTrue));
599 ASSERT_EQ(kUnknownError, status.code());
600 }
601
602 TEST(DevToolsClientImpl, WaitForNextEventConditionalFuncReturnsError) {
603 SyncWebSocketFactory factory =
604 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
605 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc),
606 base::Bind(&ReturnEvent));
607 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
608 Status status = client.HandleEventsUntil(base::Bind(&AlwaysError));
609 ASSERT_EQ(kUnknownError, status.code());
610 }
611
612 TEST(DevToolsClientImpl, NestedCommandsWithOutOfOrderResults) {
613 SyncWebSocketFactory factory =
614 base::Bind(&CreateMockSyncWebSocket<MockSyncWebSocket>);
615 int recurse_count = 0;
616 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
617 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
618 client.SetParserFuncForTesting(
619 base::Bind(&ReturnOutOfOrderResponses, &recurse_count, &client));
620 base::DictionaryValue params;
621 params.SetInteger("param", 1);
622 scoped_ptr<base::DictionaryValue> result;
623 ASSERT_TRUE(client.SendCommandAndGetResult("method", params, &result).IsOk());
624 ASSERT_TRUE(result);
625 int key;
626 ASSERT_TRUE(result->GetInteger("key", &key));
627 ASSERT_EQ(2, key);
628 }
629
630 namespace {
631
632 class OnConnectedListener : public DevToolsEventListener {
633 public:
634 OnConnectedListener(const std::string& method, DevToolsClient* client)
635 : method_(method),
636 client_(client),
637 on_connected_called_(false),
638 on_event_called_(false) {
639 client_->AddListener(this);
640 }
641 virtual ~OnConnectedListener() {}
642
643 void VerifyCalled() {
644 EXPECT_TRUE(on_connected_called_);
645 EXPECT_TRUE(on_event_called_);
646 }
647
648 virtual Status OnConnected() OVERRIDE {
649 EXPECT_FALSE(on_connected_called_);
650 EXPECT_FALSE(on_event_called_);
651 on_connected_called_ = true;
652 base::DictionaryValue params;
653 return client_->SendCommand(method_, params);
654 }
655
656 virtual void OnEvent(const std::string& method,
657 const base::DictionaryValue& params) OVERRIDE {
658 EXPECT_TRUE(on_connected_called_);
659 on_event_called_ = true;
660 }
661
662 private:
663 std::string method_;
664 DevToolsClient* client_;
665 bool on_connected_called_;
666 bool on_event_called_;
667 };
668
669 class OnConnectedSyncWebSocket : public SyncWebSocket {
670 public:
671 OnConnectedSyncWebSocket() : connected_(false) {}
672 virtual ~OnConnectedSyncWebSocket() {}
673
674 virtual bool IsConnected() OVERRIDE {
675 return connected_;
676 }
677
678 virtual bool Connect(const GURL& url) OVERRIDE {
679 connected_ = true;
680 return true;
681 }
682
683 virtual bool Send(const std::string& message) OVERRIDE {
684 EXPECT_TRUE(connected_);
685 scoped_ptr<base::Value> value(base::JSONReader::Read(message));
686 base::DictionaryValue* dict = NULL;
687 EXPECT_TRUE(value->GetAsDictionary(&dict));
688 if (!dict)
689 return false;
690 int id;
691 EXPECT_TRUE(dict->GetInteger("id", &id));
692 std::string method;
693 EXPECT_TRUE(dict->GetString("method", &method));
694
695 base::DictionaryValue response;
696 response.SetInteger("id", id);
697 response.Set("result", new base::DictionaryValue());
698 std::string json_response;
699 base::JSONWriter::Write(&response, &json_response);
700 queued_response_.push_back(json_response);
701
702 // Push one event.
703 base::DictionaryValue event;
704 event.SetString("method", "updateEvent");
705 event.Set("params", new base::DictionaryValue());
706 std::string json_event;
707 base::JSONWriter::Write(&event, &json_event);
708 queued_response_.push_back(json_event);
709
710 return true;
711 }
712
713 virtual bool ReceiveNextMessage(std::string* message) OVERRIDE {
714 if (queued_response_.empty())
715 return false;
716 *message = queued_response_.front();
717 queued_response_.pop_front();
718 return true;
719 }
720
721 virtual bool HasNextMessage() OVERRIDE {
722 return !queued_response_.empty();
723 }
724
725 private:
726 bool connected_;
727 std::list<std::string> queued_response_;
728 };
729
730 } // namespace
731
732 TEST(DevToolsClientImpl, ProcessOnConnectedFirstOnCommand) {
733 SyncWebSocketFactory factory =
734 base::Bind(&CreateMockSyncWebSocket<OnConnectedSyncWebSocket>);
735 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
736 OnConnectedListener listener1("DOM.getDocument", &client);
737 OnConnectedListener listener2("Runtime.enable", &client);
738 OnConnectedListener listener3("Page.enable", &client);
739 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
740 base::DictionaryValue params;
741 EXPECT_EQ(kOk, client.SendCommand("Runtime.execute", params).code());
742 listener1.VerifyCalled();
743 listener2.VerifyCalled();
744 listener3.VerifyCalled();
745 }
746
747 TEST(DevToolsClientImpl, ProcessOnConnectedFirstOnHandleEventsUntil) {
748 SyncWebSocketFactory factory =
749 base::Bind(&CreateMockSyncWebSocket<OnConnectedSyncWebSocket>);
750 DevToolsClientImpl client(factory, "http://url", base::Bind(&CloserFunc));
751 OnConnectedListener listener1("DOM.getDocument", &client);
752 OnConnectedListener listener2("Runtime.enable", &client);
753 OnConnectedListener listener3("Page.enable", &client);
754 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
755 EXPECT_EQ(kOk, client.HandleReceivedEvents().code());
756 listener1.VerifyCalled();
757 listener2.VerifyCalled();
758 listener3.VerifyCalled();
759 }
760
761 namespace {
762
763 class DisconnectedSyncWebSocket : public MockSyncWebSocket {
764 public:
765 DisconnectedSyncWebSocket() : connection_count_(0), command_count_(0) {}
766 virtual ~DisconnectedSyncWebSocket() {}
767
768 virtual bool Connect(const GURL& url) OVERRIDE {
769 connection_count_++;
770 connected_ = connection_count_ != 2;
771 return connected_;
772 }
773
774 virtual bool Send(const std::string& message) OVERRIDE {
775 command_count_++;
776 if (command_count_ == 1) {
777 connected_ = false;
778 return false;
779 }
780 return MockSyncWebSocket::Send(message);
781 }
782
783 private:
784 int connection_count_;
785 int command_count_;
786 };
787
788 Status CheckCloserFuncCalled(bool* is_called) {
789 *is_called = true;
790 return Status(kOk);
791 }
792
793 } // namespace
794
795 TEST(DevToolsClientImpl, Reconnect) {
796 SyncWebSocketFactory factory =
797 base::Bind(&CreateMockSyncWebSocket<DisconnectedSyncWebSocket>);
798 bool is_called = false;
799 DevToolsClientImpl client(factory, "http://url",
800 base::Bind(&CheckCloserFuncCalled, &is_called));
801 ASSERT_FALSE(is_called);
802 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
803 ASSERT_FALSE(is_called);
804 base::DictionaryValue params;
805 params.SetInteger("param", 1);
806 is_called = false;
807 ASSERT_EQ(kDisconnected, client.SendCommand("method", params).code());
808 ASSERT_FALSE(is_called);
809 ASSERT_EQ(kDisconnected, client.HandleReceivedEvents().code());
810 ASSERT_FALSE(is_called);
811 ASSERT_EQ(kOk, client.ConnectIfNecessary().code());
812 ASSERT_TRUE(is_called);
813 is_called = false;
814 ASSERT_EQ(kOk, client.SendCommand("method", params).code());
815 ASSERT_FALSE(is_called);
816 }
OLDNEW
« no previous file with comments | « chrome/test/chromedriver/devtools_client_impl.cc ('k') | chrome/test/chromedriver/devtools_event_listener.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698