blob: 1257a0e627d78505958a408647d91dfd7055d5ad [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/optimization_guide/content/renderer/page_text_agent.h"
#include <limits>
#include <string>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/web/web_local_frame.h"
namespace optimization_guide {
namespace {
class TestConsumer : public mojom::PageTextConsumer {
public:
TestConsumer() = default;
~TestConsumer() override = default;
std::u16string text() const { return base::StrCat(chunks_); }
bool on_chunks_end_called() const { return on_chunks_end_called_; }
size_t num_chunks() const { return chunks_.size(); }
void Bind(mojo::PendingReceiver<mojom::PageTextConsumer> pending_receiver) {
receiver_.Bind(std::move(pending_receiver));
}
// mojom::PageTextConsumer:
void OnTextDumpChunk(const std::u16string& chunk) override {
ASSERT_FALSE(on_chunks_end_called_);
chunks_.push_back(chunk);
}
void OnChunksEnd() override { on_chunks_end_called_ = true; }
private:
mojo::Receiver<mojom::PageTextConsumer> receiver_{this};
std::vector<std::u16string> chunks_;
bool on_chunks_end_called_ = false;
};
} // namespace
class PageTextAgentRenderViewTest : public content::RenderViewTest {
public:
PageTextAgentRenderViewTest() = default;
~PageTextAgentRenderViewTest() override = default;
};
TEST_F(PageTextAgentRenderViewTest, AMPSubframeFirstLayout) {
// Create and get a subframe.
LoadHTML(
"<html><body>"
" <p>hello</p>"
" <iframe name=sub srcdoc=\"<p>world</p>\"></iframe>"
"</body></html>");
content::RenderFrame* subframe = content::RenderFrame::FromWebFrame(
GetMainFrame()->FindFrameByName("sub")->ToWebLocalFrame());
PageTextAgent subframe_agent(subframe);
// Send the request.
mojo::PendingRemote<mojom::PageTextConsumer> consumer_remote;
TestConsumer consumer;
consumer.Bind(consumer_remote.InitWithNewPipeAndPassReceiver());
auto request = mojom::PageTextDumpRequest::New();
request->max_size = 1024;
request->event = mojom::TextDumpEvent::kFirstLayout;
subframe_agent.RequestPageTextDump(std::move(request),
std::move(consumer_remote));
// Simulate a page load.
subframe_agent.DidObserveLoadingBehavior(
blink::LoadingBehaviorFlag::kLoadingBehaviorAmpDocumentLoaded);
subframe_agent.DidFinishLoad();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(consumer.on_chunks_end_called());
}
TEST_F(PageTextAgentRenderViewTest, NotAMPSubframeLoadFinished) {
// Create and get a subframe.
LoadHTML(
"<html><body>"
" <p>hello</p>"
" <iframe name=sub srcdoc=\"<p>world</p>\"></iframe>"
"</body></html>");
content::RenderFrame* subframe = content::RenderFrame::FromWebFrame(
GetMainFrame()->FindFrameByName("sub")->ToWebLocalFrame());
PageTextAgent subframe_agent(subframe);
// Send the request.
mojo::PendingRemote<mojom::PageTextConsumer> consumer_remote;
TestConsumer consumer;
consumer.Bind(consumer_remote.InitWithNewPipeAndPassReceiver());
auto request = mojom::PageTextDumpRequest::New();
request->max_size = 1024;
request->event = mojom::TextDumpEvent::kFinishedLoad;
subframe_agent.RequestPageTextDump(std::move(request),
std::move(consumer_remote));
// Simulate a page load.
subframe_agent.DidObserveLoadingBehavior(
blink::LoadingBehaviorFlag::kLoadingBehaviorNone);
subframe_agent.DidFinishLoad();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(consumer.on_chunks_end_called());
}
TEST_F(PageTextAgentRenderViewTest, MainFrame) {
// Create and get a subframe.
LoadHTML(
"<html><body>"
" <p>hello</p>"
"</body></html>");
content::RenderFrame* mainframe =
content::RenderFrame::FromWebFrame(GetMainFrame());
PageTextAgent subframe_agent(mainframe);
// Send the request.
mojo::PendingRemote<mojom::PageTextConsumer> consumer_remote;
TestConsumer consumer;
consumer.Bind(consumer_remote.InitWithNewPipeAndPassReceiver());
auto request = mojom::PageTextDumpRequest::New();
request->max_size = 1024;
request->event = mojom::TextDumpEvent::kFinishedLoad;
subframe_agent.RequestPageTextDump(std::move(request),
std::move(consumer_remote));
// Simulate a page load.
subframe_agent.DidObserveLoadingBehavior(
blink::LoadingBehaviorFlag::kLoadingBehaviorAmpDocumentLoaded);
subframe_agent.DidFinishLoad();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(consumer.on_chunks_end_called());
}
TEST_F(PageTextAgentRenderViewTest, AMPSuccessCase) {
// Create and get a subframe.
LoadHTML(
"<html><body>"
" <p>hello</p>"
" <iframe name=sub srcdoc=\"<p>world</p>\"></iframe>"
"</body></html>");
content::RenderFrame* subframe = content::RenderFrame::FromWebFrame(
GetMainFrame()->FindFrameByName("sub")->ToWebLocalFrame());
PageTextAgent subframe_agent(subframe);
// Send the request.
mojo::PendingRemote<mojom::PageTextConsumer> consumer_remote;
TestConsumer consumer;
consumer.Bind(consumer_remote.InitWithNewPipeAndPassReceiver());
auto request = mojom::PageTextDumpRequest::New();
request->max_size = 1024;
request->event = mojom::TextDumpEvent::kFinishedLoad;
subframe_agent.RequestPageTextDump(std::move(request),
std::move(consumer_remote));
// Simulate a page load.
subframe_agent.DidObserveLoadingBehavior(
blink::LoadingBehaviorFlag::kLoadingBehaviorAmpDocumentLoaded);
subframe_agent.DidFinishLoad();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(consumer.on_chunks_end_called());
EXPECT_EQ(u"world", consumer.text());
}
} // namespace optimization_guide