| Index: headless/public/util/dom_tree_extractor_browsertest.cc
|
| diff --git a/headless/public/util/dom_tree_extractor_browsertest.cc b/headless/public/util/dom_tree_extractor_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f5dc6845577abcdfdd23d41263adceeb413561b3
|
| --- /dev/null
|
| +++ b/headless/public/util/dom_tree_extractor_browsertest.cc
|
| @@ -0,0 +1,180 @@
|
| +// 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 "headless/public/util/dom_tree_extractor.h"
|
| +
|
| +#include <memory>
|
| +#include "base/json/json_writer.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "content/public/browser/render_widget_host_view.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/test/browser_test.h"
|
| +#include "headless/lib/browser/headless_web_contents_impl.h"
|
| +#include "headless/public/domains/browser.h"
|
| +#include "headless/public/domains/emulation.h"
|
| +#include "headless/public/domains/network.h"
|
| +#include "headless/public/domains/page.h"
|
| +#include "headless/public/headless_browser.h"
|
| +#include "headless/public/headless_devtools_client.h"
|
| +#include "headless/public/headless_devtools_target.h"
|
| +#include "headless/test/headless_browser_test.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace headless {
|
| +
|
| +class DomTreeExtractorBrowserTest : public HeadlessAsyncDevTooledBrowserTest,
|
| + public page::Observer {
|
| + public:
|
| + void RunDevTooledTest() override {
|
| + EXPECT_TRUE(embedded_test_server()->Start());
|
| + devtools_client_->GetPage()->AddObserver(this);
|
| + devtools_client_->GetPage()->Enable();
|
| + devtools_client_->GetPage()->Navigate(
|
| + embedded_test_server()->GetURL("/dom_tree_test.html").spec());
|
| + }
|
| +
|
| + void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
|
| + devtools_client_->GetPage()->RemoveObserver(this);
|
| +
|
| + extractor_.reset(new DomTreeExtractor(devtools_client_.get()));
|
| + extractor_->ExtractDom(
|
| + base::Bind(&DomTreeExtractorBrowserTest::OnDomTreeExtracted,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void OnDomTreeExtracted(
|
| + std::vector<std::unique_ptr<base::DictionaryValue>> dom_tree) {
|
| + std::vector<std::string> expected_results = {
|
| + "{'baseURL':'http://127.0.0.1/dom_tree_test.html','childIndicies':[1],"
|
| + "'documentURL':'http://127.0.0.1/dom_tree_test.html','localName':'',"
|
| + "'nodeId':1,'nodeName':'#document','nodeType':9,'nodeValue':'',"
|
| + "'xmlVersion':''}",
|
| +
|
| + "{'attributes':[],'childIndicies':[2,5],'frameId':'?','localName'"
|
| + ":'html','nodeId':2,'nodeName':'HTML','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':600.0,'width':800.0,'x':0.0,'"
|
| + "y':0.0},'childIndicies':[3],'localName':'head','nodeId':3,'nodeName':'"
|
| + "HEAD','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':584.0,'width':784.0,'x':8.0,'"
|
| + "y':8.0},'childIndicies':[4],'localName':'title','nodeId':5,'nodeName':"
|
| + "'TITLE','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'boundingBox':{'height':226.0,'width':784.0,'x':8.0,'y':8.0},'"
|
| + "localName':'','nodeId':6,'nodeName':'#text','nodeType':3,'nodeValue':'"
|
| + "Hello world!'}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':600.0,'width':800.0,'x':0.0,'"
|
| + "y':0.0},'childIndicies':[6],'localName':'body','nodeId':4,'nodeName':'"
|
| + "BODY','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':['id','id1'],'boundingBox':{'height':17.0,'width':73.0,'"
|
| + "x':8.0,'y':198.0},'childIndicies':[7,8,15],'inlineTextNodes':[{'"
|
| + "boundingBox':{'height':17.0,'width':72.4375,'x':8.0,'y':198.0},'"
|
| + "numCharacters':11,'startCharacterIndex':1}],'layoutText':'\\nSome "
|
| + "text.\\n','localName':'div','nodeId':7,'nodeName':'DIV','nodeType':1,'"
|
| + "nodeValue':''}",
|
| +
|
| + "{'boundingBox':{'height':200.0,'width':400.0,'x':82.0,'y':10.0},'"
|
| + "localName':'','nodeId':8,'nodeName':'#text','nodeType':3,'nodeValue':'"
|
| + "\\nSome text.\\n'}",
|
| +
|
| + "{'attributes':['src','/iframe.html','width','400','height','200'],"
|
| + "'boundingBox':{'height':171.0,'width':384.0,'x':90.0,'y':18.0},"
|
| + "'childIndicies':[],'contentDocumentIndex':9,'frameId':'?',"
|
| + "'localName':'iframe','nodeId':9,'nodeName':'IFRAME','nodeType':1,"
|
| + "'nodeValue':''}",
|
| +
|
| + "{'baseURL':'http://127.0.0.1/iframe.html','boundingBox':{"
|
| + "'height':37.0,'width':384.0,'x':90.0,'y':18.0},'childIndicies':[10],"
|
| + "'documentURL':'http://127.0.0.1/iframe.html','localName':'',"
|
| + "'nodeId':10,'nodeName':'#document','nodeType':9,'nodeValue':'',"
|
| + "'xmlVersion':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':36.0,'width':308.0,'x':8.0,'"
|
| + "y':8.0},'childIndicies':[11,12],'frameId':'?','inlineTextNodes':"
|
| + "[{'boundingBox':{'height':36.0,'width':307.734375,'x':8.0,'y':8.0},'"
|
| + "numCharacters':22,'startCharacterIndex':0}],'layoutText':'Hello from "
|
| + "the iframe!','localName':'html','nodeId':11,'nodeName':'HTML',"
|
| + "'nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':204.0,'width':405.0,'x':80.0,"
|
| + "'y':8.0},'childIndicies':[],'localName':'head','nodeId':12,'nodeName':"
|
| + "'HEAD','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':0.0,'width':0.0,'x':0.0,'y':"
|
| + "0.0},'childIndicies':[13],'layoutText':'\\n','localName':'body','"
|
| + "nodeId':13,'nodeName':'BODY','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':[],'boundingBox':{'height':18.0,'width':784.0,'x':8.0,'"
|
| + "y':216.0},'childIndicies':[14],'localName':'h1','nodeId':14,'nodeName'"
|
| + ":'H1','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'boundingBox':{'height':18.0,'width':784.0,'x':8.0,'y':216.0},'"
|
| + "localName':'','nodeId':15,'nodeName':'#text','nodeType':3,'nodeValue':"
|
| + "'Hello from the iframe!'}",
|
| +
|
| + "{'attributes':['id','id2'],'boundingBox':{'height':18.0,'width':784.0,"
|
| + "'x':8.0,'y':216.0},'childIndicies':[16],'localName':'div','nodeId':16,"
|
| + "'nodeName':'DIV','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':['id','id3'],'boundingBox':{'height':17.0,'width':53.0,'"
|
| + "x':8.0,'y':216.0},'childIndicies':[17],'localName':'div','nodeId':17,'"
|
| + "nodeName':'DIV','nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'attributes':['id','id4'],'boundingBox':{'height':17.0,'width':53.0,'"
|
| + "x':8.0,'y':216.0},'childIndicies':[18],'inlineTextNodes':[{'"
|
| + "boundingBox':{'height':17.0,'width':52.421875,'x':8.0,'y':216.0},'"
|
| + "numCharacters':7,'startCharacterIndex':0}],'layoutText':'Google!','"
|
| + "localName':'div','nodeId':18,'nodeName':'DIV','nodeType':1,'nodeValue'"
|
| + ":''}",
|
| +
|
| + "{'attributes':['href','https://www.google.com'],'boundingBox':{"
|
| + "'height':0.0,'width':0.0,'x':0.0,'y':0.0},'childIndicies':[19],"
|
| + "'layoutText':'\\n ','localName':'a','nodeId':19,'nodeName':'A',"
|
| + "'nodeType':1,'nodeValue':''}",
|
| +
|
| + "{'localName':'','nodeId':20,'nodeName':'#text','nodeType':3,'"
|
| + "nodeValue':'Google!'}"};
|
| +
|
| + GURL::Replacements replace_port;
|
| + replace_port.SetPortStr("");
|
| + for (size_t i = 0; i < dom_tree.size(); i++) {
|
| + // Frame IDs are random.
|
| + if (dom_tree[i]->HasKey("frameId"))
|
| + dom_tree[i]->SetString("frameId", "?");
|
| +
|
| + // Ports are random.
|
| + std::string url;
|
| + if (dom_tree[i]->GetString("baseURL", &url)) {
|
| + dom_tree[i]->SetString(
|
| + "baseURL", GURL(url).ReplaceComponents(replace_port).spec());
|
| + }
|
| +
|
| + if (dom_tree[i]->GetString("documentURL", &url)) {
|
| + dom_tree[i]->SetString(
|
| + "documentURL", GURL(url).ReplaceComponents(replace_port).spec());
|
| + }
|
| +
|
| + std::string result_json;
|
| + base::JSONWriter::Write(*dom_tree[i], &result_json);
|
| +
|
| + // Not allowed to use C++11 string literals so we make do as best we can.
|
| + base::ReplaceChars(result_json, "\"", "'", &result_json);
|
| +
|
| + ASSERT_LT(i, expected_results.size());
|
| + EXPECT_EQ(expected_results[i], result_json) << " Node # " << i;
|
| + }
|
| +
|
| + FinishAsynchronousTest();
|
| + }
|
| +
|
| + std::unique_ptr<DomTreeExtractor> extractor_;
|
| +};
|
| +
|
| +HEADLESS_ASYNC_DEVTOOLED_TEST_F(DomTreeExtractorBrowserTest);
|
| +
|
| +} // namespace headless
|
|
|