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

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

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

Powered by Google App Engine
This is Rietveld 408576698