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

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: add todo 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 // TODO(eseckler): Extract expectation strings into external files to make
1329 // them easier to maintain.
1330 const std::vector<std::string> expected_dom_nodes = {
1331 R"raw_string({
1332 "auxProperties": {
1333 "baseURL": "http://127.0.0.1/dom_tree_test.html",
1334 "documentURL": "http://127.0.0.1/dom_tree_test.html"
1335 },
1336 "backendNodeId": 3,
1337 "boundingBox": {
1338 "height": 600.0,
1339 "width": 800.0,
1340 "x": 0.0,
1341 "y": 0.0
1342 },
1343 "childNodeIndexes": [ 1 ],
1344 "layoutNodeIndex": 0,
1345 "nodeName": "#document",
1346 "nodeType": 9,
1347 "nodeValue": ""
1348 }
1349 )raw_string",
1350
1351 R"raw_string({
1352 "attributes": [ ],
1353 "auxProperties": {
1354 "frameId": "?"
1355 },
1356 "backendNodeId": 4,
1357 "boundingBox": {
1358 "height": 600.0,
1359 "width": 800.0,
1360 "x": 0.0,
1361 "y": 0.0
1362 },
1363 "childNodeIndexes": [ 2, 9, 10 ],
1364 "layoutNodeIndex": 1,
1365 "nodeName": "HTML",
1366 "nodeType": 1,
1367 "nodeValue": "",
1368 "styleIndex": 0
1369 }
1370 )raw_string",
1371
1372 R"raw_string({
1373 "attributes": [ ],
1374 "auxProperties": {
1375
1376 },
1377 "backendNodeId": 5,
1378 "childNodeIndexes": [ 3, 4, 6, 7, 8 ],
1379 "nodeName": "HEAD",
1380 "nodeType": 1,
1381 "nodeValue": ""
1382 }
1383 )raw_string",
1384
1385 R"raw_string({
1386 "auxProperties": {
1387
1388 },
1389 "backendNodeId": 6,
1390 "nodeName": "#text",
1391 "nodeType": 3,
1392 "nodeValue": "\n"
1393 }
1394 )raw_string",
1395
1396 R"raw_string({
1397 "attributes": [ ],
1398 "auxProperties": {
1399
1400 },
1401 "backendNodeId": 7,
1402 "childNodeIndexes": [ 5 ],
1403 "nodeName": "TITLE",
1404 "nodeType": 1,
1405 "nodeValue": ""
1406 }
1407 )raw_string",
1408
1409 R"raw_string({
1410 "auxProperties": {
1411
1412 },
1413 "backendNodeId": 8,
1414 "nodeName": "#text",
1415 "nodeType": 3,
1416 "nodeValue": "Hello world!"
1417 }
1418 )raw_string",
1419
1420 R"raw_string({
1421 "auxProperties": {
1422
1423 },
1424 "backendNodeId": 9,
1425 "nodeName": "#text",
1426 "nodeType": 3,
1427 "nodeValue": "\n"
1428 }
1429 )raw_string",
1430
1431 R"raw_string({
1432 "attributes": [ {
1433 "name": "href",
1434 "value": "dom_tree_test.css"
1435 }, {
1436 "name": "rel",
1437 "value": "stylesheet"
1438 }, {
1439 "name": "type",
1440 "value": "text/css"
1441 } ],
1442 "auxProperties": {
1443
1444 },
1445 "backendNodeId": 10,
1446 "nodeName": "LINK",
1447 "nodeType": 1,
1448 "nodeValue": ""
1449 }
1450 )raw_string",
1451
1452 R"raw_string({
1453 "auxProperties": {
1454
1455 },
1456 "backendNodeId": 11,
1457 "nodeName": "#text",
1458 "nodeType": 3,
1459 "nodeValue": "\n"
1460 }
1461 )raw_string",
1462
1463 R"raw_string({
1464 "auxProperties": {
1465
1466 },
1467 "backendNodeId": 12,
1468 "nodeName": "#text",
1469 "nodeType": 3,
1470 "nodeValue": "\n"
1471 }
1472 )raw_string",
1473
1474 R"raw_string({
1475 "attributes": [ ],
1476 "auxProperties": {
1477
1478 },
1479 "backendNodeId": 13,
1480 "boundingBox": {
1481 "height": 584.0,
1482 "width": 784.0,
1483 "x": 8.0,
1484 "y": 8.0
1485 },
1486 "childNodeIndexes": [ 11, 12 ],
1487 "layoutNodeIndex": 2,
1488 "nodeName": "BODY",
1489 "nodeType": 1,
1490 "nodeValue": "",
1491 "styleIndex": 1
1492 }
1493 )raw_string",
1494
1495 R"raw_string({
1496 "auxProperties": {
1497
1498 },
1499 "backendNodeId": 14,
1500 "nodeName": "#text",
1501 "nodeType": 3,
1502 "nodeValue": "\n"
1503 }
1504 )raw_string",
1505
1506 R"raw_string({
1507 "attributes": [ {
1508 "name": "id",
1509 "value": "id1"
1510 } ],
1511 "auxProperties": {
1512
1513 },
1514 "backendNodeId": 15,
1515 "boundingBox": {
1516 "height": 354.0,
1517 "width": 784.0,
1518 "x": 8.0,
1519 "y": 8.0
1520 },
1521 "childNodeIndexes": [ 13, 14, 16, 17, 26, 27, 49 ],
1522 "layoutNodeIndex": 3,
1523 "nodeName": "DIV",
1524 "nodeType": 1,
1525 "nodeValue": "",
1526 "styleIndex": 0
1527 }
1528 )raw_string",
1529
1530 R"raw_string({
1531 "auxProperties": {
1532
1533 },
1534 "backendNodeId": 16,
1535 "nodeName": "#text",
1536 "nodeType": 3,
1537 "nodeValue": "\n"
1538 }
1539 )raw_string",
1540
1541 R"raw_string({
1542 "attributes": [ {
1543 "name": "class",
1544 "value": "red"
1545 } ],
1546 "auxProperties": {
1547
1548 },
1549 "backendNodeId": 17,
1550 "boundingBox": {
1551 "height": 32.0,
1552 "width": 784.0,
1553 "x": 8.0,
1554 "y": 8.0
1555 },
1556 "childNodeIndexes": [ 15 ],
1557 "layoutNodeIndex": 4,
1558 "nodeName": "H1",
1559 "nodeType": 1,
1560 "nodeValue": "",
1561 "styleIndex": 2
1562 }
1563 )raw_string",
1564
1565 R"raw_string({
1566 "auxProperties": {
1567
1568 },
1569 "backendNodeId": 18,
1570 "boundingBox": {
1571 "height": 32.0,
1572 "width": 320.0,
1573 "x": 8.0,
1574 "y": 8.0
1575 },
1576 "inlineTextNodes": [ {
1577 "boundingBox": {
1578 "height": 32.0,
1579 "width": 320.0,
1580 "x": 8.0,
1581 "y": 8.0
1582 },
1583 "numCharacters": 10,
1584 "startCharacterIndex": 0
1585 } ],
1586 "layoutNodeIndex": 5,
1587 "layoutText": "Some text.",
1588 "nodeName": "#text",
1589 "nodeType": 3,
1590 "nodeValue": "Some text.",
1591 "styleIndex": 2
1592 }
1593 )raw_string",
1594
1595 R"raw_string({
1596 "auxProperties": {
1597
1598 },
1599 "backendNodeId": 19,
1600 "nodeName": "#text",
1601 "nodeType": 3,
1602 "nodeValue": "\n"
1603 }
1604 )raw_string",
1605
1606 R"raw_string({
1607 "attributes": [ {
1608 "name": "src",
1609 "value": "/iframe.html"
1610 }, {
1611 "name": "width",
1612 "value": "400"
1613 }, {
1614 "name": "height",
1615 "value": "200"
1616 } ],
1617 "auxProperties": {
1618 "contentDocumentIndex": 18,
1619 "frameId": "?"
1620 },
1621 "backendNodeId": 20,
1622 "boundingBox": {
1623 "height": 205.0,
1624 "width": 404.0,
1625 "x": 8.0,
1626 "y": 61.0
1627 },
1628 "layoutNodeIndex": 6,
1629 "nodeName": "IFRAME",
1630 "nodeType": 1,
1631 "nodeValue": "",
1632 "styleIndex": 3
1633 }
1634 )raw_string",
1635
1636 R"raw_string({
1637 "auxProperties": {
1638 "baseURL": "http://127.0.0.1/iframe.html",
1639 "documentURL": "http://127.0.0.1/iframe.html"
1640 },
1641 "backendNodeId": 21,
1642 "boundingBox": {
1643 "height": 200.0,
1644 "width": 400.0,
1645 "x": 0.0,
1646 "y": 0.0
1647 },
1648 "childNodeIndexes": [ 19 ],
1649 "layoutNodeIndex": 7,
1650 "nodeName": "#document",
1651 "nodeType": 9,
1652 "nodeValue": ""
1653 }
1654 )raw_string",
1655
1656 R"raw_string({
1657 "attributes": [ ],
1658 "auxProperties": {
1659 "frameId": "?"
1660 },
1661 "backendNodeId": 22,
1662 "boundingBox": {
1663 "height": 200.0,
1664 "width": 400.0,
1665 "x": 10.0,
1666 "y": 63.0
1667 },
1668 "childNodeIndexes": [ 20, 21 ],
1669 "layoutNodeIndex": 8,
1670 "nodeName": "HTML",
1671 "nodeType": 1,
1672 "nodeValue": "",
1673 "styleIndex": 4
1674 }
1675 )raw_string",
1676
1677 R"raw_string({
1678 "attributes": [ ],
1679 "auxProperties": {
1680
1681 },
1682 "backendNodeId": 23,
1683 "nodeName": "HEAD",
1684 "nodeType": 1,
1685 "nodeValue": ""
1686 }
1687 )raw_string",
1688
1689 R"raw_string({
1690 "attributes": [ ],
1691 "auxProperties": {
1692
1693 },
1694 "backendNodeId": 24,
1695 "boundingBox": {
1696 "height": 171.0,
1697 "width": 384.0,
1698 "x": 18.0,
1699 "y": 71.0
1700 },
1701 "childNodeIndexes": [ 22, 23, 25 ],
1702 "layoutNodeIndex": 9,
1703 "nodeName": "BODY",
1704 "nodeType": 1,
1705 "nodeValue": "",
1706 "styleIndex": 5
1707 }
1708 )raw_string",
1709
1710 R"raw_string({
1711 "auxProperties": {
1712
1713 },
1714 "backendNodeId": 25,
1715 "nodeName": "#text",
1716 "nodeType": 3,
1717 "nodeValue": "\n"
1718 }
1719 )raw_string",
1720
1721 R"raw_string({
1722 "attributes": [ ],
1723 "auxProperties": {
1724
1725 },
1726 "backendNodeId": 26,
1727 "boundingBox": {
1728 "height": 37.0,
1729 "width": 384.0,
1730 "x": 18.0,
1731 "y": 71.0
1732 },
1733 "childNodeIndexes": [ 24 ],
1734 "layoutNodeIndex": 10,
1735 "nodeName": "H1",
1736 "nodeType": 1,
1737 "nodeValue": "",
1738 "styleIndex": 6
1739 }
1740 )raw_string",
1741
1742 R"raw_string({
1743 "auxProperties": {
1744
1745 },
1746 "backendNodeId": 27,
1747 "boundingBox": {
1748 "height": 36.0,
1749 "width": 308.0,
1750 "x": 8.0,
1751 "y": 8.0
1752 },
1753 "inlineTextNodes": [ {
1754 "boundingBox": {
1755 "height": 36.0,
1756 "width": 307.734375,
1757 "x": 8.0,
1758 "y": 8.0
1759 },
1760 "numCharacters": 22,
1761 "startCharacterIndex": 0
1762 } ],
1763 "layoutNodeIndex": 11,
1764 "layoutText": "Hello from the iframe!",
1765 "nodeName": "#text",
1766 "nodeType": 3,
1767 "nodeValue": "Hello from the iframe!",
1768 "styleIndex": 6
1769 }
1770 )raw_string",
1771
1772 R"raw_string({
1773 "auxProperties": {
1774
1775 },
1776 "backendNodeId": 28,
1777 "nodeName": "#text",
1778 "nodeType": 3,
1779 "nodeValue": "\n\n\n"
1780 }
1781 )raw_string",
1782
1783 R"raw_string({
1784 "auxProperties": {
1785
1786 },
1787 "backendNodeId": 29,
1788 "boundingBox": {
1789 "height": 0.0,
1790 "width": 0.0,
1791 "x": 0.0,
1792 "y": 0.0
1793 },
1794 "layoutNodeIndex": 12,
1795 "layoutText": "\n",
1796 "nodeName": "#text",
1797 "nodeType": 3,
1798 "nodeValue": "\n",
1799 "styleIndex": 0
1800 }
1801 )raw_string",
1802
1803 R"raw_string({
1804 "attributes": [ {
1805 "name": "id",
1806 "value": "id2"
1807 } ],
1808 "auxProperties": {
1809
1810 },
1811 "backendNodeId": 30,
1812 "boundingBox": {
1813 "height": 97.0,
1814 "width": 784.0,
1815 "x": 8.0,
1816 "y": 265.0
1817 },
1818 "childNodeIndexes": [ 28, 29, 48 ],
1819 "layoutNodeIndex": 13,
1820 "nodeName": "DIV",
1821 "nodeType": 1,
1822 "nodeValue": "",
1823 "styleIndex": 0
1824 }
1825 )raw_string",
1826
1827 R"raw_string({
1828 "auxProperties": {
1829
1830 },
1831 "backendNodeId": 31,
1832 "nodeName": "#text",
1833 "nodeType": 3,
1834 "nodeValue": "\n "
1835 }
1836 )raw_string",
1837
1838 R"raw_string({
1839 "attributes": [ {
1840 "name": "id",
1841 "value": "id3"
1842 } ],
1843 "auxProperties": {
1844
1845 },
1846 "backendNodeId": 32,
1847 "boundingBox": {
1848 "height": 97.0,
1849 "width": 784.0,
1850 "x": 8.0,
1851 "y": 265.0
1852 },
1853 "childNodeIndexes": [ 30, 31, 47 ],
1854 "layoutNodeIndex": 14,
1855 "nodeName": "DIV",
1856 "nodeType": 1,
1857 "nodeValue": "",
1858 "styleIndex": 0
1859 }
1860 )raw_string",
1861
1862 R"raw_string({
1863 "auxProperties": {
1864
1865 },
1866 "backendNodeId": 33,
1867 "nodeName": "#text",
1868 "nodeType": 3,
1869 "nodeValue": "\n "
1870 }
1871 )raw_string",
1872
1873 R"raw_string({
1874 "attributes": [ {
1875 "name": "id",
1876 "value": "id4"
1877 } ],
1878 "auxProperties": {
1879
1880 },
1881 "backendNodeId": 34,
1882 "boundingBox": {
1883 "height": 97.0,
1884 "width": 784.0,
1885 "x": 8.0,
1886 "y": 265.0
1887 },
1888 "childNodeIndexes": [ 32, 33, 35, 36, 38, 39, 40, 41, 46 ],
1889 "layoutNodeIndex": 15,
1890 "nodeName": "DIV",
1891 "nodeType": 1,
1892 "nodeValue": "",
1893 "styleIndex": 0
1894 }
1895 )raw_string",
1896
1897 R"raw_string({
1898 "auxProperties": {
1899
1900 },
1901 "backendNodeId": 35,
1902 "nodeName": "#text",
1903 "nodeType": 3,
1904 "nodeValue": "\n "
1905 }
1906 )raw_string",
1907
1908 R"raw_string({
1909 "attributes": [ {
1910 "name": "href",
1911 "value": "https://www.google.com"
1912 } ],
1913 "auxProperties": {
1914
1915 },
1916 "backendNodeId": 36,
1917 "boundingBox": {
1918 "height": 17.0,
1919 "width": 112.0,
1920 "x": 8.0,
1921 "y": 265.0
1922 },
1923 "childNodeIndexes": [ 34 ],
1924 "layoutNodeIndex": 16,
1925 "nodeName": "A",
1926 "nodeType": 1,
1927 "nodeValue": "",
1928 "styleIndex": 7
1929 }
1930 )raw_string",
1931
1932 R"raw_string({
1933 "auxProperties": {
1934
1935 },
1936 "backendNodeId": 37,
1937 "boundingBox": {
1938 "height": 17.0,
1939 "width": 112.0,
1940 "x": 8.0,
1941 "y": 265.0
1942 },
1943 "inlineTextNodes": [ {
1944 "boundingBox": {
1945 "height": 16.0,
1946 "width": 112.0,
1947 "x": 8.0,
1948 "y": 265.4375
1949 },
1950 "numCharacters": 7,
1951 "startCharacterIndex": 0
1952 } ],
1953 "layoutNodeIndex": 17,
1954 "layoutText": "Google!",
1955 "nodeName": "#text",
1956 "nodeType": 3,
1957 "nodeValue": "Google!",
1958 "styleIndex": 7
1959 }
1960 )raw_string",
1961
1962 R"raw_string({
1963 "auxProperties": {
1964
1965 },
1966 "backendNodeId": 38,
1967 "boundingBox": {
1968 "height": 0.0,
1969 "width": 0.0,
1970 "x": 0.0,
1971 "y": 0.0
1972 },
1973 "layoutNodeIndex": 18,
1974 "layoutText": "\n ",
1975 "nodeName": "#text",
1976 "nodeType": 3,
1977 "nodeValue": "\n ",
1978 "styleIndex": 0
1979 }
1980 )raw_string",
1981
1982 R"raw_string({
1983 "attributes": [ ],
1984 "auxProperties": {
1985
1986 },
1987 "backendNodeId": 39,
1988 "boundingBox": {
1989 "height": 17.0,
1990 "width": 784.0,
1991 "x": 8.0,
1992 "y": 297.0
1993 },
1994 "childNodeIndexes": [ 37 ],
1995 "layoutNodeIndex": 19,
1996 "nodeName": "P",
1997 "nodeType": 1,
1998 "nodeValue": "",
1999 "styleIndex": 8
2000 }
2001 )raw_string",
2002
2003 R"raw_string({
2004 "auxProperties": {
2005
2006 },
2007 "backendNodeId": 40,
2008 "boundingBox": {
2009 "height": 17.0,
2010 "width": 192.0,
2011 "x": 8.0,
2012 "y": 297.0
2013 },
2014 "inlineTextNodes": [ {
2015 "boundingBox": {
2016 "height": 16.0,
2017 "width": 192.0,
2018 "x": 8.0,
2019 "y": 297.4375
2020 },
2021 "numCharacters": 12,
2022 "startCharacterIndex": 0
2023 } ],
2024 "layoutNodeIndex": 20,
2025 "layoutText": "A paragraph!",
2026 "nodeName": "#text",
2027 "nodeType": 3,
2028 "nodeValue": "A paragraph!",
2029 "styleIndex": 8
2030 }
2031 )raw_string",
2032
2033 R"raw_string({
2034 "auxProperties": {
2035
2036 },
2037 "backendNodeId": 41,
2038 "nodeName": "#text",
2039 "nodeType": 3,
2040 "nodeValue": "\n "
2041 }
2042 )raw_string",
2043
2044 R"raw_string({
2045 "attributes": [ ],
2046 "auxProperties": {
2047
2048 },
2049 "backendNodeId": 42,
2050 "boundingBox": {
2051 "height": 0.0,
2052 "width": 0.0,
2053 "x": 0.0,
2054 "y": 0.0
2055 },
2056 "inlineTextNodes": [ {
2057 "boundingBox": {
2058 "height": 16.0,
2059 "width": 0.0,
2060 "x": 8.0,
2061 "y": 329.4375
2062 },
2063 "numCharacters": 1,
2064 "startCharacterIndex": 0
2065 } ],
2066 "layoutNodeIndex": 21,
2067 "layoutText": "\n",
2068 "nodeName": "BR",
2069 "nodeType": 1,
2070 "nodeValue": "",
2071 "styleIndex": 3
2072 }
2073 )raw_string",
2074
2075 R"raw_string({
2076 "auxProperties": {
2077
2078 },
2079 "backendNodeId": 43,
2080 "nodeName": "#text",
2081 "nodeType": 3,
2082 "nodeValue": "\n "
2083 }
2084 )raw_string",
2085
2086 R"raw_string({
2087 "attributes": [ {
2088 "name": "class",
2089 "value": "green"
2090 } ],
2091 "auxProperties": {
2092
2093 },
2094 "backendNodeId": 44,
2095 "boundingBox": {
2096 "height": 17.0,
2097 "width": 784.0,
2098 "x": 8.0,
2099 "y": 345.0
2100 },
2101 "childNodeIndexes": [ 42, 43, 45 ],
2102 "layoutNodeIndex": 22,
2103 "nodeName": "DIV",
2104 "nodeType": 1,
2105 "nodeValue": "",
2106 "styleIndex": 9
2107 }
2108 )raw_string",
2109
2110 R"raw_string({
2111 "auxProperties": {
2112
2113 },
2114 "backendNodeId": 45,
2115 "boundingBox": {
2116 "height": 17.0,
2117 "width": 80.0,
2118 "x": 8.0,
2119 "y": 345.0
2120 },
2121 "inlineTextNodes": [ {
2122 "boundingBox": {
2123 "height": 16.0,
2124 "width": 80.0,
2125 "x": 8.0,
2126 "y": 345.4375
2127 },
2128 "numCharacters": 5,
2129 "startCharacterIndex": 0
2130 } ],
2131 "layoutNodeIndex": 23,
2132 "layoutText": "Some ",
2133 "nodeName": "#text",
2134 "nodeType": 3,
2135 "nodeValue": "Some ",
2136 "styleIndex": 9
2137 }
2138 )raw_string",
2139
2140 R"raw_string({
2141 "attributes": [ ],
2142 "auxProperties": {
2143
2144 },
2145 "backendNodeId": 46,
2146 "boundingBox": {
2147 "height": 17.0,
2148 "width": 80.0,
2149 "x": 88.0,
2150 "y": 345.0
2151 },
2152 "childNodeIndexes": [ 44 ],
2153 "layoutNodeIndex": 24,
2154 "nodeName": "EM",
2155 "nodeType": 1,
2156 "nodeValue": "",
2157 "styleIndex": 10
2158 }
2159 )raw_string",
2160
2161 R"raw_string({
2162 "auxProperties": {
2163
2164 },
2165 "backendNodeId": 47,
2166 "boundingBox": {
2167 "height": 17.0,
2168 "width": 80.0,
2169 "x": 88.0,
2170 "y": 345.0
2171 },
2172 "inlineTextNodes": [ {
2173 "boundingBox": {
2174 "height": 16.0,
2175 "width": 80.0,
2176 "x": 88.0,
2177 "y": 345.4375
2178 },
2179 "numCharacters": 5,
2180 "startCharacterIndex": 0
2181 } ],
2182 "layoutNodeIndex": 25,
2183 "layoutText": "green",
2184 "nodeName": "#text",
2185 "nodeType": 3,
2186 "nodeValue": "green",
2187 "styleIndex": 10
2188 }
2189 )raw_string",
2190
2191 R"raw_string({
2192 "auxProperties": {
2193
2194 },
2195 "backendNodeId": 48,
2196 "boundingBox": {
2197 "height": 17.0,
2198 "width": 128.0,
2199 "x": 168.0,
2200 "y": 345.0
2201 },
2202 "inlineTextNodes": [ {
2203 "boundingBox": {
2204 "height": 16.0,
2205 "width": 128.0,
2206 "x": 168.0,
2207 "y": 345.4375
2208 },
2209 "numCharacters": 8,
2210 "startCharacterIndex": 0
2211 } ],
2212 "layoutNodeIndex": 26,
2213 "layoutText": " text...",
2214 "nodeName": "#text",
2215 "nodeType": 3,
2216 "nodeValue": " text...",
2217 "styleIndex": 9
2218 }
2219 )raw_string",
2220
2221 R"raw_string({
2222 "auxProperties": {
2223
2224 },
2225 "backendNodeId": 49,
2226 "nodeName": "#text",
2227 "nodeType": 3,
2228 "nodeValue": "\n "
2229 }
2230 )raw_string",
2231
2232 R"raw_string({
2233 "auxProperties": {
2234
2235 },
2236 "backendNodeId": 50,
2237 "nodeName": "#text",
2238 "nodeType": 3,
2239 "nodeValue": "\n "
2240 }
2241 )raw_string",
2242
2243 R"raw_string({
2244 "auxProperties": {
2245
2246 },
2247 "backendNodeId": 51,
2248 "nodeName": "#text",
2249 "nodeType": 3,
2250 "nodeValue": "\n"
2251 }
2252 )raw_string",
2253
2254 R"raw_string({
2255 "auxProperties": {
2256
2257 },
2258 "backendNodeId": 52,
2259 "nodeName": "#text",
2260 "nodeType": 3,
2261 "nodeValue": "\n\n\n"
2262 }
2263 )raw_string"};
2264
2265 EXPECT_EQ(expected_dom_nodes.size(), dom_nodes.size());
2266
2267 for (size_t i = 0; i < dom_nodes.size(); i++) {
2268 std::string result_json;
2269 base::JSONWriter::WriteWithOptions(
2270 *dom_nodes[i], base::JSONWriter::OPTIONS_PRETTY_PRINT, &result_json);
2271
2272 ASSERT_LT(i, expected_dom_nodes.size());
2273 EXPECT_EQ(NormaliseJSON(expected_dom_nodes[i]), result_json)
2274 << " Node # " << i;
2275 }
2276
2277 const std::vector<std::string> expected_styles = {
2278 R"raw_string({
2279 "color": "rgb(0, 0, 0)",
2280 "display": "block",
2281 "font-family": "ahem",
2282 "font-style": "normal",
2283 "margin-bottom": "0px",
2284 "margin-left": "0px",
2285 "margin-right": "0px",
2286 "margin-top": "0px"
2287 })raw_string",
2288
2289 R"raw_string({
2290 "color": "rgb(0, 0, 0)",
2291 "display": "block",
2292 "font-family": "ahem",
2293 "font-style": "normal",
2294 "margin-bottom": "8px",
2295 "margin-left": "8px",
2296 "margin-right": "8px",
2297 "margin-top": "8px"
2298 })raw_string",
2299
2300 R"raw_string({
2301 "color": "rgb(255, 0, 0)",
2302 "display": "block",
2303 "font-family": "ahem",
2304 "font-style": "normal",
2305 "margin-bottom": "21.44px",
2306 "margin-left": "0px",
2307 "margin-right": "0px",
2308 "margin-top": "21.44px"
2309 })raw_string",
2310
2311 R"raw_string({
2312 "color": "rgb(0, 0, 0)",
2313 "display": "inline",
2314 "font-family": "ahem",
2315 "font-style": "normal",
2316 "margin-bottom": "0px",
2317 "margin-left": "0px",
2318 "margin-right": "0px",
2319 "margin-top": "0px"
2320 })raw_string",
2321
2322 R"raw_string({
2323 "color": "rgb(0, 0, 0)",
2324 "display": "block",
2325 "font-family": "\"Times New Roman\"",
2326 "font-style": "normal",
2327 "margin-bottom": "0px",
2328 "margin-left": "0px",
2329 "margin-right": "0px",
2330 "margin-top": "0px"
2331 })raw_string",
2332
2333 R"raw_string({
2334 "color": "rgb(0, 0, 0)",
2335 "display": "block",
2336 "font-family": "\"Times New Roman\"",
2337 "font-style": "normal",
2338 "margin-bottom": "8px",
2339 "margin-left": "8px",
2340 "margin-right": "8px",
2341 "margin-top": "8px"
2342 })raw_string",
2343
2344 R"raw_string({
2345 "color": "rgb(0, 0, 0)",
2346 "display": "block",
2347 "font-family": "\"Times New Roman\"",
2348 "font-style": "normal",
2349 "margin-bottom": "21.44px",
2350 "margin-left": "0px",
2351 "margin-right": "0px",
2352 "margin-top": "21.44px"
2353 })raw_string",
2354
2355 R"raw_string({
2356 "color": "rgb(0, 0, 238)",
2357 "display": "inline",
2358 "font-family": "ahem",
2359 "font-style": "normal",
2360 "margin-bottom": "0px",
2361 "margin-left": "0px",
2362 "margin-right": "0px",
2363 "margin-top": "0px"
2364 })raw_string",
2365
2366 R"raw_string({
2367 "color": "rgb(0, 0, 0)",
2368 "display": "block",
2369 "font-family": "ahem",
2370 "font-style": "normal",
2371 "margin-bottom": "16px",
2372 "margin-left": "0px",
2373 "margin-right": "0px",
2374 "margin-top": "16px"
2375 })raw_string",
2376
2377 R"raw_string({
2378 "color": "rgb(0, 128, 0)",
2379 "display": "block",
2380 "font-family": "ahem",
2381 "font-style": "normal",
2382 "margin-bottom": "0px",
2383 "margin-left": "0px",
2384 "margin-right": "0px",
2385 "margin-top": "0px"
2386 })raw_string",
2387
2388 R"raw_string({
2389 "color": "rgb(0, 128, 0)",
2390 "display": "inline",
2391 "font-family": "ahem",
2392 "font-style": "italic",
2393 "margin-bottom": "0px",
2394 "margin-left": "0px",
2395 "margin-right": "0px",
2396 "margin-top": "0px"
2397 }
2398 )raw_string"};
2399
2400 EXPECT_EQ(expected_styles.size(), computed_styles.size());
2401
2402 for (size_t i = 0; i < computed_styles.size(); i++) {
2403 std::string result_json;
2404 base::JSONWriter::WriteWithOptions(*computed_styles[i],
2405 base::JSONWriter::OPTIONS_PRETTY_PRINT,
2406 &result_json);
2407
2408 ASSERT_LT(i, expected_styles.size());
2409 EXPECT_EQ(NormaliseJSON(expected_styles[i]), result_json)
2410 << " Style # " << i;
2411 }
2412
2413 FinishAsynchronousTest();
2414 }
2415 };
2416
2417 HEADLESS_ASYNC_DEVTOOLED_TEST_F(DomTreeExtractionBrowserTest);
2418
1208 } // namespace headless 2419 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698