1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/automation_extension.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/web_view.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AutomationExtension::AutomationExtension(scoped_ptr<WebView> web_view)
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_view_(web_view.Pass()) {}
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AutomationExtension::~AutomationExtension() {}
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)Status AutomationExtension::CaptureScreenshot(std::string* screenshot) {
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  base::ListValue args;
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<base::Value> result;
20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  Status status = web_view_->CallAsyncFunction(
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      std::string(),
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      "captureScreenshot",
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      args,
24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::TimeDelta::FromSeconds(10),
25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      &result);
26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (status.IsError())
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return Status(status.code(), "cannot take screenshot", status);
28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!result->GetAsString(screenshot))
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return Status(kUnknownError, "screenshot is not a string");
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return Status(kOk);
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::GetWindowPosition(int* x, int* y) {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int temp_width, temp_height;
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetWindowInfo(x, y, &temp_width, &temp_height);
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::SetWindowPosition(int x, int y) {
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue update_info;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetInteger("left", x);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetInteger("top", y);
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetString("state", "normal");
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return UpdateWindow(update_info);
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::GetWindowSize(int* width, int* height) {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int temp_x, temp_y;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetWindowInfo(&temp_x, &temp_y, width, height);
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::SetWindowSize(int width, int height) {
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue update_info;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetInteger("width", width);
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetInteger("height", height);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetString("state", "normal");
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return UpdateWindow(update_info);
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::MaximizeWindow() {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue update_info;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  update_info.SetString("state", "maximized");
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return UpdateWindow(update_info);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::GetWindowInfo(int* x,
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          int* y,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          int* width,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          int* height) {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ListValue args;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> result;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Status status = web_view_->CallAsyncFunction(std::string(),
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               "getWindowInfo",
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               args,
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               base::TimeDelta::FromSeconds(10),
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               &result);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (status.IsError())
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return status;
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::DictionaryValue* dict;
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int temp_x = 0;
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int temp_y = 0;
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int temp_width = 0;
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int temp_height = 0;
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!result->GetAsDictionary(&dict) ||
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !dict->GetInteger("left", &temp_x) ||
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !dict->GetInteger("top", &temp_y) ||
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !dict->GetInteger("width", &temp_width) ||
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !dict->GetInteger("height", &temp_height)) {
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Status(kUnknownError, "received invalid window info");
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *x = temp_x;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *y = temp_y;
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *width = temp_width;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *height = temp_height;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return Status(kOk);
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status AutomationExtension::UpdateWindow(
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::DictionaryValue& update_info) {
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ListValue args;
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  args.Append(update_info.DeepCopy());
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<base::Value> result;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return web_view_->CallAsyncFunction(std::string(),
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      "updateWindow",
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      args,
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      base::TimeDelta::FromSeconds(10),
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                      &result);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Status AutomationExtension::LaunchApp(std::string id) {
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue args;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  args.AppendString(id);
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::Value> result;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return web_view_->CallAsyncFunction(std::string(),
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      "launchApp",
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      args,
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::TimeDelta::FromSeconds(10),
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      &result);
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
120