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 |