#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/current_thread.h"
#include "base/test/bind.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/base/filename_util.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/test/test_web_frame_content_dumper.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_element_collection.h"
#include "third_party/blink/public/web/web_frame_serializer.h"
#include "third_party/blink/public/web/web_frame_serializer_client.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_meta_element.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_savable_resources_test_support.h"
#include "third_party/blink/public/web/web_view.h"
using blink::WebData;
using blink::WebDocument;
using blink::WebElement;
using blink::WebElementCollection;
using blink::WebFrame;
using blink::WebFrameSerializer;
using blink::WebFrameSerializerClient;
using blink::WebLocalFrame;
using blink::WebMetaElement;
using blink::WebNode;
using blink::WebString;
using blink::WebURL;
using blink::WebView;
namespace content {
bool HasDocType(const WebDocument& doc) {
return doc.FirstChild().IsDocumentTypeNode();
}
#if BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER)
#define MAYBE_DomSerializerTests DISABLED_DomSerializerTests
#elif defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
defined(ADDRESS_SANITIZER)
#define MAYBE_DomSerializerTests DISABLED_DomSerializerTests
#else
#define MAYBE_DomSerializerTests DomSerializerTests
#endif
class MAYBE_DomSerializerTests : public ContentBrowserTest,
public WebFrameSerializerClient {
public:
MAYBE_DomSerializerTests() = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kSingleProcess);
}
void SetUpOnMainThread() override {
main_frame_token_ =
shell()->web_contents()->GetPrimaryMainFrame()->GetFrameToken();
}
void DidSerializeDataForFrame(const std::vector<char>& data,
FrameSerializationStatus status) override {
ASSERT_FALSE(serialization_reported_end_of_data_);
serialized_contents_.append(data.data(), data.size());
if (status == WebFrameSerializerClient::kCurrentFrameIsFinished)
serialization_reported_end_of_data_ = true;
}
WebView* GetWebView() { return GetMainFrame()->View(); }
WebLocalFrame* GetMainFrame() {
return WebFrame::FromFrameToken(main_frame_token_)->ToWebLocalFrame();
}
WebLocalFrame* FindSubFrameByURL(const GURL& url) {
for (WebFrame* frame = GetWebView()->MainFrame(); frame;
frame = frame->TraverseNext()) {
DCHECK(frame->IsWebLocalFrame());
if (GURL(frame->ToWebLocalFrame()->GetDocument().Url()) == url)
return frame->ToWebLocalFrame();
}
return nullptr;
}
void LoadContents(const std::string& contents, const GURL& base_url) {
TestNavigationObserver navigation_observer(shell()->web_contents(), 1);
shell()->LoadDataWithBaseURL(
shell()->web_contents()->GetPrimaryMainFrame()->GetLastCommittedURL(),
contents, base_url);
navigation_observer.Wait();
main_frame_token_ =
shell()->web_contents()->GetPrimaryMainFrame()->GetFrameToken();
}
class SingleLinkRewritingDelegate
: public WebFrameSerializer::LinkRewritingDelegate {
public:
SingleLinkRewritingDelegate(const WebURL& url, const WebString& localPath)
: url_(url), local_path_(localPath) {}
bool RewriteFrameSource(WebFrame* frame,
WebString* rewritten_link) override {
return false;
}
bool RewriteLink(const WebURL& url, WebString* rewritten_link) override {
if (url != url_)
return false;
*rewritten_link = local_path_;
return true;
}
private:
const WebURL url_;
const WebString local_path_;
};
void SerializeDomForURL(const GURL& frame_url) {
SerializeDomForURL(frame_url, false);
}
void SerializeDomForURL(const GURL& frame_url, bool save_with_empty_url) {
WebFrame* web_frame = FindSubFrameByURL(frame_url);
ASSERT_TRUE(web_frame != nullptr);
WebString file_path = WebString::FromUTF8("c:\\dummy.htm");
SingleLinkRewritingDelegate delegate(frame_url, file_path);
bool result = WebFrameSerializer::Serialize(
web_frame->ToWebLocalFrame(), this, &delegate, save_with_empty_url);
ASSERT_TRUE(result);
}
bool serialization_reported_end_of_data() const {
return serialization_reported_end_of_data_;
}
const std::string& serialized_contents() const {
return serialized_contents_;
}
private:
blink::LocalFrameToken main_frame_token_;
std::string serialized_contents_;
bool serialization_reported_end_of_data_ = false;
};
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
DISABLED_SerializeHTMLDOMWithDocType) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_1.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(HasDocType(doc));
SerializeDomForURL(file_url);
}));
ASSERT_TRUE(serialization_reported_end_of_data());
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(HasDocType(doc));
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeHTMLDOMWithoutDocType) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_2.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(!HasDocType(doc));
SerializeDomForURL(file_url);
}));
ASSERT_TRUE(serialization_reported_end_of_data());
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(!HasDocType(doc));
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeXMLDocWithBuiltInEntities) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "note.html");
base::FilePath xml_file_path = GetTestFilePath("dom_serializer", "note.xml");
std::string original_contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(xml_file_path, &original_contents));
}
GURL file_url = net::FilePathToFileURL(page_file_path);
GURL xml_file_url = net::FilePathToFileURL(xml_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
SerializeDomForURL(xml_file_url);
ASSERT_TRUE(serialization_reported_end_of_data());
ASSERT_EQ(original_contents, serialized_contents());
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeHTMLDOMWithAddingMOTW) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_2.htm");
std::string original_contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(page_file_path, &original_contents));
}
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
std::string motw_declaration =
WebFrameSerializer::GenerateMarkOfTheWebDeclaration(file_url).Utf8();
ASSERT_FALSE(motw_declaration.empty());
ASSERT_FALSE(base::Contains(original_contents, motw_declaration));
SerializeDomForURL(file_url, false);
ASSERT_TRUE(serialization_reported_end_of_data());
ASSERT_TRUE(base::Contains(serialized_contents(), motw_declaration));
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeOffTheRecordHTMLDOMWithAddingMOTW) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_2.htm");
std::string original_contents;
{
base::ScopedAllowBlockingForTesting allow_blocking;
ASSERT_TRUE(base::ReadFileToString(page_file_path, &original_contents));
}
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
GURL frame_url = GURL("about:internet");
std::string motw_declaration =
WebFrameSerializer::GenerateMarkOfTheWebDeclaration(frame_url).Utf8();
ASSERT_FALSE(motw_declaration.empty());
ASSERT_TRUE(!base::Contains(original_contents, motw_declaration));
SerializeDomForURL(file_url, true);
ASSERT_TRUE(serialization_reported_end_of_data());
ASSERT_TRUE(base::Contains(serialized_contents(), motw_declaration));
}));
}
IN_PROC_BROWSER_TEST_F(
MAYBE_DomSerializerTests,
DISABLED_SerializeHTMLDOMWithNoMetaCharsetInOriginalDoc) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_1.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
WebElementCollection meta_elements =
head_element.GetElementsByHTMLTagName("meta");
for (WebElement element = meta_elements.FirstItem(); !element.IsNull();
element = meta_elements.NextItem()) {
ASSERT_TRUE(element.To<WebMetaElement>().ComputeEncoding().IsEmpty());
}
SerializeDomForURL(file_url);
}));
ASSERT_TRUE(serialization_reported_end_of_data());
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
ASSERT_TRUE(!head_element.FirstChild().IsNull());
ASSERT_TRUE(head_element.FirstChild().IsElementNode());
WebMetaElement meta_element =
head_element.FirstChild().To<WebMetaElement>();
ASSERT_EQ(meta_element.ComputeEncoding(),
web_frame->GetDocument().Encoding());
WebElementCollection meta_elements =
head_element.GetElementsByHTMLTagName("meta");
for (WebElement element = meta_elements.FirstItem(); !element.IsNull();
element = meta_elements.NextItem()) {
if (element == meta_element)
continue;
ASSERT_TRUE(element.To<WebMetaElement>().ComputeEncoding().IsEmpty());
}
}));
}
IN_PROC_BROWSER_TEST_F(
MAYBE_DomSerializerTests,
DISABLED_SerializeHTMLDOMWithMultipleMetaCharsetInOriginalDoc) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "youtube_2.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
int charset_declaration_count = 0;
WebElementCollection meta_elements =
head_element.GetElementsByHTMLTagName("meta");
for (WebElement element = meta_elements.FirstItem(); !element.IsNull();
element = meta_elements.NextItem()) {
if (!element.To<WebMetaElement>().ComputeEncoding().IsEmpty())
++charset_declaration_count;
}
ASSERT_GT(charset_declaration_count, 1);
SerializeDomForURL(file_url);
}));
ASSERT_TRUE(serialization_reported_end_of_data());
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
ASSERT_TRUE(!head_element.FirstChild().IsNull());
ASSERT_TRUE(head_element.FirstChild().IsElementNode());
WebMetaElement meta_element =
head_element.FirstChild().To<WebMetaElement>();
ASSERT_EQ(meta_element.ComputeEncoding(),
web_frame->GetDocument().Encoding());
WebElementCollection meta_elements =
head_element.GetElementsByHTMLTagName("meta");
for (WebElement element = meta_elements.FirstItem(); !element.IsNull();
element = meta_elements.NextItem()) {
if (element == meta_element)
continue;
ASSERT_TRUE(element.To<WebMetaElement>().ComputeEncoding().IsEmpty());
}
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeHTMLDOMWithEntitiesInText) {
EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl(".", "simple_page.html")));
base::FilePath page_file_path = GetTestFilePath(
"dom_serializer", "dom_serializer/htmlentities_in_text.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
static const char* const original_contents =
"<html><body>&<>\"\'</body></html>";
LoadContents(original_contents, file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement body_ele = doc.Body();
ASSERT_TRUE(!body_ele.IsNull());
WebNode text_node = body_ele.FirstChild();
ASSERT_TRUE(text_node.IsTextNode());
ASSERT_EQ(text_node.NodeValue().Utf8(), "&<>\"\'");
SerializeDomForURL(file_url);
ASSERT_TRUE(serialization_reported_end_of_data());
std::string original_str =
WebFrameSerializer::GenerateMarkOfTheWebDeclaration(file_url).Utf8();
original_str += original_contents;
if (!doc.Head().IsNull()) {
WebString encoding = web_frame->GetDocument().Encoding();
std::string htmlTag("<html>");
std::string::size_type pos = original_str.find(htmlTag);
ASSERT_NE(std::string::npos, pos);
pos += htmlTag.length();
std::string head_part("<head>");
head_part +=
WebFrameSerializer::GenerateMetaCharsetDeclaration(encoding).Utf8();
head_part += "</head>";
original_str.insert(pos, head_part);
}
ASSERT_EQ(original_str, serialized_contents());
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeHTMLDOMWithEntitiesInAttributeValue) {
EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl(".", "simple_page.html")));
base::FilePath page_file_path = GetTestFilePath(
"dom_serializer", "dom_serializer/htmlentities_in_attribute_value.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
static const char* const original_contents =
"<html><body title=\"&<>"\"></body></html>";
LoadContents(original_contents, file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement body_ele = doc.Body();
ASSERT_TRUE(!body_ele.IsNull());
WebString value = body_ele.GetAttribute("title");
ASSERT_EQ(value.Utf8(), "&<>\"");
SerializeDomForURL(file_url);
ASSERT_TRUE(serialization_reported_end_of_data());
std::string original_str =
WebFrameSerializer::GenerateMarkOfTheWebDeclaration(file_url).Utf8();
original_str += original_contents;
if (!doc.IsNull()) {
WebString encoding = web_frame->GetDocument().Encoding();
std::string htmlTag("<html>");
std::string::size_type pos = original_str.find(htmlTag);
ASSERT_NE(std::string::npos, pos);
pos += htmlTag.length();
std::string head_part("<head>");
head_part +=
WebFrameSerializer::GenerateMetaCharsetDeclaration(encoding).Utf8();
head_part += "</head>";
original_str.insert(pos, head_part);
}
ASSERT_EQ(original_str, serialized_contents());
}));
}
#if BUILDFLAG(IS_LINUX)
#define MAYBE_SerializeHTMLDOMWithNonStandardEntities \
DISABLED_SerializeHTMLDOMWithNonStandardEntities
#else
#define MAYBE_SerializeHTMLDOMWithNonStandardEntities \
SerializeHTMLDOMWithNonStandardEntities
#endif
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
MAYBE_SerializeHTMLDOMWithNonStandardEntities) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "nonstandard_htmlentities.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement body_element = doc.Body();
static const wchar_t parsed_value[] = {'%', 0x2285, 0x00b9, '\'', 0};
WebString value = body_element.GetAttribute("title");
WebString content = blink::TestWebFrameContentDumper::DumpWebViewAsText(
web_frame->View(), 1024);
ASSERT_TRUE(base::UTF16ToWide(value.Utf16()) == parsed_value);
ASSERT_TRUE(base::UTF16ToWide(content.Utf16()) == parsed_value);
SerializeDomForURL(file_url);
ASSERT_TRUE(serialization_reported_end_of_data());
ASSERT_EQ(std::string::npos, serialized_contents().find("%"));
ASSERT_EQ(std::string::npos, serialized_contents().find("⊅"));
ASSERT_EQ(std::string::npos, serialized_contents().find("¹"));
ASSERT_EQ(std::string::npos, serialized_contents().find("'"));
}));
}
#if BUILDFLAG(IS_LINUX)
#define MAYBE_SerializeHTMLDOMWithBaseTag DISABLED_SerializeHTMLDOMWithBaseTag
#else
#define MAYBE_SerializeHTMLDOMWithBaseTag SerializeHTMLDOMWithBaseTag
#endif
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
MAYBE_SerializeHTMLDOMWithBaseTag) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "html_doc_has_base_tag.htm");
base::FilePath dir_name = page_file_path.DirName();
GURL path_dir_url = net::FilePathToFileURL(dir_name.AsEndingWithSeparator());
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
EXPECT_TRUE(NavigateToURL(shell(), file_url));
const int kTotalBaseTagCountInTestFile = 2;
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElementCollection all = doc.All();
int original_base_tag_count = 0;
for (WebElement element = all.FirstItem(); !element.IsNull();
element = all.NextItem()) {
if (element.HasHTMLTagName("base")) {
original_base_tag_count++;
} else {
WebString value =
blink::GetSubResourceLinkFromElementForTesting(element);
if (value.IsNull() && element.HasHTMLTagName("a")) {
value = element.GetAttribute("href");
if (value.IsEmpty())
value = WebString();
}
if (!value.IsNull()) {
GURL link(value.Utf8());
ASSERT_TRUE(link.GetScheme().empty());
}
}
}
ASSERT_EQ(original_base_tag_count, kTotalBaseTagCountInTestFile);
GURL original_base_url(doc.BaseURL());
ASSERT_NE(original_base_url, path_dir_url);
SerializeDomForURL(file_url);
}));
ASSERT_TRUE(serialization_reported_end_of_data());
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElementCollection all = doc.All();
int new_base_tag_count = 0;
for (WebNode node = all.FirstItem(); !node.IsNull();
node = all.NextItem()) {
if (!node.IsElementNode())
continue;
WebElement element = node.To<WebElement>();
if (element.HasHTMLTagName("base")) {
new_base_tag_count++;
} else {
WebString value =
blink::GetSubResourceLinkFromElementForTesting(element);
if (value.IsNull() && element.HasHTMLTagName("a")) {
value = element.GetAttribute("href");
if (value.IsEmpty())
value = WebString();
}
if (!value.IsNull()) {
GURL link(std::string(value.Utf8()));
ASSERT_FALSE(link.GetScheme().empty());
}
}
}
ASSERT_EQ(new_base_tag_count, kTotalBaseTagCountInTestFile + 1);
GURL new_base_url(doc.BaseURL());
ASSERT_EQ(new_base_url, path_dir_url);
}));
}
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
SerializeHTMLDOMWithEmptyHead) {
EXPECT_TRUE(NavigateToURL(shell(), GetTestUrl(".", "simple_page.html")));
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "empty_head.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
ASSERT_TRUE(file_url.SchemeIsFile());
static const char* const empty_head_contents =
"<html><head></head><body>hello world</body></html>";
LoadContents(empty_head_contents, file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
ASSERT_TRUE(head_element.FirstChild().IsNull());
SerializeDomForURL(file_url);
ASSERT_TRUE(serialization_reported_end_of_data());
}));
LoadContents(serialized_contents(), file_url);
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
ASSERT_TRUE(doc.IsHTMLDocument());
WebElement head_element = doc.Head();
ASSERT_TRUE(!head_element.IsNull());
ASSERT_TRUE(!head_element.FirstChild().IsNull());
ASSERT_TRUE(head_element.FirstChild().IsElementNode());
ASSERT_TRUE(head_element.FirstChild().NextSibling().IsNull());
WebMetaElement meta_element =
head_element.FirstChild().To<WebMetaElement>();
ASSERT_EQ(meta_element.ComputeEncoding(),
web_frame->GetDocument().Encoding());
WebElement body_element = doc.Body();
ASSERT_TRUE(!body_element.IsNull());
WebNode text_node = body_element.FirstChild();
ASSERT_TRUE(text_node.IsTextNode());
ASSERT_EQ("hello world", text_node.NodeValue());
}));
}
#if BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER)
#define MAYBE_SubResourceForElementsInNonHTMLNamespace \
DISABLED_SubResourceForElementsInNonHTMLNamespace
#else
#define MAYBE_SubResourceForElementsInNonHTMLNamespace \
SubResourceForElementsInNonHTMLNamespace
#endif
IN_PROC_BROWSER_TEST_F(MAYBE_DomSerializerTests,
MAYBE_SubResourceForElementsInNonHTMLNamespace) {
base::FilePath page_file_path =
GetTestFilePath("dom_serializer", "non_html_namespace.htm");
GURL file_url = net::FilePathToFileURL(page_file_path);
EXPECT_TRUE(NavigateToURL(shell(), file_url));
PostTaskToInProcessRendererAndWait(base::BindLambdaForTesting([=, this] {
WebLocalFrame* web_frame = FindSubFrameByURL(file_url);
ASSERT_TRUE(web_frame != nullptr);
WebDocument doc = web_frame->GetDocument();
WebNode lastNodeInBody = doc.Body().LastChild();
ASSERT_TRUE(lastNodeInBody.IsElementNode());
WebString uri = blink::GetSubResourceLinkFromElementForTesting(
lastNodeInBody.To<WebElement>());
EXPECT_TRUE(uri.IsNull());
}));
}
}