Home | History | Annotate | Download | only in commands
      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 "chrome/test/webdriver/commands/chrome_commands.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/files/file_path.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "chrome/test/automation/value_conversion_util.h"
     13 #include "chrome/test/webdriver/commands/response.h"
     14 #include "chrome/test/webdriver/webdriver_error.h"
     15 #include "chrome/test/webdriver/webdriver_session.h"
     16 #include "chrome/test/webdriver/webdriver_util.h"
     17 
     18 using base::DictionaryValue;
     19 using base::ListValue;
     20 using base::Value;
     21 
     22 namespace webdriver {
     23 
     24 ExtensionsCommand::ExtensionsCommand(
     25     const std::vector<std::string>& path_segments,
     26     const DictionaryValue* const parameters)
     27     : WebDriverCommand(path_segments, parameters) {}
     28 
     29 ExtensionsCommand::~ExtensionsCommand() {}
     30 
     31 bool ExtensionsCommand::DoesGet() {
     32   return true;
     33 }
     34 
     35 bool ExtensionsCommand::DoesPost() {
     36   return true;
     37 }
     38 
     39 void ExtensionsCommand::ExecuteGet(Response* const response) {
     40   ListValue extensions_list;
     41   Error* error = session_->GetExtensionsInfo(&extensions_list);
     42   if (error) {
     43     response->SetError(error);
     44     return;
     45   }
     46 
     47   ListValue id_list;
     48   for (size_t i = 0; i < extensions_list.GetSize(); ++i) {
     49     DictionaryValue* extension_dict;
     50     if (!extensions_list.GetDictionary(i, &extension_dict)) {
     51       response->SetError(
     52           new Error(kUnknownError, "Invalid extension dictionary"));
     53       return;
     54     }
     55     bool is_component;
     56     if (!extension_dict->GetBoolean("is_component", &is_component)) {
     57       response->SetError(
     58           new Error(kUnknownError, "Missing or invalid 'is_component'"));
     59       return;
     60     }
     61     if (is_component)
     62       continue;
     63 
     64     std::string extension_id;
     65     if (!extension_dict->GetString("id", &extension_id)) {
     66       response->SetError(new Error(kUnknownError, "Missing or invalid 'id'"));
     67       return;
     68     }
     69 
     70     id_list.Append(new base::StringValue(extension_id));
     71   }
     72 
     73   response->SetValue(id_list.DeepCopy());
     74 }
     75 
     76 void ExtensionsCommand::ExecutePost(Response* const response) {
     77   base::FilePath::StringType path_string;
     78   if (!GetStringParameter("path", &path_string)) {
     79     response->SetError(new Error(kBadRequest, "'path' missing or invalid"));
     80     return;
     81   }
     82 
     83   std::string extension_id;
     84   Error* error = session_->InstallExtension(
     85       base::FilePath(path_string), &extension_id);
     86   if (error) {
     87     response->SetError(error);
     88     return;
     89   }
     90   response->SetValue(new base::StringValue(extension_id));
     91 }
     92 
     93 ExtensionCommand::ExtensionCommand(
     94     const std::vector<std::string>& path_segments,
     95     const DictionaryValue* const parameters)
     96     : WebDriverCommand(path_segments, parameters) {}
     97 
     98 ExtensionCommand::~ExtensionCommand() {}
     99 
    100 bool ExtensionCommand::Init(Response* const response) {
    101   if (!WebDriverCommand::Init(response))
    102     return false;
    103 
    104   // Path: "/session/$sessionId/chrome/extension/$id".
    105   extension_id_ = GetPathVariable(5);
    106   if (extension_id_.empty()) {
    107     response->SetError(new Error(kBadRequest, "Invalid extension ID"));
    108     return false;
    109   }
    110   return true;
    111 }
    112 
    113 bool ExtensionCommand::DoesGet() {
    114   return true;
    115 }
    116 
    117 bool ExtensionCommand::DoesPost() {
    118   return true;
    119 }
    120 
    121 bool ExtensionCommand::DoesDelete() {
    122   return true;
    123 }
    124 
    125 void ExtensionCommand::ExecuteGet(Response* const response) {
    126   ListValue extensions_list;
    127   Error* error = session_->GetExtensionsInfo(&extensions_list);
    128   if (error) {
    129     response->SetError(error);
    130     return;
    131   }
    132 
    133   bool found = false;
    134   DictionaryValue extension;
    135   for (size_t i = 0; i < extensions_list.GetSize(); ++i) {
    136     DictionaryValue* extension_dict;
    137     if (!extensions_list.GetDictionary(i, &extension_dict)) {
    138       response->SetError(
    139           new Error(kUnknownError, "Invalid extension dictionary"));
    140       return;
    141     }
    142     std::string id;
    143     if (!extension_dict->GetString("id", &id)) {
    144       response->SetError(
    145           new Error(kUnknownError, "Missing extension ID"));
    146       return;
    147     }
    148     if (id == extension_id_) {
    149       found = true;
    150       extension.Swap(extension_dict);
    151       break;
    152     }
    153   }
    154 
    155   if (!found) {
    156     response->SetError(
    157         new Error(kUnknownError, "Extension is not installed"));
    158     return;
    159   }
    160 
    161   bool is_enabled;
    162   if (!extension.GetBoolean("is_enabled", &is_enabled)) {
    163     response->SetError(
    164         new Error(kUnknownError, "Missing or invalid 'is_enabled'"));
    165     return;
    166   }
    167   bool has_page_action;
    168   if (!extension.GetBoolean("has_page_action", &has_page_action)) {
    169     response->SetError(
    170         new Error(kUnknownError, "Missing or invalid 'is_enabled'"));
    171     return;
    172   }
    173 
    174   bool is_visible = false;
    175   if (is_enabled && has_page_action) {
    176     // Only check page action visibility if we are enabled with a page action.
    177     // Otherwise Chrome will throw an error saying the extension does not have
    178     // a page action.
    179     error = session_->IsPageActionVisible(
    180         session_->current_target().view_id, extension_id_, &is_visible);
    181     if (error) {
    182       response->SetError(error);
    183       return;
    184     }
    185   }
    186 
    187   extension.SetBoolean("is_page_action_visible", is_visible);
    188   response->SetValue(extension.DeepCopy());
    189 }
    190 
    191 void ExtensionCommand::ExecutePost(Response* const response) {
    192   Error* error = NULL;
    193   if (HasParameter("enable")) {
    194     bool enable;
    195     if (!GetBooleanParameter("enable", &enable)) {
    196       response->SetError(new Error(kBadRequest, "'enable' must be a bool"));
    197       return;
    198     }
    199     error = session_->SetExtensionState(extension_id_, enable);
    200   } else if (HasParameter("click_button")) {
    201     std::string button;
    202     if (!GetStringParameter("click_button", &button)) {
    203       response->SetError(
    204           new Error(kBadRequest, "'click_button' must be a string"));
    205       return;
    206     }
    207     error = session_->ClickExtensionButton(extension_id_,
    208                                            button == "browser_action");
    209   } else {
    210     error = new Error(kBadRequest, "Missing action parameter");
    211   }
    212 
    213   if (error) {
    214     response->SetError(error);
    215     return;
    216   }
    217 }
    218 
    219 void ExtensionCommand::ExecuteDelete(Response* const response) {
    220   Error* error = session_->UninstallExtension(extension_id_);
    221   if (error) {
    222     response->SetError(error);
    223     return;
    224   }
    225 }
    226 
    227 ViewsCommand::ViewsCommand(
    228     const std::vector<std::string>& path_segments,
    229     const DictionaryValue* const parameters)
    230     : WebDriverCommand(path_segments, parameters) {}
    231 
    232 ViewsCommand::~ViewsCommand() {}
    233 
    234 bool ViewsCommand::DoesGet() {
    235   return true;
    236 }
    237 
    238 void ViewsCommand::ExecuteGet(Response* const response) {
    239   std::vector<WebViewInfo> views;
    240   Error* error = session_->GetViews(&views);
    241   if (error) {
    242     response->SetError(error);
    243     return;
    244   }
    245   ListValue* views_list = new ListValue();
    246   for (size_t i = 0; i < views.size(); ++i) {
    247     DictionaryValue* dict = new DictionaryValue();
    248     AutomationId id = views[i].view_id.GetId();
    249     dict->SetString("handle", WebViewIdToString(WebViewId::ForView(id)));
    250     dict->SetInteger("type", id.type());
    251     if (!views[i].extension_id.empty())
    252       dict->SetString("extension_id", views[i].extension_id);
    253     views_list->Append(dict);
    254   }
    255   response->SetValue(views_list);
    256 }
    257 
    258 #if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
    259 HeapProfilerDumpCommand::HeapProfilerDumpCommand(
    260     const std::vector<std::string>& ps,
    261     const DictionaryValue* const parameters)
    262     : WebDriverCommand(ps, parameters) {}
    263 
    264 HeapProfilerDumpCommand::~HeapProfilerDumpCommand() {}
    265 
    266 bool HeapProfilerDumpCommand::DoesPost() {
    267   return true;
    268 }
    269 
    270 void HeapProfilerDumpCommand::ExecutePost(Response* const response) {
    271   std::string reason;
    272   if (!GetStringParameter("reason", &reason)) {
    273     response->SetError(new Error(kBadRequest, "'reason' missing or invalid"));
    274     return;
    275   }
    276 
    277   Error* error = session_->HeapProfilerDump(reason);
    278   if (error) {
    279     response->SetError(error);
    280     return;
    281   }
    282 }
    283 #endif  // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
    284 
    285 }  // namespace webdriver
    286