1// Copyright 2013 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 "base/base64.h"
6#include "base/command_line.h"
7#include "base/json/json_reader.h"
8#include "content/browser/devtools/devtools_protocol.h"
9#include "content/public/browser/devtools_agent_host.h"
10#include "content/public/browser/web_contents.h"
11#include "content/public/test/browser_test_utils.h"
12#include "content/public/test/content_browser_test.h"
13#include "content/shell/browser/shell.h"
14#include "third_party/skia/include/core/SkBitmap.h"
15#include "ui/compositor/compositor_switches.h"
16#include "ui/gfx/codec/png_codec.h"
17
18namespace content {
19
20class RendererOverridesHandlerTest : public ContentBrowserTest,
21                                     public DevToolsAgentHostClient {
22 protected:
23  void SendCommand(const std::string& method,
24                   base::DictionaryValue* params) {
25    agent_host_->DispatchProtocolMessage(
26        DevToolsProtocol::CreateCommand(1, method, params)->Serialize());
27    base::MessageLoop::current()->Run();
28  }
29
30  bool HasValue(const std::string& path) {
31    base::Value* value = 0;
32    return result_->Get(path, &value);
33  }
34
35  bool HasListItem(const std::string& path_to_list,
36                   const std::string& name,
37                   const std::string& value) {
38    base::ListValue* list;
39    if (!result_->GetList(path_to_list, &list))
40      return false;
41
42    for (size_t i = 0; i != list->GetSize(); i++) {
43      base::DictionaryValue* item;
44      if (!list->GetDictionary(i, &item))
45        return false;
46      std::string id;
47      if (!item->GetString(name, &id))
48        return false;
49      if (id == value)
50        return true;
51    }
52    return false;
53  }
54
55  scoped_ptr<base::DictionaryValue> result_;
56  scoped_refptr<DevToolsAgentHost> agent_host_;
57
58 private:
59  virtual void SetUpOnMainThread() OVERRIDE {
60    agent_host_ = DevToolsAgentHost::GetOrCreateFor(shell()->web_contents());
61    agent_host_->AttachClient(this);
62  }
63
64  virtual void TearDownOnMainThread() OVERRIDE {
65    agent_host_->DetachClient();
66    agent_host_ = NULL;
67  }
68
69  virtual void DispatchProtocolMessage(
70      DevToolsAgentHost* agent_host, const std::string& message) OVERRIDE {
71    scoped_ptr<base::DictionaryValue> root(
72        static_cast<base::DictionaryValue*>(base::JSONReader::Read(message)));
73    base::DictionaryValue* result;
74    EXPECT_TRUE(root->GetDictionary("result", &result));
75    result_.reset(result->DeepCopy());
76    base::MessageLoop::current()->QuitNow();
77  }
78
79  virtual void AgentHostClosed(
80      DevToolsAgentHost* agent_host, bool replaced) OVERRIDE {
81    EXPECT_TRUE(false);
82  }
83};
84
85IN_PROC_BROWSER_TEST_F(RendererOverridesHandlerTest, QueryUsageAndQuota) {
86  base::DictionaryValue* params = new base::DictionaryValue();
87  params->SetString("securityOrigin", "http://example.com");
88  SendCommand("Page.queryUsageAndQuota", params);
89
90  EXPECT_TRUE(HasValue("quota.persistent"));
91  EXPECT_TRUE(HasValue("quota.temporary"));
92  EXPECT_TRUE(HasListItem("usage.temporary", "id", "appcache"));
93  EXPECT_TRUE(HasListItem("usage.temporary", "id", "database"));
94  EXPECT_TRUE(HasListItem("usage.temporary", "id", "indexeddatabase"));
95  EXPECT_TRUE(HasListItem("usage.temporary", "id", "filesystem"));
96  EXPECT_TRUE(HasListItem("usage.persistent", "id", "filesystem"));
97}
98
99class CaptureScreenshotTest : public RendererOverridesHandlerTest {
100 private:
101#if !defined(OS_ANDROID)
102  virtual void SetUpCommandLine(base::CommandLine* command_line) OVERRIDE {
103    command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
104  }
105#endif
106};
107
108// Does not link on Android
109#if defined(OS_ANDROID)
110#define MAYBE_CaptureScreenshot DISABLED_CaptureScreenshot
111#else
112#define MAYBE_CaptureScreenshot CaptureScreenshot
113#endif
114IN_PROC_BROWSER_TEST_F(CaptureScreenshotTest, MAYBE_CaptureScreenshot) {
115  shell()->LoadURL(GURL("about:blank"));
116  EXPECT_TRUE(content::ExecuteScript(
117      shell()->web_contents()->GetRenderViewHost(),
118      "document.body.style.background = '#123456'"));
119  SendCommand("Page.captureScreenshot", new base::DictionaryValue());
120  std::string base64;
121  EXPECT_TRUE(result_->GetString("data", &base64));
122  std::string png;
123  EXPECT_TRUE(base::Base64Decode(base64, &png));
124  SkBitmap bitmap;
125  gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(png.data()),
126                        png.size(), &bitmap);
127  SkColor color(bitmap.getColor(0, 0));
128  EXPECT_TRUE(std::abs(0x12-(int)SkColorGetR(color)) <= 1);
129  EXPECT_TRUE(std::abs(0x34-(int)SkColorGetG(color)) <= 1);
130  EXPECT_TRUE(std::abs(0x56-(int)SkColorGetB(color)) <= 1);
131}
132
133}  // namespace content
134