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

Side by Side Diff: headless/lib/headless_devtools_client_browsertest.cc

Issue 2882193002: [devtools] Add DOMSnapshot domain for dom+layout+style snapshots. (Closed)
Patch Set: rebase 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "base/json/json_reader.h" 7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
8 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h" 10 #include "base/run_loop.h"
11 #include "base/strings/string_util.h"
10 #include "content/public/browser/render_widget_host_view.h" 12 #include "content/public/browser/render_widget_host_view.h"
11 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/url_constants.h" 14 #include "content/public/common/url_constants.h"
13 #include "content/public/test/browser_test.h" 15 #include "content/public/test/browser_test.h"
14 #include "headless/lib/browser/headless_web_contents_impl.h" 16 #include "headless/lib/browser/headless_web_contents_impl.h"
15 #include "headless/public/devtools/domains/browser.h" 17 #include "headless/public/devtools/domains/browser.h"
16 #include "headless/public/devtools/domains/dom.h" 18 #include "headless/public/devtools/domains/dom.h"
19 #include "headless/public/devtools/domains/dom_snapshot.h"
17 #include "headless/public/devtools/domains/emulation.h" 20 #include "headless/public/devtools/domains/emulation.h"
18 #include "headless/public/devtools/domains/inspector.h" 21 #include "headless/public/devtools/domains/inspector.h"
19 #include "headless/public/devtools/domains/network.h" 22 #include "headless/public/devtools/domains/network.h"
20 #include "headless/public/devtools/domains/page.h" 23 #include "headless/public/devtools/domains/page.h"
21 #include "headless/public/devtools/domains/runtime.h" 24 #include "headless/public/devtools/domains/runtime.h"
22 #include "headless/public/devtools/domains/target.h" 25 #include "headless/public/devtools/domains/target.h"
23 #include "headless/public/headless_browser.h" 26 #include "headless/public/headless_browser.h"
24 #include "headless/public/headless_devtools_client.h" 27 #include "headless/public/headless_devtools_client.h"
25 #include "headless/public/headless_devtools_target.h" 28 #include "headless/public/headless_devtools_target.h"
26 #include "headless/test/headless_browser_test.h" 29 #include "headless/test/headless_browser_test.h"
(...skipping 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 EXPECT_TRUE(dev_tools_client_detached_); 1201 EXPECT_TRUE(dev_tools_client_detached_);
1199 } 1202 }
1200 1203
1201 private: 1204 private:
1202 bool dev_tools_client_attached_ = false; 1205 bool dev_tools_client_attached_ = false;
1203 bool dev_tools_client_detached_ = false; 1206 bool dev_tools_client_detached_ = false;
1204 }; 1207 };
1205 1208
1206 HEADLESS_ASYNC_DEVTOOLED_TEST_F(DevToolsAttachAndDetachNotifications); 1209 HEADLESS_ASYNC_DEVTOOLED_TEST_F(DevToolsAttachAndDetachNotifications);
1207 1210
1211 namespace {
1212
1213 std::string NormaliseJSON(const std::string& json) {
1214 std::unique_ptr<base::Value> parsed_json = base::JSONReader::Read(json);
1215 DCHECK(parsed_json);
1216 std::string normalized_json;
1217 base::JSONWriter::WriteWithOptions(
1218 *parsed_json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &normalized_json);
1219 return normalized_json;
1220 }
1221
1222 } // namespace
1223
1224 class DomTreeExtractionBrowserTest : public HeadlessAsyncDevTooledBrowserTest,
1225 public page::Observer {
1226 public:
1227 void RunDevTooledTest() override {
1228 EXPECT_TRUE(embedded_test_server()->Start());
1229 devtools_client_->GetPage()->AddObserver(this);
1230 devtools_client_->GetPage()->Enable();
1231 devtools_client_->GetPage()->Navigate(
1232 embedded_test_server()->GetURL("/dom_tree_test.html").spec());
1233 }
1234
1235 void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
1236 devtools_client_->GetPage()->Disable();
1237 devtools_client_->GetPage()->RemoveObserver(this);
1238
1239 std::vector<std::string> css_whitelist = {
1240 "color", "display", "font-style", "font-family",
1241 "margin-left", "margin-right", "margin-top", "margin-bottom"};
1242 devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot(
1243 dom_snapshot::GetSnapshotParams::Builder()
1244 .SetComputedStyleWhitelist(std::move(css_whitelist))
1245 .Build(),
1246 base::Bind(&DomTreeExtractionBrowserTest::OnGetSnapshotResult,
1247 base::Unretained(this)));
1248 }
1249
1250 void OnGetSnapshotResult(
1251 std::unique_ptr<dom_snapshot::GetSnapshotResult> result) {
1252 GURL::Replacements replace_port;
1253 replace_port.SetPortStr("");
1254
1255 std::vector<std::unique_ptr<base::DictionaryValue>> dom_nodes(
1256 result->GetDomNodes()->size());
1257
1258 // For convenience, flatten the dom tree into an array of dicts.
1259 for (size_t i = 0; i < result->GetDomNodes()->size(); i++) {
1260 dom_snapshot::DOMNode* node = (*result->GetDomNodes())[i].get();
1261
1262 dom_nodes[i].reset(
1263 static_cast<base::DictionaryValue*>(node->Serialize().release()));
1264 base::DictionaryValue* node_dict = dom_nodes[i].get();
1265
1266 base::DictionaryValue* aux_dict = nullptr;
1267 node_dict->GetDictionary("auxProperties", &aux_dict);
1268
1269 // Frame IDs are random.
1270 if (aux_dict && aux_dict->HasKey("frameId"))
1271 aux_dict->SetString("frameId", "?");
1272
1273 // Ports are random.
1274 std::string url;
1275 if (aux_dict && aux_dict->GetString("baseURL", &url)) {
1276 aux_dict->SetString("baseURL",
1277 GURL(url).ReplaceComponents(replace_port).spec());
1278 }
1279
1280 if (aux_dict && aux_dict->GetString("documentURL", &url)) {
1281 aux_dict->SetString("documentURL",
1282 GURL(url).ReplaceComponents(replace_port).spec());
1283 }
1284
1285 // Merge LayoutTreeNode data into the dictionary.
1286 int layout_node_index;
1287 if (node_dict->GetInteger("layoutNodeIndex", &layout_node_index)) {
1288 ASSERT_LE(0, layout_node_index);
1289 ASSERT_GT(result->GetLayoutTreeNodes()->size(),
1290 static_cast<size_t>(layout_node_index));
1291 const std::unique_ptr<dom_snapshot::LayoutTreeNode>& layout_node =
1292 (*result->GetLayoutTreeNodes())[layout_node_index];
1293
1294 node_dict->Set("boundingBox",
1295 layout_node->GetBoundingBox()->Serialize());
1296
1297 if (layout_node->HasLayoutText())
1298 node_dict->SetString("layoutText", layout_node->GetLayoutText());
1299
1300 if (layout_node->HasStyleIndex())
1301 node_dict->SetInteger("styleIndex", layout_node->GetStyleIndex());
1302
1303 if (layout_node->HasInlineTextNodes()) {
1304 std::unique_ptr<base::ListValue> inline_text_nodes(
1305 new base::ListValue());
1306 for (const std::unique_ptr<css::InlineTextBox>& inline_text_box :
1307 *layout_node->GetInlineTextNodes()) {
1308 size_t index = inline_text_nodes->GetSize();
1309 inline_text_nodes->Set(index, inline_text_box->Serialize());
1310 }
1311 node_dict->Set("inlineTextNodes", std::move(inline_text_nodes));
1312 }
1313 }
1314 }
1315
1316 std::vector<std::unique_ptr<base::DictionaryValue>> computed_styles(
1317 result->GetComputedStyles()->size());
1318
1319 for (size_t i = 0; i < result->GetComputedStyles()->size(); i++) {
1320 std::unique_ptr<base::DictionaryValue> style(new base::DictionaryValue());
1321 for (const auto& style_property :
1322 *(*result->GetComputedStyles())[i]->GetProperties()) {
1323 style->SetString(style_property->GetName(), style_property->GetValue());
1324 }
1325 computed_styles[i] = std::move(style);
1326 }
1327
1328 const std::vector<std::string> expected_dom_nodes = {
alex clarke (OOO till 29th) 2017/06/07 12:56:44 Bikeshed (maybe best as a todo): Formatting this s
Eric Seckler 2017/06/07 13:05:17 ah, I was just printf-ing the result_jsons to crea
1329 R"raw_string({
1330 "auxProperties": {
1331 "baseURL": "http://127.0.0.1/dom_tree_test.html",
1332 "documentURL": "http://127.0.0.1/dom_tree_test.html"
1333 },
1334 "backendNodeId": 3,
1335 "boundingBox": {
1336 "height": 600.0,
1337 "width": 800.0,
1338 "x": 0.0,
1339 "y": 0.0
1340 },
1341 "childNodeIndexes": [ 1 ],
1342 "layoutNodeIndex": 0,
1343 "nodeName": "#document",
1344 "nodeType": 9,
1345 "nodeValue": ""
1346 }
1347 )raw_string",
1348
1349 R"raw_string({
1350 "attributes": [ ],
1351 "auxProperties": {
1352 "frameId": "?"
1353 },
1354 "backendNodeId": 4,
1355 "boundingBox": {
1356 "height": 600.0,
1357 "width": 800.0,
1358 "x": 0.0,
1359 "y": 0.0
1360 },
1361 "childNodeIndexes": [ 2, 9, 10 ],
1362 "layoutNodeIndex": 1,
1363 "nodeName": "HTML",
1364 "nodeType": 1,
1365 "nodeValue": "",
1366 "styleIndex": 0
1367 }
1368 )raw_string",
1369
1370 R"raw_string({
1371 "attributes": [ ],
1372 "auxProperties": {
1373
1374 },
1375 "backendNodeId": 5,
1376 "childNodeIndexes": [ 3, 4, 6, 7, 8 ],
1377 "nodeName": "HEAD",
1378 "nodeType": 1,
1379 "nodeValue": ""
1380 }
1381 )raw_string",
1382
1383 R"raw_string({
1384 "auxProperties": {
1385
1386 },
1387 "backendNodeId": 6,
1388 "nodeName": "#text",
1389 "nodeType": 3,
1390 "nodeValue": "\n"
1391 }
1392 )raw_string",
1393
1394 R"raw_string({
1395 "attributes": [ ],
1396 "auxProperties": {
1397
1398 },
1399 "backendNodeId": 7,
1400 "childNodeIndexes": [ 5 ],
1401 "nodeName": "TITLE",
1402 "nodeType": 1,
1403 "nodeValue": ""
1404 }
1405 )raw_string",
1406
1407 R"raw_string({
1408 "auxProperties": {
1409
1410 },
1411 "backendNodeId": 8,
1412 "nodeName": "#text",
1413 "nodeType": 3,
1414 "nodeValue": "Hello world!"
1415 }
1416 )raw_string",
1417
1418 R"raw_string({
1419 "auxProperties": {
1420
1421 },
1422 "backendNodeId": 9,
1423 "nodeName": "#text",
1424 "nodeType": 3,
1425 "nodeValue": "\n"
1426 }
1427 )raw_string",
1428
1429 R"raw_string({
1430 "attributes": [ {
1431 "name": "href",
1432 "value": "dom_tree_test.css"
1433 }, {
1434 "name": "rel",
1435 "value": "stylesheet"
1436 }, {
1437 "name": "type",
1438 "value": "text/css"
1439 } ],
1440 "auxProperties": {
1441
1442 },
1443 "backendNodeId": 10,
1444 "nodeName": "LINK",
1445 "nodeType": 1,
1446 "nodeValue": ""
1447 }
1448 )raw_string",
1449
1450 R"raw_string({
1451 "auxProperties": {
1452
1453 },
1454 "backendNodeId": 11,
1455 "nodeName": "#text",
1456 "nodeType": 3,
1457 "nodeValue": "\n"
1458 }
1459 )raw_string",
1460
1461 R"raw_string({
1462 "auxProperties": {
1463
1464 },
1465 "backendNodeId": 12,
1466 "nodeName": "#text",
1467 "nodeType": 3,
1468 "nodeValue": "\n"
1469 }
1470 )raw_string",
1471
1472 R"raw_string({
1473 "attributes": [ ],
1474 "auxProperties": {
1475
1476 },
1477 "backendNodeId": 13,
1478 "boundingBox": {
1479 "height": 584.0,
1480 "width": 784.0,
1481 "x": 8.0,
1482 "y": 8.0
1483 },
1484 "childNodeIndexes": [ 11, 12 ],
1485 "layoutNodeIndex": 2,
1486 "nodeName": "BODY",
1487 "nodeType": 1,
1488 "nodeValue": "",
1489 "styleIndex": 1
1490 }
1491 )raw_string",
1492
1493 R"raw_string({
1494 "auxProperties": {
1495
1496 },
1497 "backendNodeId": 14,
1498 "nodeName": "#text",
1499 "nodeType": 3,
1500 "nodeValue": "\n"
1501 }
1502 )raw_string",
1503
1504 R"raw_string({
1505 "attributes": [ {
1506 "name": "id",
1507 "value": "id1"
1508 } ],
1509 "auxProperties": {
1510
1511 },
1512 "backendNodeId": 15,
1513 "boundingBox": {
1514 "height": 354.0,
1515 "width": 784.0,
1516 "x": 8.0,
1517 "y": 8.0
1518 },
1519 "childNodeIndexes": [ 13, 14, 16, 17, 26, 27, 49 ],
1520 "layoutNodeIndex": 3,
1521 "nodeName": "DIV",
1522 "nodeType": 1,
1523 "nodeValue": "",
1524 "styleIndex": 0
1525 }
1526 )raw_string",
1527
1528 R"raw_string({
1529 "auxProperties": {
1530
1531 },
1532 "backendNodeId": 16,
1533 "nodeName": "#text",
1534 "nodeType": 3,
1535 "nodeValue": "\n"
1536 }
1537 )raw_string",
1538
1539 R"raw_string({
1540 "attributes": [ {
1541 "name": "class",
1542 "value": "red"
1543 } ],
1544 "auxProperties": {
1545
1546 },
1547 "backendNodeId": 17,
1548 "boundingBox": {
1549 "height": 32.0,
1550 "width": 784.0,
1551 "x": 8.0,
1552 "y": 8.0
1553 },
1554 "childNodeIndexes": [ 15 ],
1555 "layoutNodeIndex": 4,
1556 "nodeName": "H1",
1557 "nodeType": 1,
1558 "nodeValue": "",
1559 "styleIndex": 2
1560 }
1561 )raw_string",
1562
1563 R"raw_string({
1564 "auxProperties": {
1565
1566 },
1567 "backendNodeId": 18,
1568 "boundingBox": {
1569 "height": 32.0,
1570 "width": 320.0,
1571 "x": 8.0,
1572 "y": 8.0
1573 },
1574 "inlineTextNodes": [ {
1575 "boundingBox": {
1576 "height": 32.0,
1577 "width": 320.0,
1578 "x": 8.0,
1579 "y": 8.0
1580 },
1581 "numCharacters": 10,
1582 "startCharacterIndex": 0
1583 } ],
1584 "layoutNodeIndex": 5,
1585 "layoutText": "Some text.",
1586 "nodeName": "#text",
1587 "nodeType": 3,
1588 "nodeValue": "Some text.",
1589 "styleIndex": 2
1590 }
1591 )raw_string",
1592
1593 R"raw_string({
1594 "auxProperties": {
1595
1596 },
1597 "backendNodeId": 19,
1598 "nodeName": "#text",
1599 "nodeType": 3,
1600 "nodeValue": "\n"
1601 }
1602 )raw_string",
1603
1604 R"raw_string({
1605 "attributes": [ {
1606 "name": "src",
1607 "value": "/iframe.html"
1608 }, {
1609 "name": "width",
1610 "value": "400"
1611 }, {
1612 "name": "height",
1613 "value": "200"
1614 } ],
1615 "auxProperties": {
1616 "contentDocumentIndex": 18,
1617 "frameId": "?"
1618 },
1619 "backendNodeId": 20,
1620 "boundingBox": {
1621 "height": 205.0,
1622 "width": 404.0,
1623 "x": 8.0,
1624 "y": 61.0
1625 },
1626 "layoutNodeIndex": 6,
1627 "nodeName": "IFRAME",
1628 "nodeType": 1,
1629 "nodeValue": "",
1630 "styleIndex": 3
1631 }
1632 )raw_string",
1633
1634 R"raw_string({
1635 "auxProperties": {
1636 "baseURL": "http://127.0.0.1/iframe.html",
1637 "documentURL": "http://127.0.0.1/iframe.html"
1638 },
1639 "backendNodeId": 21,
1640 "boundingBox": {
1641 "height": 200.0,
1642 "width": 400.0,
1643 "x": 0.0,
1644 "y": 0.0
1645 },
1646 "childNodeIndexes": [ 19 ],
1647 "layoutNodeIndex": 7,
1648 "nodeName": "#document",
1649 "nodeType": 9,
1650 "nodeValue": ""
1651 }
1652 )raw_string",
1653
1654 R"raw_string({
1655 "attributes": [ ],
1656 "auxProperties": {
1657 "frameId": "?"
1658 },
1659 "backendNodeId": 22,
1660 "boundingBox": {
1661 "height": 200.0,
1662 "width": 400.0,
1663 "x": 10.0,
1664 "y": 63.0
1665 },
1666 "childNodeIndexes": [ 20, 21 ],
1667 "layoutNodeIndex": 8,
1668 "nodeName": "HTML",
1669 "nodeType": 1,
1670 "nodeValue": "",
1671 "styleIndex": 4
1672 }
1673 )raw_string",
1674
1675 R"raw_string({
1676 "attributes": [ ],
1677 "auxProperties": {
1678
1679 },
1680 "backendNodeId": 23,
1681 "nodeName": "HEAD",
1682 "nodeType": 1,
1683 "nodeValue": ""
1684 }
1685 )raw_string",
1686
1687 R"raw_string({
1688 "attributes": [ ],
1689 "auxProperties": {
1690
1691 },
1692 "backendNodeId": 24,
1693 "boundingBox": {
1694 "height": 171.0,
1695 "width": 384.0,
1696 "x": 18.0,
1697 "y": 71.0
1698 },
1699 "childNodeIndexes": [ 22, 23, 25 ],
1700 "layoutNodeIndex": 9,
1701 "nodeName": "BODY",
1702 "nodeType": 1,
1703 "nodeValue": "",
1704 "styleIndex": 5
1705 }
1706 )raw_string",
1707
1708 R"raw_string({
1709 "auxProperties": {
1710
1711 },
1712 "backendNodeId": 25,
1713 "nodeName": "#text",
1714 "nodeType": 3,
1715 "nodeValue": "\n"
1716 }
1717 )raw_string",
1718
1719 R"raw_string({
1720 "attributes": [ ],
1721 "auxProperties": {
1722
1723 },
1724 "backendNodeId": 26,
1725 "boundingBox": {
1726 "height": 37.0,
1727 "width": 384.0,
1728 "x": 18.0,
1729 "y": 71.0
1730 },
1731 "childNodeIndexes": [ 24 ],
1732 "layoutNodeIndex": 10,
1733 "nodeName": "H1",
1734 "nodeType": 1,
1735 "nodeValue": "",
1736 "styleIndex": 6
1737 }
1738 )raw_string",
1739
1740 R"raw_string({
1741 "auxProperties": {
1742
1743 },
1744 "backendNodeId": 27,
1745 "boundingBox": {
1746 "height": 36.0,
1747 "width": 308.0,
1748 "x": 8.0,
1749 "y": 8.0
1750 },
1751 "inlineTextNodes": [ {
1752 "boundingBox": {
1753 "height": 36.0,
1754 "width": 307.734375,
1755 "x": 8.0,
1756 "y": 8.0
1757 },
1758 "numCharacters": 22,
1759 "startCharacterIndex": 0
1760 } ],
1761 "layoutNodeIndex": 11,
1762 "layoutText": "Hello from the iframe!",
1763 "nodeName": "#text",
1764 "nodeType": 3,
1765 "nodeValue": "Hello from the iframe!",
1766 "styleIndex": 6
1767 }
1768 )raw_string",
1769
1770 R"raw_string({
1771 "auxProperties": {
1772
1773 },
1774 "backendNodeId": 28,
1775 "nodeName": "#text",
1776 "nodeType": 3,
1777 "nodeValue": "\n\n\n"
1778 }
1779 )raw_string",
1780
1781 R"raw_string({
1782 "auxProperties": {
1783
1784 },
1785 "backendNodeId": 29,
1786 "boundingBox": {
1787 "height": 0.0,
1788 "width": 0.0,
1789 "x": 0.0,
1790 "y": 0.0
1791 },
1792 "layoutNodeIndex": 12,
1793 "layoutText": "\n",
1794 "nodeName": "#text",
1795 "nodeType": 3,
1796 "nodeValue": "\n",
1797 "styleIndex": 0
1798 }
1799 )raw_string",
1800
1801 R"raw_string({
1802 "attributes": [ {
1803 "name": "id",
1804 "value": "id2"
1805 } ],
1806 "auxProperties": {
1807
1808 },
1809 "backendNodeId": 30,
1810 "boundingBox": {
1811 "height": 97.0,
1812 "width": 784.0,
1813 "x": 8.0,
1814 "y": 265.0
1815 },
1816 "childNodeIndexes": [ 28, 29, 48 ],
1817 "layoutNodeIndex": 13,
1818 "nodeName": "DIV",
1819 "nodeType": 1,
1820 "nodeValue": "",
1821 "styleIndex": 0
1822 }
1823 )raw_string",
1824
1825 R"raw_string({
1826 "auxProperties": {
1827
1828 },
1829 "backendNodeId": 31,
1830 "nodeName": "#text",
1831 "nodeType": 3,
1832 "nodeValue": "\n "
1833 }
1834 )raw_string",
1835
1836 R"raw_string({
1837 "attributes": [ {
1838 "name": "id",
1839 "value": "id3"
1840 } ],
1841 "auxProperties": {
1842
1843 },
1844 "backendNodeId": 32,
1845 "boundingBox": {
1846 "height": 97.0,
1847 "width": 784.0,
1848 "x": 8.0,
1849 "y": 265.0
1850 },
1851 "childNodeIndexes": [ 30, 31, 47 ],
1852 "layoutNodeIndex": 14,
1853 "nodeName": "DIV",
1854 "nodeType": 1,
1855 "nodeValue": "",
1856 "styleIndex": 0
1857 }
1858 )raw_string",
1859
1860 R"raw_string({
1861 "auxProperties": {
1862
1863 },
1864 "backendNodeId": 33,
1865 "nodeName": "#text",
1866 "nodeType": 3,
1867 "nodeValue": "\n "
1868 }
1869 )raw_string",
1870
1871 R"raw_string({
1872 "attributes": [ {
1873 "name": "id",
1874 "value": "id4"
1875 } ],
1876 "auxProperties": {
1877
1878 },
1879 "backendNodeId": 34,
1880 "boundingBox": {
1881 "height": 97.0,
1882 "width": 784.0,
1883 "x": 8.0,
1884 "y": 265.0
1885 },
1886 "childNodeIndexes": [ 32, 33, 35, 36, 38, 39, 40, 41, 46 ],
1887 "layoutNodeIndex": 15,
1888 "nodeName": "DIV",
1889 "nodeType": 1,
1890 "nodeValue": "",
1891 "styleIndex": 0
1892 }
1893 )raw_string",
1894
1895 R"raw_string({
1896 "auxProperties": {
1897
1898 },
1899 "backendNodeId": 35,
1900 "nodeName": "#text",
1901 "nodeType": 3,
1902 "nodeValue": "\n "
1903 }
1904 )raw_string",
1905
1906 R"raw_string({
1907 "attributes": [ {
1908 "name": "href",
1909 "value": "https://www.google.com"
1910 } ],
1911 "auxProperties": {
1912
1913 },
1914 "backendNodeId": 36,
1915 "boundingBox": {
1916 "height": 17.0,
1917 "width": 112.0,
1918 "x": 8.0,
1919 "y": 265.0
1920 },
1921 "childNodeIndexes": [ 34 ],
1922 "layoutNodeIndex": 16,
1923 "nodeName": "A",
1924 "nodeType": 1,
1925 "nodeValue": "",
1926 "styleIndex": 7
1927 }
1928 )raw_string",
1929
1930 R"raw_string({
1931 "auxProperties": {
1932
1933 },
1934 "backendNodeId": 37,
1935 "boundingBox": {
1936 "height": 17.0,
1937 "width": 112.0,
1938 "x": 8.0,
1939 "y": 265.0
1940 },
1941 "inlineTextNodes": [ {
1942 "boundingBox": {
1943 "height": 16.0,
1944 "width": 112.0,
1945 "x": 8.0,
1946 "y": 265.4375
1947 },
1948 "numCharacters": 7,
1949 "startCharacterIndex": 0
1950 } ],
1951 "layoutNodeIndex": 17,
1952 "layoutText": "Google!",
1953 "nodeName": "#text",
1954 "nodeType": 3,
1955 "nodeValue": "Google!",
1956 "styleIndex": 7
1957 }
1958 )raw_string",
1959
1960 R"raw_string({
1961 "auxProperties": {
1962
1963 },
1964 "backendNodeId": 38,
1965 "boundingBox": {
1966 "height": 0.0,
1967 "width": 0.0,
1968 "x": 0.0,
1969 "y": 0.0
1970 },
1971 "layoutNodeIndex": 18,
1972 "layoutText": "\n ",
1973 "nodeName": "#text",
1974 "nodeType": 3,
1975 "nodeValue": "\n ",
1976 "styleIndex": 0
1977 }
1978 )raw_string",
1979
1980 R"raw_string({
1981 "attributes": [ ],
1982 "auxProperties": {
1983
1984 },
1985 "backendNodeId": 39,
1986 "boundingBox": {
1987 "height": 17.0,
1988 "width": 784.0,
1989 "x": 8.0,
1990 "y": 297.0
1991 },
1992 "childNodeIndexes": [ 37 ],
1993 "layoutNodeIndex": 19,
1994 "nodeName": "P",
1995 "nodeType": 1,
1996 "nodeValue": "",
1997 "styleIndex": 8
1998 }
1999 )raw_string",
2000
2001 R"raw_string({
2002 "auxProperties": {
2003
2004 },
2005 "backendNodeId": 40,
2006 "boundingBox": {
2007 "height": 17.0,
2008 "width": 192.0,
2009 "x": 8.0,
2010 "y": 297.0
2011 },
2012 "inlineTextNodes": [ {
2013 "boundingBox": {
2014 "height": 16.0,
2015 "width": 192.0,
2016 "x": 8.0,
2017 "y": 297.4375
2018 },
2019 "numCharacters": 12,
2020 "startCharacterIndex": 0
2021 } ],
2022 "layoutNodeIndex": 20,
2023 "layoutText": "A paragraph!",
2024 "nodeName": "#text",
2025 "nodeType": 3,
2026 "nodeValue": "A paragraph!",
2027 "styleIndex": 8
2028 }
2029 )raw_string",
2030
2031 R"raw_string({
2032 "auxProperties": {
2033
2034 },
2035 "backendNodeId": 41,
2036 "nodeName": "#text",
2037 "nodeType": 3,
2038 "nodeValue": "\n "
2039 }
2040 )raw_string",
2041
2042 R"raw_string({
2043 "attributes": [ ],
2044 "auxProperties": {
2045
2046 },
2047 "backendNodeId": 42,
2048 "boundingBox": {
2049 "height": 0.0,
2050 "width": 0.0,
2051 "x": 0.0,
2052 "y": 0.0
2053 },
2054 "inlineTextNodes": [ {
2055 "boundingBox": {
2056 "height": 16.0,
2057 "width": 0.0,
2058 "x": 8.0,
2059 "y": 329.4375
2060 },
2061 "numCharacters": 1,
2062 "startCharacterIndex": 0
2063 } ],
2064 "layoutNodeIndex": 21,
2065 "layoutText": "\n",
2066 "nodeName": "BR",
2067 "nodeType": 1,
2068 "nodeValue": "",
2069 "styleIndex": 3
2070 }
2071 )raw_string",
2072
2073 R"raw_string({
2074 "auxProperties": {
2075
2076 },
2077 "backendNodeId": 43,
2078 "nodeName": "#text",
2079 "nodeType": 3,
2080 "nodeValue": "\n "
2081 }
2082 )raw_string",
2083
2084 R"raw_string({
2085 "attributes": [ {
2086 "name": "class",
2087 "value": "green"
2088 } ],
2089 "auxProperties": {
2090
2091 },
2092 "backendNodeId": 44,
2093 "boundingBox": {
2094 "height": 17.0,
2095 "width": 784.0,
2096 "x": 8.0,
2097 "y": 345.0
2098 },
2099 "childNodeIndexes": [ 42, 43, 45 ],
2100 "layoutNodeIndex": 22,
2101 "nodeName": "DIV",
2102 "nodeType": 1,
2103 "nodeValue": "",
2104 "styleIndex": 9
2105 }
2106 )raw_string",
2107
2108 R"raw_string({
2109 "auxProperties": {
2110
2111 },
2112 "backendNodeId": 45,
2113 "boundingBox": {
2114 "height": 17.0,
2115 "width": 80.0,
2116 "x": 8.0,
2117 "y": 345.0
2118 },
2119 "inlineTextNodes": [ {
2120 "boundingBox": {
2121 "height": 16.0,
2122 "width": 80.0,
2123 "x": 8.0,
2124 "y": 345.4375
2125 },
2126 "numCharacters": 5,
2127 "startCharacterIndex": 0
2128 } ],
2129 "layoutNodeIndex": 23,
2130 "layoutText": "Some ",
2131 "nodeName": "#text",
2132 "nodeType": 3,
2133 "nodeValue": "Some ",
2134 "styleIndex": 9
2135 }
2136 )raw_string",
2137
2138 R"raw_string({
2139 "attributes": [ ],
2140 "auxProperties": {
2141
2142 },
2143 "backendNodeId": 46,
2144 "boundingBox": {
2145 "height": 17.0,
2146 "width": 80.0,
2147 "x": 88.0,
2148 "y": 345.0
2149 },
2150 "childNodeIndexes": [ 44 ],
2151 "layoutNodeIndex": 24,
2152 "nodeName": "EM",
2153 "nodeType": 1,
2154 "nodeValue": "",
2155 "styleIndex": 10
2156 }
2157 )raw_string",
2158
2159 R"raw_string({
2160 "auxProperties": {
2161
2162 },
2163 "backendNodeId": 47,
2164 "boundingBox": {
2165 "height": 17.0,
2166 "width": 80.0,
2167 "x": 88.0,
2168 "y": 345.0
2169 },
2170 "inlineTextNodes": [ {
2171 "boundingBox": {
2172 "height": 16.0,
2173 "width": 80.0,
2174 "x": 88.0,
2175 "y": 345.4375
2176 },
2177 "numCharacters": 5,
2178 "startCharacterIndex": 0
2179 } ],
2180 "layoutNodeIndex": 25,
2181 "layoutText": "green",
2182 "nodeName": "#text",
2183 "nodeType": 3,
2184 "nodeValue": "green",
2185 "styleIndex": 10
2186 }
2187 )raw_string",
2188
2189 R"raw_string({
2190 "auxProperties": {
2191
2192 },
2193 "backendNodeId": 48,
2194 "boundingBox": {
2195 "height": 17.0,
2196 "width": 128.0,
2197 "x": 168.0,
2198 "y": 345.0
2199 },
2200 "inlineTextNodes": [ {
2201 "boundingBox": {
2202 "height": 16.0,
2203 "width": 128.0,
2204 "x": 168.0,
2205 "y": 345.4375
2206 },
2207 "numCharacters": 8,
2208 "startCharacterIndex": 0
2209 } ],
2210 "layoutNodeIndex": 26,
2211 "layoutText": " text...",
2212 "nodeName": "#text",
2213 "nodeType": 3,
2214 "nodeValue": " text...",
2215 "styleIndex": 9
2216 }
2217 )raw_string",
2218
2219 R"raw_string({
2220 "auxProperties": {
2221
2222 },
2223 "backendNodeId": 49,
2224 "nodeName": "#text",
2225 "nodeType": 3,
2226 "nodeValue": "\n "
2227 }
2228 )raw_string",
2229
2230 R"raw_string({
2231 "auxProperties": {
2232
2233 },
2234 "backendNodeId": 50,
2235 "nodeName": "#text",
2236 "nodeType": 3,
2237 "nodeValue": "\n "
2238 }
2239 )raw_string",
2240
2241 R"raw_string({
2242 "auxProperties": {
2243
2244 },
2245 "backendNodeId": 51,
2246 "nodeName": "#text",
2247 "nodeType": 3,
2248 "nodeValue": "\n"
2249 }
2250 )raw_string",
2251
2252 R"raw_string({
2253 "auxProperties": {
2254
2255 },
2256 "backendNodeId": 52,
2257 "nodeName": "#text",
2258 "nodeType": 3,
2259 "nodeValue": "\n\n\n"
2260 }
2261 )raw_string"};
2262
2263 EXPECT_EQ(expected_dom_nodes.size(), dom_nodes.size());
2264
2265 for (size_t i = 0; i < dom_nodes.size(); i++) {
2266 std::string result_json;
2267 base::JSONWriter::WriteWithOptions(
2268 *dom_nodes[i], base::JSONWriter::OPTIONS_PRETTY_PRINT, &result_json);
2269
2270 ASSERT_LT(i, expected_dom_nodes.size());
2271 EXPECT_EQ(NormaliseJSON(expected_dom_nodes[i]), result_json)
2272 << " Node # " << i;
2273 }
2274
2275 const std::vector<std::string> expected_styles = {
2276 R"raw_string({
2277 "color": "rgb(0, 0, 0)",
2278 "display": "block",
2279 "font-family": "ahem",
2280 "font-style": "normal",
2281 "margin-bottom": "0px",
2282 "margin-left": "0px",
2283 "margin-right": "0px",
2284 "margin-top": "0px"
2285 })raw_string",
2286
2287 R"raw_string({
2288 "color": "rgb(0, 0, 0)",
2289 "display": "block",
2290 "font-family": "ahem",
2291 "font-style": "normal",
2292 "margin-bottom": "8px",
2293 "margin-left": "8px",
2294 "margin-right": "8px",
2295 "margin-top": "8px"
2296 })raw_string",
2297
2298 R"raw_string({
2299 "color": "rgb(255, 0, 0)",
2300 "display": "block",
2301 "font-family": "ahem",
2302 "font-style": "normal",
2303 "margin-bottom": "21.44px",
2304 "margin-left": "0px",
2305 "margin-right": "0px",
2306 "margin-top": "21.44px"
2307 })raw_string",
2308
2309 R"raw_string({
2310 "color": "rgb(0, 0, 0)",
2311 "display": "inline",
2312 "font-family": "ahem",
2313 "font-style": "normal",
2314 "margin-bottom": "0px",
2315 "margin-left": "0px",
2316 "margin-right": "0px",
2317 "margin-top": "0px"
2318 })raw_string",
2319
2320 R"raw_string({
2321 "color": "rgb(0, 0, 0)",
2322 "display": "block",
2323 "font-family": "\"Times New Roman\"",
2324 "font-style": "normal",
2325 "margin-bottom": "0px",
2326 "margin-left": "0px",
2327 "margin-right": "0px",
2328 "margin-top": "0px"
2329 })raw_string",
2330
2331 R"raw_string({
2332 "color": "rgb(0, 0, 0)",
2333 "display": "block",
2334 "font-family": "\"Times New Roman\"",
2335 "font-style": "normal",
2336 "margin-bottom": "8px",
2337 "margin-left": "8px",
2338 "margin-right": "8px",
2339 "margin-top": "8px"
2340 })raw_string",
2341
2342 R"raw_string({
2343 "color": "rgb(0, 0, 0)",
2344 "display": "block",
2345 "font-family": "\"Times New Roman\"",
2346 "font-style": "normal",
2347 "margin-bottom": "21.44px",
2348 "margin-left": "0px",
2349 "margin-right": "0px",
2350 "margin-top": "21.44px"
2351 })raw_string",
2352
2353 R"raw_string({
2354 "color": "rgb(0, 0, 238)",
2355 "display": "inline",
2356 "font-family": "ahem",
2357 "font-style": "normal",
2358 "margin-bottom": "0px",
2359 "margin-left": "0px",
2360 "margin-right": "0px",
2361 "margin-top": "0px"
2362 })raw_string",
2363
2364 R"raw_string({
2365 "color": "rgb(0, 0, 0)",
2366 "display": "block",
2367 "font-family": "ahem",
2368 "font-style": "normal",
2369 "margin-bottom": "16px",
2370 "margin-left": "0px",
2371 "margin-right": "0px",
2372 "margin-top": "16px"
2373 })raw_string",
2374
2375 R"raw_string({
2376 "color": "rgb(0, 128, 0)",
2377 "display": "block",
2378 "font-family": "ahem",
2379 "font-style": "normal",
2380 "margin-bottom": "0px",
2381 "margin-left": "0px",
2382 "margin-right": "0px",
2383 "margin-top": "0px"
2384 })raw_string",
2385
2386 R"raw_string({
2387 "color": "rgb(0, 128, 0)",
2388 "display": "inline",
2389 "font-family": "ahem",
2390 "font-style": "italic",
2391 "margin-bottom": "0px",
2392 "margin-left": "0px",
2393 "margin-right": "0px",
2394 "margin-top": "0px"
2395 }
2396 )raw_string"};
2397
2398 EXPECT_EQ(expected_styles.size(), computed_styles.size());
2399
2400 for (size_t i = 0; i < computed_styles.size(); i++) {
2401 std::string result_json;
2402 base::JSONWriter::WriteWithOptions(*computed_styles[i],
2403 base::JSONWriter::OPTIONS_PRETTY_PRINT,
2404 &result_json);
2405
2406 ASSERT_LT(i, expected_styles.size());
2407 EXPECT_EQ(NormaliseJSON(expected_styles[i]), result_json)
2408 << " Style # " << i;
2409 }
2410
2411 FinishAsynchronousTest();
2412 }
2413 };
2414
2415 HEADLESS_ASYNC_DEVTOOLED_TEST_F(DomTreeExtractionBrowserTest);
2416
1208 } // namespace headless 2417 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698