OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/webdriver/webdriver_session.h" | 5 #include "chrome/test/webdriver/webdriver_session.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "chrome/test/automation/automation_json_requests.h" | 36 #include "chrome/test/automation/automation_json_requests.h" |
37 #include "chrome/test/automation/value_conversion_util.h" | 37 #include "chrome/test/automation/value_conversion_util.h" |
38 #include "chrome/test/webdriver/webdriver_error.h" | 38 #include "chrome/test/webdriver/webdriver_error.h" |
39 #include "chrome/test/webdriver/webdriver_key_converter.h" | 39 #include "chrome/test/webdriver/webdriver_key_converter.h" |
40 #include "chrome/test/webdriver/webdriver_session_manager.h" | 40 #include "chrome/test/webdriver/webdriver_session_manager.h" |
41 #include "chrome/test/webdriver/webdriver_util.h" | 41 #include "chrome/test/webdriver/webdriver_util.h" |
42 #include "third_party/webdriver/atoms.h" | 42 #include "third_party/webdriver/atoms.h" |
43 | 43 |
44 namespace webdriver { | 44 namespace webdriver { |
45 | 45 |
46 FrameId::FrameId(int window_id, const FramePath& frame_path) | 46 FrameId::FrameId() {} |
47 : window_id(window_id), | 47 |
| 48 FrameId::FrameId(const WebViewId& view_id, const FramePath& frame_path) |
| 49 : view_id(view_id), |
48 frame_path(frame_path) { | 50 frame_path(frame_path) { |
49 } | 51 } |
50 | 52 |
51 FrameId& FrameId::operator=(const FrameId& other) { | |
52 window_id = other.window_id; | |
53 frame_path = other.frame_path; | |
54 return *this; | |
55 } | |
56 | |
57 Session::Options::Options() | 53 Session::Options::Options() |
58 : use_native_events(false), | 54 : use_native_events(false), |
59 load_async(false) { | 55 load_async(false) { |
60 } | 56 } |
61 | 57 |
62 Session::Options::~Options() { | 58 Session::Options::~Options() { |
63 } | 59 } |
64 | 60 |
65 Session::Session(const Options& options) | 61 Session::Session(const Options& options) |
66 : id_(GenerateRandomID()), | 62 : id_(GenerateRandomID()), |
67 current_target_(FrameId(0, FramePath())), | 63 current_target_(FrameId(WebViewId(), FramePath())), |
68 thread_(id_.c_str()), | 64 thread_(id_.c_str()), |
69 async_script_timeout_(0), | 65 async_script_timeout_(0), |
70 implicit_wait_(0), | 66 implicit_wait_(0), |
71 has_alert_prompt_text_(false), | 67 has_alert_prompt_text_(false), |
72 options_(options) { | 68 options_(options) { |
73 SessionManager::GetInstance()->Add(this); | 69 SessionManager::GetInstance()->Add(this); |
74 } | 70 } |
75 | 71 |
76 Session::~Session() { | 72 Session::~Session() { |
77 SessionManager::GetInstance()->Remove(id_); | 73 SessionManager::GetInstance()->Remove(id_); |
(...skipping 30 matching lines...) Expand all Loading... |
108 } | 104 } |
109 } | 105 } |
110 } | 106 } |
111 return error; | 107 return error; |
112 } | 108 } |
113 | 109 |
114 Error* Session::AfterExecuteCommand() { | 110 Error* Session::AfterExecuteCommand() { |
115 Error* error = NULL; | 111 Error* error = NULL; |
116 if (!options_.load_async) { | 112 if (!options_.load_async) { |
117 LOG(INFO) << "Waiting for the page to stop loading"; | 113 LOG(INFO) << "Waiting for the page to stop loading"; |
118 error = WaitForAllTabsToStopLoading(); | 114 error = WaitForAllViewsToStopLoading(); |
119 LOG(INFO) << "Done waiting for the page to stop loading"; | 115 LOG(INFO) << "Done waiting for the page to stop loading"; |
120 } | 116 } |
121 return error; | 117 return error; |
122 } | 118 } |
123 | 119 |
124 void Session::Terminate() { | 120 void Session::Terminate() { |
125 RunSessionTask(NewRunnableMethod( | 121 RunSessionTask(NewRunnableMethod( |
126 this, | 122 this, |
127 &Session::TerminateOnSessionThread)); | 123 &Session::TerminateOnSessionThread)); |
128 delete this; | 124 delete this; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 return error; | 266 return error; |
271 } | 267 } |
272 | 268 |
273 Error* Session::DragAndDropFilePaths( | 269 Error* Session::DragAndDropFilePaths( |
274 const Point& location, | 270 const Point& location, |
275 const std::vector<FilePath::StringType>& paths) { | 271 const std::vector<FilePath::StringType>& paths) { |
276 Error* error = NULL; | 272 Error* error = NULL; |
277 RunSessionTask(NewRunnableMethod( | 273 RunSessionTask(NewRunnableMethod( |
278 automation_.get(), | 274 automation_.get(), |
279 &Automation::DragAndDropFilePaths, | 275 &Automation::DragAndDropFilePaths, |
280 current_target_.window_id, | 276 current_target_.view_id, |
281 location, | 277 location, |
282 paths, | 278 paths, |
283 &error)); | 279 &error)); |
284 return error; | 280 return error; |
285 } | 281 } |
286 | 282 |
287 Error* Session::NavigateToURL(const std::string& url) { | 283 Error* Session::NavigateToURL(const std::string& url) { |
| 284 if (!current_target_.view_id.IsTab()) { |
| 285 return new Error(kUnknownError, |
| 286 "The current target does not support navigation"); |
| 287 } |
288 Error* error = NULL; | 288 Error* error = NULL; |
289 if (options_.load_async) { | 289 if (options_.load_async) { |
290 RunSessionTask(NewRunnableMethod( | 290 RunSessionTask(NewRunnableMethod( |
291 automation_.get(), | 291 automation_.get(), |
292 &Automation::NavigateToURLAsync, | 292 &Automation::NavigateToURLAsync, |
293 current_target_.window_id, | 293 current_target_.view_id, |
294 url, | 294 url, |
295 &error)); | 295 &error)); |
296 } else { | 296 } else { |
297 RunSessionTask(NewRunnableMethod( | 297 RunSessionTask(NewRunnableMethod( |
298 automation_.get(), | 298 automation_.get(), |
299 &Automation::NavigateToURL, | 299 &Automation::NavigateToURL, |
300 current_target_.window_id, | 300 current_target_.view_id, |
301 url, | 301 url, |
302 &error)); | 302 &error)); |
303 } | 303 } |
304 return error; | 304 return error; |
305 } | 305 } |
306 | 306 |
307 Error* Session::GoForward() { | 307 Error* Session::GoForward() { |
| 308 if (!current_target_.view_id.IsTab()) { |
| 309 return new Error(kUnknownError, |
| 310 "The current target does not support navigation"); |
| 311 } |
308 Error* error = NULL; | 312 Error* error = NULL; |
309 RunSessionTask(NewRunnableMethod( | 313 RunSessionTask(NewRunnableMethod( |
310 automation_.get(), | 314 automation_.get(), |
311 &Automation::GoForward, | 315 &Automation::GoForward, |
312 current_target_.window_id, | 316 current_target_.view_id, |
313 &error)); | 317 &error)); |
314 return error; | 318 return error; |
315 } | 319 } |
316 | 320 |
317 Error* Session::GoBack() { | 321 Error* Session::GoBack() { |
| 322 if (!current_target_.view_id.IsTab()) { |
| 323 return new Error(kUnknownError, |
| 324 "The current target does not support navigation"); |
| 325 } |
318 Error* error = NULL; | 326 Error* error = NULL; |
319 RunSessionTask(NewRunnableMethod( | 327 RunSessionTask(NewRunnableMethod( |
320 automation_.get(), | 328 automation_.get(), |
321 &Automation::GoBack, | 329 &Automation::GoBack, |
322 current_target_.window_id, | 330 current_target_.view_id, |
323 &error)); | 331 &error)); |
324 return error; | 332 return error; |
325 } | 333 } |
326 | 334 |
327 Error* Session::Reload() { | 335 Error* Session::Reload() { |
| 336 if (!current_target_.view_id.IsTab()) { |
| 337 return new Error(kUnknownError, |
| 338 "The current target does not support navigation"); |
| 339 } |
328 Error* error = NULL; | 340 Error* error = NULL; |
329 RunSessionTask(NewRunnableMethod( | 341 RunSessionTask(NewRunnableMethod( |
330 automation_.get(), | 342 automation_.get(), |
331 &Automation::Reload, | 343 &Automation::Reload, |
332 current_target_.window_id, | 344 current_target_.view_id, |
333 &error)); | 345 &error)); |
334 return error; | 346 return error; |
335 } | 347 } |
336 | 348 |
337 Error* Session::GetURL(std::string* url) { | 349 Error* Session::GetURL(std::string* url) { |
338 return ExecuteScriptAndParse(current_target_, | 350 return ExecuteScriptAndParse(current_target_, |
339 "function() { return document.URL }", | 351 "function() { return document.URL }", |
340 "getUrl", | 352 "getUrl", |
341 new ListValue(), | 353 new ListValue(), |
342 CreateDirectValueParser(url)); | 354 CreateDirectValueParser(url)); |
343 } | 355 } |
344 | 356 |
345 Error* Session::GetTitle(std::string* tab_title) { | 357 Error* Session::GetTitle(std::string* tab_title) { |
346 const char* kGetTitleScript = | 358 const char* kGetTitleScript = |
347 "function() {" | 359 "function() {" |
348 " if (document.title)" | 360 " if (document.title)" |
349 " return document.title;" | 361 " return document.title;" |
350 " else" | 362 " else" |
351 " return document.URL;" | 363 " return document.URL;" |
352 "}"; | 364 "}"; |
353 return ExecuteScriptAndParse(FrameId(current_target_.window_id, FramePath()), | 365 return ExecuteScriptAndParse(FrameId(current_target_.view_id, FramePath()), |
354 kGetTitleScript, | 366 kGetTitleScript, |
355 "getTitle", | 367 "getTitle", |
356 new ListValue(), | 368 new ListValue(), |
357 CreateDirectValueParser(tab_title)); | 369 CreateDirectValueParser(tab_title)); |
358 } | 370 } |
359 | 371 |
360 Error* Session::MouseMoveAndClick(const Point& location, | 372 Error* Session::MouseMoveAndClick(const Point& location, |
361 automation::MouseButton button) { | 373 automation::MouseButton button) { |
362 Error* error = NULL; | 374 Error* error = NULL; |
363 RunSessionTask(NewRunnableMethod( | 375 RunSessionTask(NewRunnableMethod( |
364 automation_.get(), | 376 automation_.get(), |
365 &Automation::MouseClick, | 377 &Automation::MouseClick, |
366 current_target_.window_id, | 378 current_target_.view_id, |
367 location, | 379 location, |
368 button, | 380 button, |
369 &error)); | 381 &error)); |
370 if (!error) | 382 if (!error) |
371 mouse_position_ = location; | 383 mouse_position_ = location; |
372 return error; | 384 return error; |
373 } | 385 } |
374 | 386 |
375 Error* Session::MouseMove(const Point& location) { | 387 Error* Session::MouseMove(const Point& location) { |
376 Error* error = NULL; | 388 Error* error = NULL; |
377 RunSessionTask(NewRunnableMethod( | 389 RunSessionTask(NewRunnableMethod( |
378 automation_.get(), | 390 automation_.get(), |
379 &Automation::MouseMove, | 391 &Automation::MouseMove, |
380 current_target_.window_id, | 392 current_target_.view_id, |
381 location, | 393 location, |
382 &error)); | 394 &error)); |
383 if (!error) | 395 if (!error) |
384 mouse_position_ = location; | 396 mouse_position_ = location; |
385 return error; | 397 return error; |
386 } | 398 } |
387 | 399 |
388 Error* Session::MouseDrag(const Point& start, | 400 Error* Session::MouseDrag(const Point& start, |
389 const Point& end) { | 401 const Point& end) { |
390 Error* error = NULL; | 402 Error* error = NULL; |
391 RunSessionTask(NewRunnableMethod( | 403 RunSessionTask(NewRunnableMethod( |
392 automation_.get(), | 404 automation_.get(), |
393 &Automation::MouseDrag, | 405 &Automation::MouseDrag, |
394 current_target_.window_id, | 406 current_target_.view_id, |
395 start, | 407 start, |
396 end, | 408 end, |
397 &error)); | 409 &error)); |
398 if (!error) | 410 if (!error) |
399 mouse_position_ = end; | 411 mouse_position_ = end; |
400 return error; | 412 return error; |
401 } | 413 } |
402 | 414 |
403 Error* Session::MouseClick(automation::MouseButton button) { | 415 Error* Session::MouseClick(automation::MouseButton button) { |
404 return MouseMoveAndClick(mouse_position_, button); | 416 return MouseMoveAndClick(mouse_position_, button); |
405 } | 417 } |
406 | 418 |
407 Error* Session::MouseButtonDown() { | 419 Error* Session::MouseButtonDown() { |
408 Error* error = NULL; | 420 Error* error = NULL; |
409 RunSessionTask(NewRunnableMethod( | 421 RunSessionTask(NewRunnableMethod( |
410 automation_.get(), | 422 automation_.get(), |
411 &Automation::MouseButtonDown, | 423 &Automation::MouseButtonDown, |
412 current_target_.window_id, | 424 current_target_.view_id, |
413 mouse_position_, | 425 mouse_position_, |
414 &error)); | 426 &error)); |
415 return error; | 427 return error; |
416 } | 428 } |
417 | 429 |
418 Error* Session::MouseButtonUp() { | 430 Error* Session::MouseButtonUp() { |
419 Error* error = NULL; | 431 Error* error = NULL; |
420 RunSessionTask(NewRunnableMethod( | 432 RunSessionTask(NewRunnableMethod( |
421 automation_.get(), | 433 automation_.get(), |
422 &Automation::MouseButtonUp, | 434 &Automation::MouseButtonUp, |
423 current_target_.window_id, | 435 current_target_.view_id, |
424 mouse_position_, | 436 mouse_position_, |
425 &error)); | 437 &error)); |
426 return error; | 438 return error; |
427 } | 439 } |
428 | 440 |
429 Error* Session::MouseDoubleClick() { | 441 Error* Session::MouseDoubleClick() { |
430 Error* error = NULL; | 442 Error* error = NULL; |
431 RunSessionTask(NewRunnableMethod( | 443 RunSessionTask(NewRunnableMethod( |
432 automation_.get(), | 444 automation_.get(), |
433 &Automation::MouseDoubleClick, | 445 &Automation::MouseDoubleClick, |
434 current_target_.window_id, | 446 current_target_.view_id, |
435 mouse_position_, | 447 mouse_position_, |
436 &error)); | 448 &error)); |
437 return error; | 449 return error; |
438 } | 450 } |
439 | 451 |
440 Error* Session::GetCookies(const std::string& url, ListValue** cookies) { | 452 Error* Session::GetCookies(const std::string& url, ListValue** cookies) { |
441 Error* error = NULL; | 453 Error* error = NULL; |
442 RunSessionTask(NewRunnableMethod( | 454 RunSessionTask(NewRunnableMethod( |
443 automation_.get(), | 455 automation_.get(), |
444 &Automation::GetCookies, | 456 &Automation::GetCookies, |
(...skipping 20 matching lines...) Expand all Loading... |
465 Error* error = NULL; | 477 Error* error = NULL; |
466 RunSessionTask(NewRunnableMethod( | 478 RunSessionTask(NewRunnableMethod( |
467 automation_.get(), | 479 automation_.get(), |
468 &Automation::SetCookie, | 480 &Automation::SetCookie, |
469 url, | 481 url, |
470 cookie_dict, | 482 cookie_dict, |
471 &error)); | 483 &error)); |
472 return error; | 484 return error; |
473 } | 485 } |
474 | 486 |
475 Error* Session::GetWindowIds(std::vector<int>* window_ids) { | 487 Error* Session::GetViews(std::vector<WebViewInfo>* views) { |
476 Error* error = NULL; | 488 Error* error = NULL; |
477 RunSessionTask(NewRunnableMethod( | 489 RunSessionTask(NewRunnableMethod( |
478 automation_.get(), | 490 automation_.get(), |
479 &Automation::GetTabIds, | 491 &Automation::GetViews, |
480 window_ids, | 492 views, |
481 &error)); | 493 &error)); |
482 return error; | 494 return error; |
483 } | 495 } |
484 | 496 |
485 Error* Session::SwitchToWindow(const std::string& name) { | 497 Error* Session::SwitchToView(const std::string& id_or_name) { |
486 int switch_to_id = 0; | 498 Error* error = NULL; |
487 int name_no = 0; | 499 bool does_exist = false; |
488 if (base::StringToInt(name, &name_no)) { | 500 |
489 Error* error = NULL; | 501 WebViewId new_view; |
490 bool does_exist = false; | 502 StringToWebViewId(id_or_name, &new_view); |
| 503 if (new_view.IsValid()) { |
491 RunSessionTask(NewRunnableMethod( | 504 RunSessionTask(NewRunnableMethod( |
492 automation_.get(), | 505 automation_.get(), |
493 &Automation::DoesTabExist, | 506 &Automation::DoesViewExist, |
494 name_no, | 507 new_view, |
495 &does_exist, | 508 &does_exist, |
496 &error)); | 509 &error)); |
497 if (error) | 510 if (error) |
498 return error; | 511 return error; |
499 if (does_exist) | |
500 switch_to_id = name_no; | |
501 } | 512 } |
502 | 513 |
503 if (!switch_to_id) { | 514 if (!does_exist) { |
504 std::vector<int> window_ids; | 515 // See if any of the tab window names match |name|. |
505 Error* error = GetWindowIds(&window_ids); | 516 std::vector<WebViewInfo> views; |
| 517 Error* error = GetViews(&views); |
506 if (error) | 518 if (error) |
507 return error; | 519 return error; |
508 // See if any of the window names match |name|. | 520 for (size_t i = 0; i < views.size(); ++i) { |
509 for (size_t i = 0; i < window_ids.size(); ++i) { | 521 if (!views[i].view_id.IsTab()) |
| 522 continue; |
510 std::string window_name; | 523 std::string window_name; |
511 Error* error = ExecuteScriptAndParse( | 524 Error* error = ExecuteScriptAndParse( |
512 FrameId(window_ids[i], FramePath()), | 525 FrameId(views[i].view_id, FramePath()), |
513 "function() { return window.name; }", | 526 "function() { return window.name; }", |
514 "getWindowName", | 527 "getWindowName", |
515 new ListValue(), | 528 new ListValue(), |
516 CreateDirectValueParser(&window_name)); | 529 CreateDirectValueParser(&window_name)); |
517 if (error) | 530 if (error) |
518 return error; | 531 return error; |
519 if (name == window_name) { | 532 if (id_or_name == window_name) { |
520 switch_to_id = window_ids[i]; | 533 new_view = views[i].view_id; |
| 534 does_exist = true; |
521 break; | 535 break; |
522 } | 536 } |
523 } | 537 } |
524 } | 538 } |
525 | 539 |
526 if (!switch_to_id) | 540 if (!does_exist) |
527 return new Error(kNoSuchWindow); | 541 return new Error(kNoSuchWindow); |
528 frame_elements_.clear(); | 542 frame_elements_.clear(); |
529 current_target_ = FrameId(switch_to_id, FramePath()); | 543 current_target_ = FrameId(new_view, FramePath()); |
530 return NULL; | 544 return NULL; |
531 } | 545 } |
532 | 546 |
533 Error* Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) { | 547 Error* Session::SwitchToFrameWithNameOrId(const std::string& name_or_id) { |
534 std::string script = | 548 std::string script = |
535 "function(arg) {" | 549 "function(arg) {" |
536 " var xpath = '(/html/body//iframe|/html/frameset/frame)';" | 550 " var xpath = '(/html/body//iframe|/html/frameset/frame)';" |
537 " var sub = function(s) { return s.replace(/\\$/g, arg); };" | 551 " var sub = function(s) { return s.replace(/\\$/g, arg); };" |
538 " xpath += sub('[@name=\"$\" or @id=\"$\"]');" | 552 " xpath += sub('[@name=\"$\" or @id=\"$\"]');" |
539 " var frame = document.evaluate(xpath, document, null, " | 553 " var frame = document.evaluate(xpath, document, null, " |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 if (frame_elements_.size() != components.size()) { | 618 if (frame_elements_.size() != components.size()) { |
605 return new Error(kUnknownError, | 619 return new Error(kUnknownError, |
606 "Frame element vector out of sync with frame path"); | 620 "Frame element vector out of sync with frame path"); |
607 } | 621 } |
608 FramePath frame_path; | 622 FramePath frame_path; |
609 // Start from the root path and check that each frame element that makes | 623 // Start from the root path and check that each frame element that makes |
610 // up the current frame target is valid by executing an empty script. | 624 // up the current frame target is valid by executing an empty script. |
611 // This code should not execute script in any frame before making sure the | 625 // This code should not execute script in any frame before making sure the |
612 // frame element is valid, otherwise the automation hangs until a timeout. | 626 // frame element is valid, otherwise the automation hangs until a timeout. |
613 for (size_t i = 0; i < frame_elements_.size(); ++i) { | 627 for (size_t i = 0; i < frame_elements_.size(); ++i) { |
614 FrameId frame_id(current_target_.window_id, frame_path); | 628 FrameId frame_id(current_target_.view_id, frame_path); |
615 scoped_ptr<Error> error(ExecuteScriptAndParse( | 629 scoped_ptr<Error> error(ExecuteScriptAndParse( |
616 frame_id, | 630 frame_id, |
617 "function(){ }", | 631 "function(){ }", |
618 "emptyScript", | 632 "emptyScript", |
619 CreateListValueFrom(frame_elements_[i]), | 633 CreateListValueFrom(frame_elements_[i]), |
620 CreateDirectValueParser(kSkipParsing))); | 634 CreateDirectValueParser(kSkipParsing))); |
621 if (error.get() && error->code() == kStaleElementReference) { | 635 if (error.get() && error->code() == kStaleElementReference) { |
622 SwitchToTopFrame(); | 636 SwitchToTopFrame(); |
623 } else if (error.get()) { | 637 } else if (error.get()) { |
624 return error.release(); | 638 return error.release(); |
625 } | 639 } |
626 frame_path = frame_path.Append(components[i]); | 640 frame_path = frame_path.Append(components[i]); |
627 } | 641 } |
628 return NULL; | 642 return NULL; |
629 } | 643 } |
630 | 644 |
631 Error* Session::CloseWindow() { | 645 Error* Session::CloseWindow() { |
632 Error* error = NULL; | 646 Error* error = NULL; |
633 RunSessionTask(NewRunnableMethod( | 647 RunSessionTask(NewRunnableMethod( |
634 automation_.get(), | 648 automation_.get(), |
635 &Automation::CloseTab, | 649 &Automation::CloseView, |
636 current_target_.window_id, | 650 current_target_.view_id, |
637 &error)); | 651 &error)); |
638 | 652 |
639 if (!error) { | 653 if (!error) { |
640 std::vector<int> window_ids; | 654 std::vector<WebViewInfo> views; |
641 scoped_ptr<Error> error(GetWindowIds(&window_ids)); | 655 scoped_ptr<Error> error(GetViews(&views)); |
642 if (error.get() || window_ids.empty()) { | 656 if (error.get() || views.empty()) { |
643 // The automation connection will soon be closed, if not already, | 657 // The automation connection will soon be closed, if not already, |
644 // because we supposedly just closed the last window. Terminate the | 658 // because we supposedly just closed the last window. Terminate the |
645 // session. | 659 // session. |
646 // TODO(kkania): This will cause us problems if GetWindowIds fails for a | 660 // TODO(kkania): This will cause us problems if GetWindowIds fails for a |
647 // reason other than the channel is disconnected. Look into having | 661 // reason other than the channel is disconnected. Look into having |
648 // |GetWindowIds| tell us if it just closed the last window. | 662 // |GetWindowIds| tell us if it just closed the last window. |
649 Terminate(); | 663 Terminate(); |
650 } | 664 } |
651 } | 665 } |
652 return error; | 666 return error; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 Error* error = GetElementRegionInViewHelper( | 787 Error* error = GetElementRegionInViewHelper( |
774 current_target_, element, region, center, verify_clickable_at_middle, | 788 current_target_, element, region, center, verify_clickable_at_middle, |
775 ®ion_offset); | 789 ®ion_offset); |
776 if (error) | 790 if (error) |
777 return error; | 791 return error; |
778 | 792 |
779 for (FramePath frame_path = current_target_.frame_path; | 793 for (FramePath frame_path = current_target_.frame_path; |
780 frame_path.IsSubframe(); | 794 frame_path.IsSubframe(); |
781 frame_path = frame_path.Parent()) { | 795 frame_path = frame_path.Parent()) { |
782 // Find the frame element for the current frame path. | 796 // Find the frame element for the current frame path. |
783 FrameId frame_id(current_target_.window_id, frame_path.Parent()); | 797 FrameId frame_id(current_target_.view_id, frame_path.Parent()); |
784 ElementId frame_element; | 798 ElementId frame_element; |
785 error = FindElement( | 799 error = FindElement( |
786 frame_id, ElementId(""), | 800 frame_id, ElementId(""), |
787 LocatorType::kXpath, frame_path.BaseName().value(), &frame_element); | 801 LocatorType::kXpath, frame_path.BaseName().value(), &frame_element); |
788 if (error) { | 802 if (error) { |
789 std::string context = base::StringPrintf( | 803 std::string context = base::StringPrintf( |
790 "Could not find frame element (%s) in frame (%s)", | 804 "Could not find frame element (%s) in frame (%s)", |
791 frame_path.BaseName().value().c_str(), | 805 frame_path.BaseName().value().c_str(), |
792 frame_path.Parent().value().c_str()); | 806 frame_path.Parent().value().c_str()); |
793 error->AddDetails(context); | 807 error->AddDetails(context); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 const std::string& key, | 995 const std::string& key, |
982 Value** value) { | 996 Value** value) { |
983 return ExecuteScriptAndParse( | 997 return ExecuteScriptAndParse( |
984 current_target_, | 998 current_target_, |
985 atoms::asString(atoms::GET_ATTRIBUTE), | 999 atoms::asString(atoms::GET_ATTRIBUTE), |
986 "getAttribute", | 1000 "getAttribute", |
987 CreateListValueFrom(element, key), | 1001 CreateListValueFrom(element, key), |
988 CreateDirectValueParser(value)); | 1002 CreateDirectValueParser(value)); |
989 } | 1003 } |
990 | 1004 |
991 Error* Session::WaitForAllTabsToStopLoading() { | 1005 Error* Session::WaitForAllViewsToStopLoading() { |
992 if (!automation_.get()) | 1006 if (!automation_.get()) |
993 return NULL; | 1007 return NULL; |
994 Error* error = NULL; | 1008 Error* error = NULL; |
995 RunSessionTask(NewRunnableMethod( | 1009 RunSessionTask(NewRunnableMethod( |
996 automation_.get(), | 1010 automation_.get(), |
997 &Automation::WaitForAllTabsToStopLoading, | 1011 &Automation::WaitForAllViewsToStopLoading, |
998 &error)); | 1012 &error)); |
999 return error; | 1013 return error; |
1000 } | 1014 } |
1001 | 1015 |
1002 Error* Session::InstallExtensionDeprecated(const FilePath& path) { | 1016 Error* Session::InstallExtensionDeprecated(const FilePath& path) { |
1003 Error* error = NULL; | 1017 Error* error = NULL; |
1004 RunSessionTask(NewRunnableMethod( | 1018 RunSessionTask(NewRunnableMethod( |
1005 automation_.get(), | 1019 automation_.get(), |
1006 &Automation::InstallExtensionDeprecated, | 1020 &Automation::InstallExtensionDeprecated, |
1007 path, | 1021 path, |
1008 &error)); | 1022 &error)); |
1009 return error; | 1023 return error; |
1010 } | 1024 } |
1011 | 1025 |
1012 Error* Session::GetInstalledExtensions( | |
1013 std::vector<std::string>* extension_ids) { | |
1014 Error* error = NULL; | |
1015 RunSessionTask(base::Bind( | |
1016 &Automation::GetInstalledExtensions, | |
1017 base::Unretained(automation_.get()), | |
1018 extension_ids, | |
1019 &error)); | |
1020 return error; | |
1021 } | |
1022 | |
1023 Error* Session::InstallExtension( | 1026 Error* Session::InstallExtension( |
1024 const FilePath& path, std::string* extension_id) { | 1027 const FilePath& path, std::string* extension_id) { |
1025 Error* error = NULL; | 1028 Error* error = NULL; |
1026 RunSessionTask(base::Bind( | 1029 RunSessionTask(base::Bind( |
1027 &Automation::InstallExtension, | 1030 &Automation::InstallExtension, |
1028 base::Unretained(automation_.get()), | 1031 base::Unretained(automation_.get()), |
1029 path, | 1032 path, |
1030 extension_id, | 1033 extension_id, |
1031 &error)); | 1034 &error)); |
1032 return error; | 1035 return error; |
| 1036 } |
| 1037 |
| 1038 Error* Session::GetExtensionsInfo(base::ListValue* extensions_list) { |
| 1039 Error* error = NULL; |
| 1040 RunSessionTask(base::Bind( |
| 1041 &Automation::GetExtensionsInfo, |
| 1042 base::Unretained(automation_.get()), |
| 1043 extensions_list, |
| 1044 &error)); |
| 1045 return error; |
| 1046 } |
| 1047 |
| 1048 Error* Session::IsPageActionVisible( |
| 1049 const WebViewId& tab_id, |
| 1050 const std::string& extension_id, |
| 1051 bool* is_visible) { |
| 1052 if (!tab_id.IsTab()) { |
| 1053 return new Error( |
| 1054 kUnknownError, |
| 1055 "The current target does not support page actions. Switch to a tab."); |
| 1056 } |
| 1057 Error* error = NULL; |
| 1058 RunSessionTask(base::Bind( |
| 1059 &Automation::IsPageActionVisible, |
| 1060 base::Unretained(automation_.get()), |
| 1061 tab_id, |
| 1062 extension_id, |
| 1063 is_visible, |
| 1064 &error)); |
| 1065 return error; |
| 1066 } |
| 1067 |
| 1068 Error* Session::SetExtensionState( |
| 1069 const std::string& extension_id, bool enable) { |
| 1070 Error* error = NULL; |
| 1071 RunSessionTask(base::Bind( |
| 1072 &Automation::SetExtensionState, |
| 1073 base::Unretained(automation_.get()), |
| 1074 extension_id, |
| 1075 enable, |
| 1076 &error)); |
| 1077 return error; |
| 1078 } |
| 1079 |
| 1080 Error* Session::ClickExtensionButton( |
| 1081 const std::string& extension_id, bool browser_action) { |
| 1082 Error* error = NULL; |
| 1083 RunSessionTask(base::Bind( |
| 1084 &Automation::ClickExtensionButton, |
| 1085 base::Unretained(automation_.get()), |
| 1086 extension_id, |
| 1087 browser_action, |
| 1088 &error)); |
| 1089 return error; |
| 1090 } |
| 1091 |
| 1092 Error* Session::UninstallExtension(const std::string& extension_id) { |
| 1093 Error* error = NULL; |
| 1094 RunSessionTask(base::Bind( |
| 1095 &Automation::UninstallExtension, |
| 1096 base::Unretained(automation_.get()), |
| 1097 extension_id, |
| 1098 &error)); |
| 1099 return error; |
1033 } | 1100 } |
1034 | 1101 |
1035 const std::string& Session::id() const { | 1102 const std::string& Session::id() const { |
1036 return id_; | 1103 return id_; |
1037 } | 1104 } |
1038 | 1105 |
1039 const FrameId& Session::current_target() const { | 1106 const FrameId& Session::current_target() const { |
1040 return current_target_; | 1107 return current_target_; |
1041 } | 1108 } |
1042 | 1109 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 done_event->Signal(); | 1164 done_event->Signal(); |
1098 } | 1165 } |
1099 | 1166 |
1100 void Session::InitOnSessionThread(const Automation::BrowserOptions& options, | 1167 void Session::InitOnSessionThread(const Automation::BrowserOptions& options, |
1101 Error** error) { | 1168 Error** error) { |
1102 automation_.reset(new Automation()); | 1169 automation_.reset(new Automation()); |
1103 automation_->Init(options, error); | 1170 automation_->Init(options, error); |
1104 if (*error) | 1171 if (*error) |
1105 return; | 1172 return; |
1106 | 1173 |
1107 std::vector<int> tab_ids; | 1174 std::vector<WebViewInfo> views; |
1108 automation_->GetTabIds(&tab_ids, error); | 1175 automation_->GetViews(&views, error); |
1109 if (*error) | 1176 if (*error) |
1110 return; | 1177 return; |
1111 if (tab_ids.empty()) { | 1178 if (views.empty()) { |
1112 *error = new Error(kUnknownError, "No tab ids after initialization"); | 1179 *error = new Error(kUnknownError, "No view ids after initialization"); |
1113 return; | 1180 return; |
1114 } | 1181 } |
1115 current_target_ = FrameId(tab_ids[0], FramePath()); | 1182 current_target_ = FrameId(views[0].view_id, FramePath()); |
1116 } | 1183 } |
1117 | 1184 |
1118 void Session::TerminateOnSessionThread() { | 1185 void Session::TerminateOnSessionThread() { |
1119 if (automation_.get()) | 1186 if (automation_.get()) |
1120 automation_->Terminate(); | 1187 automation_->Terminate(); |
1121 automation_.reset(); | 1188 automation_.reset(); |
1122 } | 1189 } |
1123 | 1190 |
1124 Error* Session::ExecuteScriptAndParseValue(const FrameId& frame_id, | 1191 Error* Session::ExecuteScriptAndParseValue(const FrameId& frame_id, |
1125 const std::string& script, | 1192 const std::string& script, |
1126 Value** script_result) { | 1193 Value** script_result) { |
1127 std::string response_json; | 1194 std::string response_json; |
1128 Error* error = NULL; | 1195 Error* error = NULL; |
1129 RunSessionTask(NewRunnableMethod( | 1196 RunSessionTask(NewRunnableMethod( |
1130 automation_.get(), | 1197 automation_.get(), |
1131 &Automation::ExecuteScript, | 1198 &Automation::ExecuteScript, |
1132 frame_id.window_id, | 1199 frame_id.view_id, |
1133 frame_id.frame_path, | 1200 frame_id.frame_path, |
1134 script, | 1201 script, |
1135 &response_json, | 1202 &response_json, |
1136 &error)); | 1203 &error)); |
1137 if (error) | 1204 if (error) |
1138 return error; | 1205 return error; |
1139 | 1206 |
1140 scoped_ptr<Value> value(base::JSONReader::ReadAndReturnError( | 1207 scoped_ptr<Value> value(base::JSONReader::ReadAndReturnError( |
1141 response_json, true, NULL, NULL)); | 1208 response_json, true, NULL, NULL)); |
1142 if (!value.get()) | 1209 if (!value.get()) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 return; | 1246 return; |
1180 } | 1247 } |
1181 for (size_t i = 0; i < key_events.size(); ++i) { | 1248 for (size_t i = 0; i < key_events.size(); ++i) { |
1182 if (options_.use_native_events) { | 1249 if (options_.use_native_events) { |
1183 // The automation provider will generate up/down events for us, we | 1250 // The automation provider will generate up/down events for us, we |
1184 // only need to call it once as compared to the WebKeyEvent method. | 1251 // only need to call it once as compared to the WebKeyEvent method. |
1185 // Hence we filter events by their types, keeping only rawkeydown. | 1252 // Hence we filter events by their types, keeping only rawkeydown. |
1186 if (key_events[i].type != automation::kRawKeyDownType) | 1253 if (key_events[i].type != automation::kRawKeyDownType) |
1187 continue; | 1254 continue; |
1188 automation_->SendNativeKeyEvent( | 1255 automation_->SendNativeKeyEvent( |
1189 current_target_.window_id, | 1256 current_target_.view_id, |
1190 key_events[i].key_code, | 1257 key_events[i].key_code, |
1191 key_events[i].modifiers, | 1258 key_events[i].modifiers, |
1192 error); | 1259 error); |
1193 } else { | 1260 } else { |
1194 automation_->SendWebKeyEvent( | 1261 automation_->SendWebKeyEvent( |
1195 current_target_.window_id, key_events[i], error); | 1262 current_target_.view_id, |
| 1263 key_events[i], error); |
1196 } | 1264 } |
1197 if (*error) { | 1265 if (*error) { |
1198 std::string details = base::StringPrintf( | 1266 std::string details = base::StringPrintf( |
1199 "Failed to send key event. Event details:\n" | 1267 "Failed to send key event. Event details:\n" |
1200 "Type: %d, KeyCode: %d, UnmodifiedText: %s, ModifiedText: %s, " | 1268 "Type: %d, KeyCode: %d, UnmodifiedText: %s, ModifiedText: %s, " |
1201 "Modifiers: %d", | 1269 "Modifiers: %d", |
1202 key_events[i].type, | 1270 key_events[i].type, |
1203 key_events[i].key_code, | 1271 key_events[i].key_code, |
1204 key_events[i].unmodified_text.c_str(), | 1272 key_events[i].unmodified_text.c_str(), |
1205 key_events[i].modified_text.c_str(), | 1273 key_events[i].modified_text.c_str(), |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 middle_point.Offset(region.width() / 2, region.height() / 2); | 1498 middle_point.Offset(region.width() / 2, region.height() / 2); |
1431 error = VerifyElementIsClickable(frame_id, element, middle_point); | 1499 error = VerifyElementIsClickable(frame_id, element, middle_point); |
1432 if (error) | 1500 if (error) |
1433 return error; | 1501 return error; |
1434 } | 1502 } |
1435 *location = temp_location; | 1503 *location = temp_location; |
1436 return NULL; | 1504 return NULL; |
1437 } | 1505 } |
1438 | 1506 |
1439 Error* Session::GetScreenShot(std::string* png) { | 1507 Error* Session::GetScreenShot(std::string* png) { |
| 1508 if (!current_target_.view_id.IsTab()) { |
| 1509 return new Error(kUnknownError, |
| 1510 "The current target does not support screenshot"); |
| 1511 } |
1440 Error* error = NULL; | 1512 Error* error = NULL; |
1441 ScopedTempDir screenshots_dir; | 1513 ScopedTempDir screenshots_dir; |
1442 if (!screenshots_dir.CreateUniqueTempDir()) { | 1514 if (!screenshots_dir.CreateUniqueTempDir()) { |
1443 return new Error(kUnknownError, | 1515 return new Error(kUnknownError, |
1444 "Could not create temp directory for screenshot"); | 1516 "Could not create temp directory for screenshot"); |
1445 } | 1517 } |
1446 | 1518 |
1447 FilePath path = screenshots_dir.path().AppendASCII("screen"); | 1519 FilePath path = screenshots_dir.path().AppendASCII("screen"); |
1448 RunSessionTask(NewRunnableMethod( | 1520 RunSessionTask(NewRunnableMethod( |
1449 automation_.get(), | 1521 automation_.get(), |
1450 &Automation::CaptureEntirePageAsPNG, | 1522 &Automation::CaptureEntirePageAsPNG, |
1451 current_target_.window_id, | 1523 current_target_.view_id, |
1452 path, | 1524 path, |
1453 &error)); | 1525 &error)); |
1454 if (error) | 1526 if (error) |
1455 return error; | 1527 return error; |
1456 if (!file_util::ReadFileToString(path, png)) | 1528 if (!file_util::ReadFileToString(path, png)) |
1457 return new Error(kUnknownError, "Could not read screenshot file"); | 1529 return new Error(kUnknownError, "Could not read screenshot file"); |
1458 return NULL; | 1530 return NULL; |
1459 } | 1531 } |
1460 | 1532 |
1461 Error* Session::GetBrowserConnectionState(bool* online) { | 1533 Error* Session::GetBrowserConnectionState(bool* online) { |
1462 return ExecuteScriptAndParse( | 1534 return ExecuteScriptAndParse( |
1463 current_target_, | 1535 current_target_, |
1464 atoms::asString(atoms::IS_ONLINE), | 1536 atoms::asString(atoms::IS_ONLINE), |
1465 "isOnline", | 1537 "isOnline", |
1466 new ListValue(), | 1538 new ListValue(), |
1467 CreateDirectValueParser(online)); | 1539 CreateDirectValueParser(online)); |
1468 } | 1540 } |
1469 | 1541 |
1470 Error* Session::GetAppCacheStatus(int* status) { | 1542 Error* Session::GetAppCacheStatus(int* status) { |
1471 return ExecuteScriptAndParse( | 1543 return ExecuteScriptAndParse( |
1472 current_target_, | 1544 current_target_, |
1473 atoms::asString(atoms::GET_APPCACHE_STATUS), | 1545 atoms::asString(atoms::GET_APPCACHE_STATUS), |
1474 "getAppcacheStatus", | 1546 "getAppcacheStatus", |
1475 new ListValue(), | 1547 new ListValue(), |
1476 CreateDirectValueParser(status)); | 1548 CreateDirectValueParser(status)); |
1477 } | 1549 } |
1478 | 1550 |
1479 } // namespace webdriver | 1551 } // namespace webdriver |
OLD | NEW |