blob: 67fee60f2086f5f0d404b30be5e08fb45c5130e1 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <string>
#include <vector>
#include "base/base64.h"
#include "content/public/test/browser_test.h"
#include "headless/public/devtools/domains/page.h"
#include "headless/public/devtools/domains/runtime.h"
#include "headless/public/devtools/domains/security.h"
#include "headless/public/headless_browser.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_web_contents.h"
#include "headless/test/headless_browser_test.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
using testing::UnorderedElementsAre;
namespace headless {
class HeadlessWebContentsTest : public HeadlessBrowserTest {};
IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, Navigation) {
EXPECT_TRUE(embedded_test_server()->Start());
HeadlessBrowserContext* browser_context =
browser()->CreateBrowserContextBuilder().Build();
HeadlessWebContents* web_contents =
browser_context->CreateWebContentsBuilder()
.SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
.Build();
EXPECT_TRUE(WaitForLoad(web_contents));
EXPECT_THAT(browser_context->GetAllWebContents(),
UnorderedElementsAre(web_contents));
}
IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, WindowOpen) {
EXPECT_TRUE(embedded_test_server()->Start());
HeadlessBrowserContext* browser_context =
browser()->CreateBrowserContextBuilder().Build();
HeadlessWebContents* web_contents =
browser_context->CreateWebContentsBuilder()
.SetInitialURL(embedded_test_server()->GetURL("/window_open.html"))
.Build();
EXPECT_TRUE(WaitForLoad(web_contents));
EXPECT_EQ(static_cast<size_t>(2),
browser_context->GetAllWebContents().size());
}
IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, Focus) {
EXPECT_TRUE(embedded_test_server()->Start());
HeadlessBrowserContext* browser_context =
browser()->CreateBrowserContextBuilder().Build();
HeadlessWebContents* web_contents =
browser_context->CreateWebContentsBuilder()
.SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
.Build();
EXPECT_TRUE(WaitForLoad(web_contents));
bool result;
EXPECT_TRUE(EvaluateScript(web_contents, "document.hasFocus()")
->GetResult()
->GetValue()
->GetAsBoolean(&result));
EXPECT_TRUE(result);
HeadlessWebContents* web_contents2 =
browser_context->CreateWebContentsBuilder()
.SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
.Build();
EXPECT_TRUE(WaitForLoad(web_contents2));
// TODO(irisu): Focus of two web contents should be independent of the other.
// Both web_contents and web_contents2 should be focused at this point.
// NOTE(dvallet): Mac headless implementation already does this.
EXPECT_TRUE(EvaluateScript(web_contents, "document.hasFocus()")
->GetResult()
->GetValue()
->GetAsBoolean(&result));
#if !defined(OS_MACOSX)
EXPECT_FALSE(result);
#else
// Mac sets all contents as focused.
EXPECT_TRUE(result);
#endif
EXPECT_TRUE(EvaluateScript(web_contents2, "document.hasFocus()")
->GetResult()
->GetValue()
->GetAsBoolean(&result));
EXPECT_TRUE(result);
}
namespace {
bool DecodePNG(std::string base64_data, SkBitmap* bitmap) {
std::string png_data;
if (!base::Base64Decode(base64_data, &png_data))
return false;
return gfx::PNGCodec::Decode(
reinterpret_cast<unsigned const char*>(png_data.data()), png_data.size(),
bitmap);
}
} // namespace
// Parameter specifies whether --disable-gpu should be used.
class HeadlessWebContentsScreenshotTest
: public HeadlessAsyncDevTooledBrowserTest,
public ::testing::WithParamInterface<bool> {
public:
void SetUp() override {
EnablePixelOutput();
if (GetParam())
UseSoftwareCompositing();
HeadlessAsyncDevTooledBrowserTest::SetUp();
}
void RunDevTooledTest() override {
std::unique_ptr<runtime::EvaluateParams> params =
runtime::EvaluateParams::Builder()
.SetExpression("document.body.style.background = '#0000ff'")
.Build();
devtools_client_->GetRuntime()->Evaluate(
std::move(params),
base::Bind(&HeadlessWebContentsScreenshotTest::OnPageSetupCompleted,
base::Unretained(this)));
}
void OnPageSetupCompleted(std::unique_ptr<runtime::EvaluateResult> result) {
devtools_client_->GetPage()->GetExperimental()->CaptureScreenshot(
page::CaptureScreenshotParams::Builder().SetFromSurface(true).Build(),
base::Bind(&HeadlessWebContentsScreenshotTest::OnScreenshotCaptured,
base::Unretained(this)));
}
void OnScreenshotCaptured(
std::unique_ptr<page::CaptureScreenshotResult> result) {
std::string base64 = result->GetData();
EXPECT_LT(0U, base64.length());
SkBitmap result_bitmap;
EXPECT_TRUE(DecodePNG(base64, &result_bitmap));
EXPECT_EQ(800, result_bitmap.width());
EXPECT_EQ(600, result_bitmap.height());
SkColor actual_color = result_bitmap.getColor(400, 300);
SkColor expected_color = SkColorSetRGB(0x00, 0x00, 0xff);
EXPECT_EQ(expected_color, actual_color);
FinishAsynchronousTest();
}
};
HEADLESS_ASYNC_DEVTOOLED_TEST_P(HeadlessWebContentsScreenshotTest);
// Instantiate test case for both software and gpu compositing modes.
INSTANTIATE_TEST_CASE_P(HeadlessWebContentsScreenshotTests,
HeadlessWebContentsScreenshotTest,
::testing::Bool());
class HeadlessWebContentsSecurityTest
: public HeadlessAsyncDevTooledBrowserTest,
public security::ExperimentalObserver {
public:
void RunDevTooledTest() override {
devtools_client_->GetSecurity()->GetExperimental()->AddObserver(this);
devtools_client_->GetSecurity()->GetExperimental()->Enable(
security::EnableParams::Builder().Build());
}
void OnSecurityStateChanged(
const security::SecurityStateChangedParams& params) override {
EXPECT_EQ(security::SecurityState::NEUTRAL, params.GetSecurityState());
devtools_client_->GetSecurity()->GetExperimental()->Disable(
security::DisableParams::Builder().Build());
devtools_client_->GetSecurity()->GetExperimental()->RemoveObserver(this);
FinishAsynchronousTest();
}
};
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsSecurityTest);
} // namespace headless