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

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

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

Powered by Google App Engine
This is Rietveld 408576698