Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1698)

Side by Side Diff: headless/public/util/flat_dom_tree_extractor_browsertest.cc

Issue 2673773002: Adds a FlatDomTreeExtractor to headless (Closed)
Patch Set: Fix DCHECKS Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « headless/public/util/flat_dom_tree_extractor.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "headless/public/util/flat_dom_tree_extractor.h"
6
7 #include <memory>
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/string_util.h"
11 #include "content/public/browser/render_widget_host_view.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/test/browser_test.h"
14 #include "headless/lib/browser/headless_web_contents_impl.h"
15 #include "headless/public/devtools/domains/emulation.h"
16 #include "headless/public/devtools/domains/network.h"
17 #include "headless/public/devtools/domains/page.h"
18 #include "headless/public/headless_browser.h"
19 #include "headless/public/headless_devtools_client.h"
20 #include "headless/public/headless_devtools_target.h"
21 #include "headless/test/headless_browser_test.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "url/gurl.h"
24
25 namespace headless {
26
27 namespace {
28
29 std::string NormaliseJSON(const std::string& json) {
30 std::unique_ptr<base::Value> parsed_json = base::JSONReader::Read(json);
31 DCHECK(parsed_json);
32 std::string normalized_json;
33 base::JSONWriter::WriteWithOptions(
34 *parsed_json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &normalized_json);
35 return normalized_json;
36 }
37
38 } // namespace
39
40 class FlatDomTreeExtractorBrowserTest
41 : public HeadlessAsyncDevTooledBrowserTest,
42 public page::Observer {
43 public:
44 void RunDevTooledTest() override {
45 EXPECT_TRUE(embedded_test_server()->Start());
46 devtools_client_->GetPage()->AddObserver(this);
47 devtools_client_->GetPage()->Enable();
48 devtools_client_->GetPage()->Navigate(
49 embedded_test_server()->GetURL("/dom_tree_test.html").spec());
50 }
51
52 void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
53 devtools_client_->GetPage()->Disable();
54 devtools_client_->GetPage()->RemoveObserver(this);
55
56 extractor_.reset(new FlatDomTreeExtractor(devtools_client_.get()));
57
58 devtools_client_->GetDOM()->Enable();
59 std::vector<std::string> css_whitelist = {
60 "color", "display", "font-style", "font-family",
61 "margin-left", "margin-right", "margin-top", "margin-bottom"};
62 extractor_->ExtractDomTree(
63 css_whitelist,
64 base::Bind(&FlatDomTreeExtractorBrowserTest::OnDomTreeExtracted,
65 base::Unretained(this)));
66 }
67
68 void OnDomTreeExtracted(FlatDomTreeExtractor::DomTree dom_tree) {
69 GURL::Replacements replace_port;
70 replace_port.SetPortStr("");
71
72 std::vector<std::unique_ptr<base::DictionaryValue>> dom_nodes(
73 dom_tree.dom_nodes_.size());
74
75 std::map<int, std::unique_ptr<base::ListValue>> child_lists;
76
77 // For convenience flatten the dom tree into an array.
78 for (size_t i = 0; i < dom_tree.dom_nodes_.size(); i++) {
79 dom::Node* node = const_cast<dom::Node*>(dom_tree.dom_nodes_[i]);
80
81 dom_nodes[i].reset(
82 static_cast<base::DictionaryValue*>(node->Serialize().release()));
83
84 if (node->HasParentId()) {
85 if (child_lists.find(node->GetParentId()) == child_lists.end()) {
86 child_lists.insert(std::make_pair(
87 node->GetParentId(), base::MakeUnique<base::ListValue>()));
88 }
89 child_lists[node->GetParentId()]->AppendInteger(i);
90 }
91 dom_nodes[i]->Remove("children", nullptr);
92
93 // Convert content document pointers into indexes.
94 if (node->HasContentDocument()) {
95 dom_nodes[i]->SetInteger(
96 "contentDocumentIndex",
97 dom_tree
98 .node_id_to_index_[node->GetContentDocument()->GetNodeId()]);
99 dom_nodes[i]->Remove("contentDocument", nullptr);
100 }
101
102 dom_nodes[i]->Remove("childNodeCount", nullptr);
103
104 // Frame IDs are random.
105 if (dom_nodes[i]->HasKey("frameId"))
106 dom_nodes[i]->SetString("frameId", "?");
107
108 // Ports are random.
109 std::string url;
110 if (dom_nodes[i]->GetString("baseURL", &url)) {
111 dom_nodes[i]->SetString(
112 "baseURL", GURL(url).ReplaceComponents(replace_port).spec());
113 }
114
115 if (dom_nodes[i]->GetString("documentURL", &url)) {
116 dom_nodes[i]->SetString(
117 "documentURL", GURL(url).ReplaceComponents(replace_port).spec());
118 }
119 }
120
121 for (auto& pair : child_lists) {
122 dom_nodes[dom_tree.node_id_to_index_[pair.first]]->Set(
123 "childIndices", std::move(pair.second));
124 }
125
126 // Merge LayoutTreeNode data into the dictionaries.
127 for (const css::LayoutTreeNode* layout_node : dom_tree.layout_tree_nodes_) {
128 auto it = dom_tree.node_id_to_index_.find(layout_node->GetNodeId());
129 ASSERT_TRUE(it != dom_tree.node_id_to_index_.end());
130
131 base::DictionaryValue* node_dict = dom_nodes[it->second].get();
132 node_dict->Set("boundingBox", layout_node->GetBoundingBox()->Serialize());
133
134 if (layout_node->HasLayoutText())
135 node_dict->SetString("layoutText", layout_node->GetLayoutText());
136
137 if (layout_node->HasStyleIndex())
138 node_dict->SetInteger("styleIndex", layout_node->GetStyleIndex());
139
140 if (layout_node->HasInlineTextNodes()) {
141 std::unique_ptr<base::ListValue> inline_text_nodes(
142 new base::ListValue());
143 for (const std::unique_ptr<css::InlineTextBox>& inline_text_box :
144 *layout_node->GetInlineTextNodes()) {
145 size_t index = inline_text_nodes->GetSize();
146 inline_text_nodes->Set(index, inline_text_box->Serialize());
147 }
148 node_dict->Set("inlineTextNodes", std::move(inline_text_nodes));
149 }
150 }
151
152 std::vector<std::unique_ptr<base::DictionaryValue>> computed_styles(
153 dom_tree.computed_styles_.size());
154
155 for (size_t i = 0; i < dom_tree.computed_styles_.size(); i++) {
156 std::unique_ptr<base::DictionaryValue> style(new base::DictionaryValue());
157 for (const auto& style_property :
158 *dom_tree.computed_styles_[i]->GetProperties()) {
159 style->SetString(style_property->GetName(), style_property->GetValue());
160 }
161 computed_styles[i] = std::move(style);
162 }
163
164 const std::vector<std::string> expected_dom_nodes = {
165 R"raw_string({
166 "backendNodeId": 7,
167 "localName": "",
168 "nodeId": 5,
169 "nodeName": "#text",
170 "nodeType": 3,
171 "nodeValue": "Hello world!",
172 "parentId": 4
173 })raw_string",
174
175 R"raw_string({
176 "attributes": [ ],
177 "backendNodeId": 6,
178 "childIndices": [ 0 ],
179 "localName": "title",
180 "nodeId": 4,
181 "nodeName": "TITLE",
182 "nodeType": 1,
183 "nodeValue": "",
184 "parentId": 3
185 })raw_string",
186
187 R"raw_string({
188 "attributes": [ "href", "dom_tree_test.css", "rel", "stylesheet",
189 "type", "text/css" ],
190 "backendNodeId": 8,
191 "localName": "link",
192 "nodeId": 6,
193 "nodeName": "LINK",
194 "nodeType": 1,
195 "nodeValue": "",
196 "parentId": 3
197 })raw_string",
198
199 R"raw_string({
200 "attributes": [ ],
201 "backendNodeId": 5,
202 "childIndices": [ 1, 2 ],
203 "localName": "head",
204 "nodeId": 3,
205 "nodeName": "HEAD",
206 "nodeType": 1,
207 "nodeValue": "",
208 "parentId": 2
209 })raw_string",
210
211 R"raw_string({
212 "backendNodeId": 12,
213 "boundingBox": {
214 "height": 32.0,
215 "width": 320.0,
216 "x": 8.0,
217 "y": 8.0
218 },
219 "inlineTextNodes": [ {
220 "boundingBox": {
221 "height": 32.0,
222 "width": 320.0,
223 "x": 8.0,
224 "y": 8.0
225 },
226 "numCharacters": 10,
227 "startCharacterIndex": 0
228 } ],
229 "layoutText": "Some text.",
230 "localName": "",
231 "nodeId": 10,
232 "nodeName": "#text",
233 "nodeType": 3,
234 "nodeValue": "Some text.",
235 "parentId": 9,
236 "styleIndex": 2
237 })raw_string",
238
239 R"raw_string({
240 "attributes": [ "class", "red" ],
241 "backendNodeId": 11,
242 "boundingBox": {
243 "height": 32.0,
244 "width": 784.0,
245 "x": 8.0,
246 "y": 8.0
247 },
248 "childIndices": [ 4 ],
249 "localName": "h1",
250 "nodeId": 9,
251 "nodeName": "H1",
252 "nodeType": 1,
253 "nodeValue": "",
254 "parentId": 8,
255 "styleIndex": 2
256 })raw_string",
257
258 R"raw_string({
259 "attributes": [ ],
260 "backendNodeId": 16,
261 "localName": "head",
262 "nodeId": 14,
263 "nodeName": "HEAD",
264 "nodeType": 1,
265 "nodeValue": "",
266 "parentId": 13
267 })raw_string",
268
269 R"raw_string({
270 "backendNodeId": 19,
271 "boundingBox": {
272 "height": 36.0,
273 "width": 308.0,
274 "x": 8.0,
275 "y": 8.0
276 },
277 "inlineTextNodes": [ {
278 "boundingBox": {
279 "height": 36.0,
280 "width": 307.734375,
281 "x": 8.0,
282 "y": 8.0
283 },
284 "numCharacters": 22,
285 "startCharacterIndex": 0
286 } ],
287 "layoutText": "Hello from the iframe!",
288 "localName": "",
289 "nodeId": 17,
290 "nodeName": "#text",
291 "nodeType": 3,
292 "nodeValue": "Hello from the iframe!",
293 "parentId": 16,
294 "styleIndex": 5
295 })raw_string",
296
297 R"raw_string({
298 "attributes": [ ],
299 "backendNodeId": 18,
300 "boundingBox": {
301 "height": 37.0,
302 "width": 384.0,
303 "x": 18.0,
304 "y": 71.0
305 },
306 "childIndices": [ 7 ],
307 "localName": "h1",
308 "nodeId": 16,
309 "nodeName": "H1",
310 "nodeType": 1,
311 "nodeValue": "",
312 "parentId": 15,
313 "styleIndex": 5
314 })raw_string",
315
316 R"raw_string({
317 "attributes": [ ],
318 "backendNodeId": 17,
319 "boundingBox": {
320 "height": 171.0,
321 "width": 384.0,
322 "x": 18.0,
323 "y": 71.0
324 },
325 "childIndices": [ 8 ],
326 "localName": "body",
327 "nodeId": 15,
328 "nodeName": "BODY",
329 "nodeType": 1,
330 "nodeValue": "",
331 "parentId": 13,
332 "styleIndex": 4
333 })raw_string",
334
335 R"raw_string({
336 "attributes": [ ],
337 "backendNodeId": 15,
338 "boundingBox": {
339 "height": 200.0,
340 "width": 400.0,
341 "x": 10.0,
342 "y": 63.0
343 },
344 "childIndices": [ 6, 9 ],
345 "frameId": "?",
346 "localName": "html",
347 "nodeId": 13,
348 "nodeName": "HTML",
349 "nodeType": 1,
350 "nodeValue": "",
351 "parentId": 12,
352 "styleIndex": 3
353 })raw_string",
354
355 R"raw_string({
356 "attributes": [ "src", "/iframe.html", "width", "400", "height",
357 "200" ],
358 "backendNodeId": 13,
359 "boundingBox": {
360 "height": 205.0,
361 "width": 404.0,
362 "x": 8.0,
363 "y": 61.0
364 },
365 "contentDocumentIndex": 12,
366 "frameId": "?",
367 "localName": "iframe",
368 "nodeId": 11,
369 "nodeName": "IFRAME",
370 "nodeType": 1,
371 "nodeValue": "",
372 "parentId": 8,
373 "styleIndex": 6
374 })raw_string",
375
376 R"raw_string({
377 "backendNodeId": 14,
378 "baseURL": "http://127.0.0.1/iframe.html",
379 "childIndices": [ 10 ],
380 "documentURL": "http://127.0.0.1/iframe.html",
381 "localName": "",
382 "nodeId": 12,
383 "nodeName": "#document",
384 "nodeType": 9,
385 "nodeValue": "",
386 "xmlVersion": ""
387 })raw_string",
388
389 R"raw_string({
390 "backendNodeId": 24,
391 "boundingBox": {
392 "height": 17.0,
393 "width": 112.0,
394 "x": 8.0,
395 "y": 265.0
396 },
397 "inlineTextNodes": [ {
398 "boundingBox": {
399 "height": 16.0,
400 "width": 112.0,
401 "x": 8.0,
402 "y": 265.4375
403 },
404 "numCharacters": 7,
405 "startCharacterIndex": 0
406 } ],
407 "layoutText": "Google!",
408 "localName": "",
409 "nodeId": 22,
410 "nodeName": "#text",
411 "nodeType": 3,
412 "nodeValue": "Google!",
413 "parentId": 21,
414 "styleIndex": 7
415 })raw_string",
416
417 R"raw_string({
418 "attributes": [ "href", "https://www.google.com" ],
419 "backendNodeId": 23,
420 "boundingBox": {
421 "height": 17.0,
422 "width": 112.0,
423 "x": 8.0,
424 "y": 265.0
425 },
426 "childIndices": [ 13 ],
427 "localName": "a",
428 "nodeId": 21,
429 "nodeName": "A",
430 "nodeType": 1,
431 "nodeValue": "",
432 "parentId": 20,
433 "styleIndex": 7
434 })raw_string",
435
436 R"raw_string({
437 "backendNodeId": 26,
438 "boundingBox": {
439 "height": 17.0,
440 "width": 192.0,
441 "x": 8.0,
442 "y": 297.0
443 },
444 "inlineTextNodes": [ {
445 "boundingBox": {
446 "height": 16.0,
447 "width": 192.0,
448 "x": 8.0,
449 "y": 297.4375
450 },
451 "numCharacters": 12,
452 "startCharacterIndex": 0
453 } ],
454 "layoutText": "A paragraph!",
455 "localName": "",
456 "nodeId": 24,
457 "nodeName": "#text",
458 "nodeType": 3,
459 "nodeValue": "A paragraph!",
460 "parentId": 23,
461 "styleIndex": 8
462 })raw_string",
463
464 R"raw_string({
465 "attributes": [ ],
466 "backendNodeId": 25,
467 "boundingBox": {
468 "height": 17.0,
469 "width": 784.0,
470 "x": 8.0,
471 "y": 297.0
472 },
473 "childIndices": [ 15 ],
474 "localName": "p",
475 "nodeId": 23,
476 "nodeName": "P",
477 "nodeType": 1,
478 "nodeValue": "",
479 "parentId": 20,
480 "styleIndex": 8
481 })raw_string",
482
483 R"raw_string({
484 "attributes": [ ],
485 "backendNodeId": 27,
486 "boundingBox": {
487 "height": 0.0,
488 "width": 0.0,
489 "x": 0.0,
490 "y": 0.0
491 },
492 "inlineTextNodes": [ {
493 "boundingBox": {
494 "height": 16.0,
495 "width": 0.0,
496 "x": 8.0,
497 "y": 329.4375
498 },
499 "numCharacters": 1,
500 "startCharacterIndex": 0
501 } ],
502 "layoutText": "\n",
503 "localName": "br",
504 "nodeId": 25,
505 "nodeName": "BR",
506 "nodeType": 1,
507 "nodeValue": "",
508 "parentId": 20,
509 "styleIndex": 6
510 })raw_string",
511
512 R"raw_string({
513 "backendNodeId": 29,
514 "boundingBox": {
515 "height": 17.0,
516 "width": 80.0,
517 "x": 8.0,
518 "y": 345.0
519 },
520 "inlineTextNodes": [ {
521 "boundingBox": {
522 "height": 16.0,
523 "width": 80.0,
524 "x": 8.0,
525 "y": 345.4375
526 },
527 "numCharacters": 5,
528 "startCharacterIndex": 0
529 } ],
530 "layoutText": "Some ",
531 "localName": "",
532 "nodeId": 27,
533 "nodeName": "#text",
534 "nodeType": 3,
535 "nodeValue": "Some ",
536 "parentId": 26,
537 "styleIndex": 9
538 })raw_string",
539
540 R"raw_string({
541 "backendNodeId": 31,
542 "boundingBox": {
543 "height": 17.0,
544 "width": 80.0,
545 "x": 88.0,
546 "y": 345.0
547 },
548 "inlineTextNodes": [ {
549 "boundingBox": {
550 "height": 16.0,
551 "width": 80.0,
552 "x": 88.0,
553 "y": 345.4375
554 },
555 "numCharacters": 5,
556 "startCharacterIndex": 0
557 } ],
558 "layoutText": "green",
559 "localName": "",
560 "nodeId": 29,
561 "nodeName": "#text",
562 "nodeType": 3,
563 "nodeValue": "green",
564 "parentId": 28,
565 "styleIndex": 10
566 })raw_string",
567
568 R"raw_string({
569 "attributes": [ ],
570 "backendNodeId": 30,
571 "boundingBox": {
572 "height": 17.0,
573 "width": 80.0,
574 "x": 88.0,
575 "y": 345.0
576 },
577 "childIndices": [ 19 ],
578 "localName": "em",
579 "nodeId": 28,
580 "nodeName": "EM",
581 "nodeType": 1,
582 "nodeValue": "",
583 "parentId": 26,
584 "styleIndex": 10
585 })raw_string",
586
587 R"raw_string({
588 "backendNodeId": 32,
589 "boundingBox": {
590 "height": 17.0,
591 "width": 128.0,
592 "x": 168.0,
593 "y": 345.0
594 },
595 "inlineTextNodes": [ {
596 "boundingBox": {
597 "height": 16.0,
598 "width": 128.0,
599 "x": 168.0,
600 "y": 345.4375
601 },
602 "numCharacters": 8,
603 "startCharacterIndex": 0
604 } ],
605 "layoutText": " text...",
606 "localName": "",
607 "nodeId": 30,
608 "nodeName": "#text",
609 "nodeType": 3,
610 "nodeValue": " text...",
611 "parentId": 26,
612 "styleIndex": 9
613 })raw_string",
614
615 R"raw_string({
616 "attributes": [ "class", "green" ],
617 "backendNodeId": 28,
618 "boundingBox": {
619 "height": 17.0,
620 "width": 784.0,
621 "x": 8.0,
622 "y": 345.0
623 },
624 "childIndices": [ 18, 20, 21 ],
625 "localName": "div",
626 "nodeId": 26,
627 "nodeName": "DIV",
628 "nodeType": 1,
629 "nodeValue": "",
630 "parentId": 20,
631 "styleIndex": 9
632 })raw_string",
633
634 R"raw_string({
635 "attributes": [ "id", "id4" ],
636 "backendNodeId": 22,
637 "boundingBox": {
638 "height": 97.0,
639 "width": 784.0,
640 "x": 8.0,
641 "y": 265.0
642 },
643 "childIndices": [ 14, 16, 17, 22 ],
644 "localName": "div",
645 "nodeId": 20,
646 "nodeName": "DIV",
647 "nodeType": 1,
648 "nodeValue": "",
649 "parentId": 19,
650 "styleIndex": 0
651 })raw_string",
652
653 R"raw_string({
654 "attributes": [ "id", "id3" ],
655 "backendNodeId": 21,
656 "boundingBox": {
657 "height": 97.0,
658 "width": 784.0,
659 "x": 8.0,
660 "y": 265.0
661 },
662 "childIndices": [ 23 ],
663 "localName": "div",
664 "nodeId": 19,
665 "nodeName": "DIV",
666 "nodeType": 1,
667 "nodeValue": "",
668 "parentId": 18,
669 "styleIndex": 0
670 })raw_string",
671
672 R"raw_string({
673 "attributes": [ "id", "id2" ],
674 "backendNodeId": 20,
675 "boundingBox": {
676 "height": 97.0,
677 "width": 784.0,
678 "x": 8.0,
679 "y": 265.0
680 },
681 "childIndices": [ 24 ],
682 "localName": "div",
683 "nodeId": 18,
684 "nodeName": "DIV",
685 "nodeType": 1,
686 "nodeValue": "",
687 "parentId": 8,
688 "styleIndex": 0
689 })raw_string",
690
691 R"raw_string({
692 "attributes": [ "id", "id1" ],
693 "backendNodeId": 10,
694 "boundingBox": {
695 "height": 354.0,
696 "width": 784.0,
697 "x": 8.0,
698 "y": 8.0
699 },
700 "childIndices": [ 5, 11, 25 ],
701 "localName": "div",
702 "nodeId": 8,
703 "nodeName": "DIV",
704 "nodeType": 1,
705 "nodeValue": "",
706 "parentId": 7,
707 "styleIndex": 0
708 })raw_string",
709
710 R"raw_string({
711 "attributes": [ ],
712 "backendNodeId": 9,
713 "boundingBox": {
714 "height": 584.0,
715 "width": 784.0,
716 "x": 8.0,
717 "y": 8.0
718 },
719 "childIndices": [ 26 ],
720 "localName": "body",
721 "nodeId": 7,
722 "nodeName": "BODY",
723 "nodeType": 1,
724 "nodeValue": "",
725 "parentId": 2,
726 "styleIndex": 1
727 })raw_string",
728
729 R"raw_string({
730 "attributes": [ ],
731 "backendNodeId": 4,
732 "boundingBox": {
733 "height": 600.0,
734 "width": 800.0,
735 "x": 0.0,
736 "y": 0.0
737 },
738 "childIndices": [ 3, 27 ],
739 "frameId": "?",
740 "localName": "html",
741 "nodeId": 2,
742 "nodeName": "HTML",
743 "nodeType": 1,
744 "nodeValue": "",
745 "parentId": 1,
746 "styleIndex": 0
747 })raw_string",
748
749 R"raw_string({
750 "backendNodeId": 3,
751 "baseURL": "http://127.0.0.1/dom_tree_test.html",
752 "boundingBox": {
753 "height": 600.0,
754 "width": 800.0,
755 "x": 0.0,
756 "y": 0.0
757 },
758 "childIndices": [ 28 ],
759 "documentURL": "http://127.0.0.1/dom_tree_test.html",
760 "localName": "",
761 "nodeId": 1,
762 "nodeName": "#document",
763 "nodeType": 9,
764 "nodeValue": "",
765 "xmlVersion": ""
766 })raw_string"};
767
768 EXPECT_EQ(expected_dom_nodes.size(), dom_nodes.size());
769
770 for (size_t i = 0; i < dom_nodes.size(); i++) {
771 std::string result_json;
772 base::JSONWriter::WriteWithOptions(
773 *dom_nodes[i], base::JSONWriter::OPTIONS_PRETTY_PRINT, &result_json);
774
775 ASSERT_LT(i, expected_dom_nodes.size());
776 EXPECT_EQ(NormaliseJSON(expected_dom_nodes[i]), result_json) << " Node # "
777 << i;
778 }
779
780 const std::vector<std::string> expected_styles = {
781 R"raw_string({
782 "color": "rgb(0, 0, 0)",
783 "display": "block",
784 "font-family": "ahem",
785 "font-style": "normal",
786 "margin-bottom": "0px",
787 "margin-left": "0px",
788 "margin-right": "0px",
789 "margin-top": "0px"
790 })raw_string",
791
792 R"raw_string({
793 "color": "rgb(0, 0, 0)",
794 "display": "block",
795 "font-family": "ahem",
796 "font-style": "normal",
797 "margin-bottom": "8px",
798 "margin-left": "8px",
799 "margin-right": "8px",
800 "margin-top": "8px"
801 })raw_string",
802
803 R"raw_string({
804 "color": "rgb(255, 0, 0)",
805 "display": "block",
806 "font-family": "ahem",
807 "font-style": "normal",
808 "margin-bottom": "21.44px",
809 "margin-left": "0px",
810 "margin-right": "0px",
811 "margin-top": "21.44px"
812 })raw_string",
813
814 R"raw_string({
815 "color": "rgb(0, 0, 0)",
816 "display": "block",
817 "font-family": "\"Times New Roman\"",
818 "font-style": "normal",
819 "margin-bottom": "0px",
820 "margin-left": "0px",
821 "margin-right": "0px",
822 "margin-top": "0px"
823 })raw_string",
824
825 R"raw_string({
826 "color": "rgb(0, 0, 0)",
827 "display": "block",
828 "font-family": "\"Times New Roman\"",
829 "font-style": "normal",
830 "margin-bottom": "8px",
831 "margin-left": "8px",
832 "margin-right": "8px",
833 "margin-top": "8px"
834 })raw_string",
835
836 R"raw_string({
837 "color": "rgb(0, 0, 0)",
838 "display": "block",
839 "font-family": "\"Times New Roman\"",
840 "font-style": "normal",
841 "margin-bottom": "21.44px",
842 "margin-left": "0px",
843 "margin-right": "0px",
844 "margin-top": "21.44px"
845 })raw_string",
846
847 R"raw_string({
848 "color": "rgb(0, 0, 0)",
849 "display": "inline",
850 "font-family": "ahem",
851 "font-style": "normal",
852 "margin-bottom": "0px",
853 "margin-left": "0px",
854 "margin-right": "0px",
855 "margin-top": "0px"
856 })raw_string",
857
858 R"raw_string({
859 "color": "rgb(0, 0, 238)",
860 "display": "inline",
861 "font-family": "ahem",
862 "font-style": "normal",
863 "margin-bottom": "0px",
864 "margin-left": "0px",
865 "margin-right": "0px",
866 "margin-top": "0px"
867 })raw_string",
868
869 R"raw_string({
870 "color": "rgb(0, 0, 0)",
871 "display": "block",
872 "font-family": "ahem",
873 "font-style": "normal",
874 "margin-bottom": "16px",
875 "margin-left": "0px",
876 "margin-right": "0px",
877 "margin-top": "16px"
878 })raw_string",
879
880 R"raw_string({
881 "color": "rgb(0, 128, 0)",
882 "display": "block",
883 "font-family": "ahem",
884 "font-style": "normal",
885 "margin-bottom": "0px",
886 "margin-left": "0px",
887 "margin-right": "0px",
888 "margin-top": "0px"
889 })raw_string",
890
891 R"raw_string({
892 "color": "rgb(0, 128, 0)",
893 "display": "inline",
894 "font-family": "ahem",
895 "font-style": "italic",
896 "margin-bottom": "0px",
897 "margin-left": "0px",
898 "margin-right": "0px",
899 "margin-top": "0px"
900 }
901 )raw_string"};
902
903 for (size_t i = 0; i < computed_styles.size(); i++) {
904 std::string result_json;
905 base::JSONWriter::WriteWithOptions(*computed_styles[i],
906 base::JSONWriter::OPTIONS_PRETTY_PRINT,
907 &result_json);
908
909 ASSERT_LT(i, expected_styles.size());
910 EXPECT_EQ(NormaliseJSON(expected_styles[i]), result_json) << " Style # "
911 << i;
912 }
913
914 devtools_client_->GetDOM()->Disable();
915 FinishAsynchronousTest();
916 }
917
918 std::unique_ptr<FlatDomTreeExtractor> extractor_;
919 };
920
921 HEADLESS_ASYNC_DEVTOOLED_TEST_F(FlatDomTreeExtractorBrowserTest);
922
923 } // namespace headless
OLDNEW
« no previous file with comments | « headless/public/util/flat_dom_tree_extractor.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698