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

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: move aux properties back to node type 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 // Frame IDs are random.
1267 if (node_dict->HasKey("frameId"))
1268 node_dict->SetString("frameId", "?");
1269
1270 // Ports are random.
1271 std::string url;
1272 if (node_dict->GetString("baseURL", &url)) {
1273 node_dict->SetString("baseURL",
1274 GURL(url).ReplaceComponents(replace_port).spec());
1275 }
1276
1277 if (node_dict->GetString("documentURL", &url)) {
1278 node_dict->SetString("documentURL",
1279 GURL(url).ReplaceComponents(replace_port).spec());
1280 }
1281
1282 // Merge LayoutTreeNode data into the dictionary.
1283 int layout_node_index;
1284 if (node_dict->GetInteger("layoutNodeIndex", &layout_node_index)) {
1285 ASSERT_LE(0, layout_node_index);
1286 ASSERT_GT(result->GetLayoutTreeNodes()->size(),
1287 static_cast<size_t>(layout_node_index));
1288 const std::unique_ptr<dom_snapshot::LayoutTreeNode>& layout_node =
1289 (*result->GetLayoutTreeNodes())[layout_node_index];
1290
1291 node_dict->Set("boundingBox",
1292 layout_node->GetBoundingBox()->Serialize());
1293
1294 if (layout_node->HasLayoutText())
1295 node_dict->SetString("layoutText", layout_node->GetLayoutText());
1296
1297 if (layout_node->HasStyleIndex())
1298 node_dict->SetInteger("styleIndex", layout_node->GetStyleIndex());
1299
1300 if (layout_node->HasInlineTextNodes()) {
1301 std::unique_ptr<base::ListValue> inline_text_nodes(
1302 new base::ListValue());
1303 for (const std::unique_ptr<css::InlineTextBox>& inline_text_box :
1304 *layout_node->GetInlineTextNodes()) {
1305 size_t index = inline_text_nodes->GetSize();
1306 inline_text_nodes->Set(index, inline_text_box->Serialize());
1307 }
1308 node_dict->Set("inlineTextNodes", std::move(inline_text_nodes));
1309 }
1310 }
1311 }
1312
1313 std::vector<std::unique_ptr<base::DictionaryValue>> computed_styles(
1314 result->GetComputedStyles()->size());
1315
1316 for (size_t i = 0; i < result->GetComputedStyles()->size(); i++) {
1317 std::unique_ptr<base::DictionaryValue> style(new base::DictionaryValue());
1318 for (const auto& style_property :
1319 *(*result->GetComputedStyles())[i]->GetProperties()) {
1320 style->SetString(style_property->GetName(), style_property->GetValue());
1321 }
1322 computed_styles[i] = std::move(style);
1323 }
1324
1325 // TODO(eseckler): Extract expectation strings into external files to make
1326 // them easier to maintain.
1327 const std::vector<std::string> expected_dom_nodes = {
1328 R"raw_string({
1329 "backendNodeId": 3,
1330 "baseURL": "http://127.0.0.1/dom_tree_test.html",
1331 "boundingBox": {
1332 "height": 600.0,
1333 "width": 800.0,
1334 "x": 0.0,
1335 "y": 0.0
1336 },
1337 "childNodeIndexes": [ 1 ],
1338 "documentURL": "http://127.0.0.1/dom_tree_test.html",
1339 "layoutNodeIndex": 0,
1340 "nodeName": "#document",
1341 "nodeType": 9,
1342 "nodeValue": ""
1343 }
1344 )raw_string",
1345
1346 R"raw_string({
1347 "backendNodeId": 4,
1348 "boundingBox": {
1349 "height": 600.0,
1350 "width": 800.0,
1351 "x": 0.0,
1352 "y": 0.0
1353 },
1354 "childNodeIndexes": [ 2, 9, 10 ],
1355 "frameId": "?",
1356 "layoutNodeIndex": 1,
1357 "nodeName": "HTML",
1358 "nodeType": 1,
1359 "nodeValue": "",
1360 "styleIndex": 0
1361 }
1362 )raw_string",
1363
1364 R"raw_string({
1365 "backendNodeId": 5,
1366 "childNodeIndexes": [ 3, 4, 6, 7, 8 ],
1367 "nodeName": "HEAD",
1368 "nodeType": 1,
1369 "nodeValue": ""
1370 }
1371 )raw_string",
1372
1373 R"raw_string({
1374 "backendNodeId": 6,
1375 "nodeName": "#text",
1376 "nodeType": 3,
1377 "nodeValue": "\n"
1378 }
1379 )raw_string",
1380
1381 R"raw_string({
1382 "backendNodeId": 7,
1383 "childNodeIndexes": [ 5 ],
1384 "nodeName": "TITLE",
1385 "nodeType": 1,
1386 "nodeValue": ""
1387 }
1388 )raw_string",
1389
1390 R"raw_string({
1391 "backendNodeId": 8,
1392 "nodeName": "#text",
1393 "nodeType": 3,
1394 "nodeValue": "Hello world!"
1395 }
1396 )raw_string",
1397
1398 R"raw_string({
1399 "backendNodeId": 9,
1400 "nodeName": "#text",
1401 "nodeType": 3,
1402 "nodeValue": "\n"
1403 }
1404 )raw_string",
1405
1406 R"raw_string({
1407 "attributes": [ {
1408 "name": "href",
1409 "value": "dom_tree_test.css"
1410 }, {
1411 "name": "rel",
1412 "value": "stylesheet"
1413 }, {
1414 "name": "type",
1415 "value": "text/css"
1416 } ],
1417 "backendNodeId": 10,
1418 "nodeName": "LINK",
1419 "nodeType": 1,
1420 "nodeValue": ""
1421 }
1422 )raw_string",
1423
1424 R"raw_string({
1425 "backendNodeId": 11,
1426 "nodeName": "#text",
1427 "nodeType": 3,
1428 "nodeValue": "\n"
1429 }
1430 )raw_string",
1431
1432 R"raw_string({
1433 "backendNodeId": 12,
1434 "nodeName": "#text",
1435 "nodeType": 3,
1436 "nodeValue": "\n"
1437 }
1438 )raw_string",
1439
1440 R"raw_string({
1441 "backendNodeId": 13,
1442 "boundingBox": {
1443 "height": 584.0,
1444 "width": 784.0,
1445 "x": 8.0,
1446 "y": 8.0
1447 },
1448 "childNodeIndexes": [ 11, 12 ],
1449 "layoutNodeIndex": 2,
1450 "nodeName": "BODY",
1451 "nodeType": 1,
1452 "nodeValue": "",
1453 "styleIndex": 1
1454 }
1455 )raw_string",
1456
1457 R"raw_string({
1458 "backendNodeId": 14,
1459 "nodeName": "#text",
1460 "nodeType": 3,
1461 "nodeValue": "\n"
1462 }
1463 )raw_string",
1464
1465 R"raw_string({
1466 "attributes": [ {
1467 "name": "id",
1468 "value": "id1"
1469 } ],
1470 "backendNodeId": 15,
1471 "boundingBox": {
1472 "height": 354.0,
1473 "width": 784.0,
1474 "x": 8.0,
1475 "y": 8.0
1476 },
1477 "childNodeIndexes": [ 13, 14, 16, 17, 26, 27, 49 ],
1478 "layoutNodeIndex": 3,
1479 "nodeName": "DIV",
1480 "nodeType": 1,
1481 "nodeValue": "",
1482 "styleIndex": 0
1483 }
1484 )raw_string",
1485
1486 R"raw_string({
1487 "backendNodeId": 16,
1488 "nodeName": "#text",
1489 "nodeType": 3,
1490 "nodeValue": "\n"
1491 }
1492 )raw_string",
1493
1494 R"raw_string({
1495 "attributes": [ {
1496 "name": "class",
1497 "value": "red"
1498 } ],
1499 "backendNodeId": 17,
1500 "boundingBox": {
1501 "height": 32.0,
1502 "width": 784.0,
1503 "x": 8.0,
1504 "y": 8.0
1505 },
1506 "childNodeIndexes": [ 15 ],
1507 "layoutNodeIndex": 4,
1508 "nodeName": "H1",
1509 "nodeType": 1,
1510 "nodeValue": "",
1511 "styleIndex": 2
1512 }
1513 )raw_string",
1514
1515 R"raw_string({
1516 "backendNodeId": 18,
1517 "boundingBox": {
1518 "height": 32.0,
1519 "width": 320.0,
1520 "x": 8.0,
1521 "y": 8.0
1522 },
1523 "inlineTextNodes": [ {
1524 "boundingBox": {
1525 "height": 32.0,
1526 "width": 320.0,
1527 "x": 8.0,
1528 "y": 8.0
1529 },
1530 "numCharacters": 10,
1531 "startCharacterIndex": 0
1532 } ],
1533 "layoutNodeIndex": 5,
1534 "layoutText": "Some text.",
1535 "nodeName": "#text",
1536 "nodeType": 3,
1537 "nodeValue": "Some text.",
1538 "styleIndex": 2
1539 }
1540 )raw_string",
1541
1542 R"raw_string({
1543 "backendNodeId": 19,
1544 "nodeName": "#text",
1545 "nodeType": 3,
1546 "nodeValue": "\n"
1547 }
1548 )raw_string",
1549
1550 R"raw_string({
1551 "attributes": [ {
1552 "name": "src",
1553 "value": "/iframe.html"
1554 }, {
1555 "name": "width",
1556 "value": "400"
1557 }, {
1558 "name": "height",
1559 "value": "200"
1560 } ],
1561 "backendNodeId": 20,
1562 "boundingBox": {
1563 "height": 205.0,
1564 "width": 404.0,
1565 "x": 8.0,
1566 "y": 61.0
1567 },
1568 "contentDocumentIndex": 18,
1569 "frameId": "?",
1570 "layoutNodeIndex": 6,
1571 "nodeName": "IFRAME",
1572 "nodeType": 1,
1573 "nodeValue": "",
1574 "styleIndex": 3
1575 }
1576 )raw_string",
1577
1578 R"raw_string({
1579 "backendNodeId": 21,
1580 "baseURL": "http://127.0.0.1/iframe.html",
1581 "boundingBox": {
1582 "height": 200.0,
1583 "width": 400.0,
1584 "x": 0.0,
1585 "y": 0.0
1586 },
1587 "childNodeIndexes": [ 19 ],
1588 "documentURL": "http://127.0.0.1/iframe.html",
1589 "layoutNodeIndex": 7,
1590 "nodeName": "#document",
1591 "nodeType": 9,
1592 "nodeValue": ""
1593 }
1594 )raw_string",
1595
1596 R"raw_string({
1597 "backendNodeId": 22,
1598 "boundingBox": {
1599 "height": 200.0,
1600 "width": 400.0,
1601 "x": 10.0,
1602 "y": 63.0
1603 },
1604 "childNodeIndexes": [ 20, 21 ],
1605 "frameId": "?",
1606 "layoutNodeIndex": 8,
1607 "nodeName": "HTML",
1608 "nodeType": 1,
1609 "nodeValue": "",
1610 "styleIndex": 4
1611 }
1612 )raw_string",
1613
1614 R"raw_string({
1615 "backendNodeId": 23,
1616 "nodeName": "HEAD",
1617 "nodeType": 1,
1618 "nodeValue": ""
1619 }
1620 )raw_string",
1621
1622 R"raw_string({
1623 "backendNodeId": 24,
1624 "boundingBox": {
1625 "height": 171.0,
1626 "width": 384.0,
1627 "x": 18.0,
1628 "y": 71.0
1629 },
1630 "childNodeIndexes": [ 22, 23, 25 ],
1631 "layoutNodeIndex": 9,
1632 "nodeName": "BODY",
1633 "nodeType": 1,
1634 "nodeValue": "",
1635 "styleIndex": 5
1636 }
1637 )raw_string",
1638
1639 R"raw_string({
1640 "backendNodeId": 25,
1641 "nodeName": "#text",
1642 "nodeType": 3,
1643 "nodeValue": "\n"
1644 }
1645 )raw_string",
1646
1647 R"raw_string({
1648 "backendNodeId": 26,
1649 "boundingBox": {
1650 "height": 37.0,
1651 "width": 384.0,
1652 "x": 18.0,
1653 "y": 71.0
1654 },
1655 "childNodeIndexes": [ 24 ],
1656 "layoutNodeIndex": 10,
1657 "nodeName": "H1",
1658 "nodeType": 1,
1659 "nodeValue": "",
1660 "styleIndex": 6
1661 }
1662 )raw_string",
1663
1664 R"raw_string({
1665 "backendNodeId": 27,
1666 "boundingBox": {
1667 "height": 36.0,
1668 "width": 308.0,
1669 "x": 8.0,
1670 "y": 8.0
1671 },
1672 "inlineTextNodes": [ {
1673 "boundingBox": {
1674 "height": 36.0,
1675 "width": 307.734375,
1676 "x": 8.0,
1677 "y": 8.0
1678 },
1679 "numCharacters": 22,
1680 "startCharacterIndex": 0
1681 } ],
1682 "layoutNodeIndex": 11,
1683 "layoutText": "Hello from the iframe!",
1684 "nodeName": "#text",
1685 "nodeType": 3,
1686 "nodeValue": "Hello from the iframe!",
1687 "styleIndex": 6
1688 }
1689 )raw_string",
1690
1691 R"raw_string({
1692 "backendNodeId": 28,
1693 "nodeName": "#text",
1694 "nodeType": 3,
1695 "nodeValue": "\n\n\n"
1696 }
1697 )raw_string",
1698
1699 R"raw_string({
1700 "backendNodeId": 29,
1701 "boundingBox": {
1702 "height": 0.0,
1703 "width": 0.0,
1704 "x": 0.0,
1705 "y": 0.0
1706 },
1707 "layoutNodeIndex": 12,
1708 "layoutText": "\n",
1709 "nodeName": "#text",
1710 "nodeType": 3,
1711 "nodeValue": "\n",
1712 "styleIndex": 0
1713 }
1714 )raw_string",
1715
1716 R"raw_string({
1717 "attributes": [ {
1718 "name": "id",
1719 "value": "id2"
1720 } ],
1721 "backendNodeId": 30,
1722 "boundingBox": {
1723 "height": 97.0,
1724 "width": 784.0,
1725 "x": 8.0,
1726 "y": 265.0
1727 },
1728 "childNodeIndexes": [ 28, 29, 48 ],
1729 "layoutNodeIndex": 13,
1730 "nodeName": "DIV",
1731 "nodeType": 1,
1732 "nodeValue": "",
1733 "styleIndex": 0
1734 }
1735 )raw_string",
1736
1737 R"raw_string({
1738 "backendNodeId": 31,
1739 "nodeName": "#text",
1740 "nodeType": 3,
1741 "nodeValue": "\n "
1742 }
1743 )raw_string",
1744
1745 R"raw_string({
1746 "attributes": [ {
1747 "name": "id",
1748 "value": "id3"
1749 } ],
1750 "backendNodeId": 32,
1751 "boundingBox": {
1752 "height": 97.0,
1753 "width": 784.0,
1754 "x": 8.0,
1755 "y": 265.0
1756 },
1757 "childNodeIndexes": [ 30, 31, 47 ],
1758 "layoutNodeIndex": 14,
1759 "nodeName": "DIV",
1760 "nodeType": 1,
1761 "nodeValue": "",
1762 "styleIndex": 0
1763 }
1764 )raw_string",
1765
1766 R"raw_string({
1767 "backendNodeId": 33,
1768 "nodeName": "#text",
1769 "nodeType": 3,
1770 "nodeValue": "\n "
1771 }
1772 )raw_string",
1773
1774 R"raw_string({
1775 "attributes": [ {
1776 "name": "id",
1777 "value": "id4"
1778 } ],
1779 "backendNodeId": 34,
1780 "boundingBox": {
1781 "height": 97.0,
1782 "width": 784.0,
1783 "x": 8.0,
1784 "y": 265.0
1785 },
1786 "childNodeIndexes": [ 32, 33, 35, 36, 38, 39, 40, 41, 46 ],
1787 "layoutNodeIndex": 15,
1788 "nodeName": "DIV",
1789 "nodeType": 1,
1790 "nodeValue": "",
1791 "styleIndex": 0
1792 }
1793 )raw_string",
1794
1795 R"raw_string({
1796 "backendNodeId": 35,
1797 "nodeName": "#text",
1798 "nodeType": 3,
1799 "nodeValue": "\n "
1800 }
1801 )raw_string",
1802
1803 R"raw_string({
1804 "attributes": [ {
1805 "name": "href",
1806 "value": "https://www.google.com"
1807 } ],
1808 "backendNodeId": 36,
1809 "boundingBox": {
1810 "height": 17.0,
1811 "width": 112.0,
1812 "x": 8.0,
1813 "y": 265.0
1814 },
1815 "childNodeIndexes": [ 34 ],
1816 "layoutNodeIndex": 16,
1817 "nodeName": "A",
1818 "nodeType": 1,
1819 "nodeValue": "",
1820 "styleIndex": 7
1821 }
1822 )raw_string",
1823
1824 R"raw_string({
1825 "backendNodeId": 37,
1826 "boundingBox": {
1827 "height": 17.0,
1828 "width": 112.0,
1829 "x": 8.0,
1830 "y": 265.0
1831 },
1832 "inlineTextNodes": [ {
1833 "boundingBox": {
1834 "height": 16.0,
1835 "width": 112.0,
1836 "x": 8.0,
1837 "y": 265.4375
1838 },
1839 "numCharacters": 7,
1840 "startCharacterIndex": 0
1841 } ],
1842 "layoutNodeIndex": 17,
1843 "layoutText": "Google!",
1844 "nodeName": "#text",
1845 "nodeType": 3,
1846 "nodeValue": "Google!",
1847 "styleIndex": 7
1848 }
1849 )raw_string",
1850
1851 R"raw_string({
1852 "backendNodeId": 38,
1853 "boundingBox": {
1854 "height": 0.0,
1855 "width": 0.0,
1856 "x": 0.0,
1857 "y": 0.0
1858 },
1859 "layoutNodeIndex": 18,
1860 "layoutText": "\n ",
1861 "nodeName": "#text",
1862 "nodeType": 3,
1863 "nodeValue": "\n ",
1864 "styleIndex": 0
1865 }
1866 )raw_string",
1867
1868 R"raw_string({
1869 "backendNodeId": 39,
1870 "boundingBox": {
1871 "height": 17.0,
1872 "width": 784.0,
1873 "x": 8.0,
1874 "y": 297.0
1875 },
1876 "childNodeIndexes": [ 37 ],
1877 "layoutNodeIndex": 19,
1878 "nodeName": "P",
1879 "nodeType": 1,
1880 "nodeValue": "",
1881 "styleIndex": 8
1882 }
1883 )raw_string",
1884
1885 R"raw_string({
1886 "backendNodeId": 40,
1887 "boundingBox": {
1888 "height": 17.0,
1889 "width": 192.0,
1890 "x": 8.0,
1891 "y": 297.0
1892 },
1893 "inlineTextNodes": [ {
1894 "boundingBox": {
1895 "height": 16.0,
1896 "width": 192.0,
1897 "x": 8.0,
1898 "y": 297.4375
1899 },
1900 "numCharacters": 12,
1901 "startCharacterIndex": 0
1902 } ],
1903 "layoutNodeIndex": 20,
1904 "layoutText": "A paragraph!",
1905 "nodeName": "#text",
1906 "nodeType": 3,
1907 "nodeValue": "A paragraph!",
1908 "styleIndex": 8
1909 }
1910 )raw_string",
1911
1912 R"raw_string({
1913 "backendNodeId": 41,
1914 "nodeName": "#text",
1915 "nodeType": 3,
1916 "nodeValue": "\n "
1917 }
1918 )raw_string",
1919
1920 R"raw_string({
1921 "backendNodeId": 42,
1922 "boundingBox": {
1923 "height": 0.0,
1924 "width": 0.0,
1925 "x": 0.0,
1926 "y": 0.0
1927 },
1928 "inlineTextNodes": [ {
1929 "boundingBox": {
1930 "height": 16.0,
1931 "width": 0.0,
1932 "x": 8.0,
1933 "y": 329.4375
1934 },
1935 "numCharacters": 1,
1936 "startCharacterIndex": 0
1937 } ],
1938 "layoutNodeIndex": 21,
1939 "layoutText": "\n",
1940 "nodeName": "BR",
1941 "nodeType": 1,
1942 "nodeValue": "",
1943 "styleIndex": 3
1944 }
1945 )raw_string",
1946
1947 R"raw_string({
1948 "backendNodeId": 43,
1949 "nodeName": "#text",
1950 "nodeType": 3,
1951 "nodeValue": "\n "
1952 }
1953 )raw_string",
1954
1955 R"raw_string({
1956 "attributes": [ {
1957 "name": "class",
1958 "value": "green"
1959 } ],
1960 "backendNodeId": 44,
1961 "boundingBox": {
1962 "height": 17.0,
1963 "width": 784.0,
1964 "x": 8.0,
1965 "y": 345.0
1966 },
1967 "childNodeIndexes": [ 42, 43, 45 ],
1968 "layoutNodeIndex": 22,
1969 "nodeName": "DIV",
1970 "nodeType": 1,
1971 "nodeValue": "",
1972 "styleIndex": 9
1973 }
1974 )raw_string",
1975
1976 R"raw_string({
1977 "backendNodeId": 45,
1978 "boundingBox": {
1979 "height": 17.0,
1980 "width": 80.0,
1981 "x": 8.0,
1982 "y": 345.0
1983 },
1984 "inlineTextNodes": [ {
1985 "boundingBox": {
1986 "height": 16.0,
1987 "width": 80.0,
1988 "x": 8.0,
1989 "y": 345.4375
1990 },
1991 "numCharacters": 5,
1992 "startCharacterIndex": 0
1993 } ],
1994 "layoutNodeIndex": 23,
1995 "layoutText": "Some ",
1996 "nodeName": "#text",
1997 "nodeType": 3,
1998 "nodeValue": "Some ",
1999 "styleIndex": 9
2000 }
2001 )raw_string",
2002
2003 R"raw_string({
2004 "backendNodeId": 46,
2005 "boundingBox": {
2006 "height": 17.0,
2007 "width": 80.0,
2008 "x": 88.0,
2009 "y": 345.0
2010 },
2011 "childNodeIndexes": [ 44 ],
2012 "layoutNodeIndex": 24,
2013 "nodeName": "EM",
2014 "nodeType": 1,
2015 "nodeValue": "",
2016 "styleIndex": 10
2017 }
2018 )raw_string",
2019
2020 R"raw_string({
2021 "backendNodeId": 47,
2022 "boundingBox": {
2023 "height": 17.0,
2024 "width": 80.0,
2025 "x": 88.0,
2026 "y": 345.0
2027 },
2028 "inlineTextNodes": [ {
2029 "boundingBox": {
2030 "height": 16.0,
2031 "width": 80.0,
2032 "x": 88.0,
2033 "y": 345.4375
2034 },
2035 "numCharacters": 5,
2036 "startCharacterIndex": 0
2037 } ],
2038 "layoutNodeIndex": 25,
2039 "layoutText": "green",
2040 "nodeName": "#text",
2041 "nodeType": 3,
2042 "nodeValue": "green",
2043 "styleIndex": 10
2044 }
2045 )raw_string",
2046
2047 R"raw_string({
2048 "backendNodeId": 48,
2049 "boundingBox": {
2050 "height": 17.0,
2051 "width": 128.0,
2052 "x": 168.0,
2053 "y": 345.0
2054 },
2055 "inlineTextNodes": [ {
2056 "boundingBox": {
2057 "height": 16.0,
2058 "width": 128.0,
2059 "x": 168.0,
2060 "y": 345.4375
2061 },
2062 "numCharacters": 8,
2063 "startCharacterIndex": 0
2064 } ],
2065 "layoutNodeIndex": 26,
2066 "layoutText": " text...",
2067 "nodeName": "#text",
2068 "nodeType": 3,
2069 "nodeValue": " text...",
2070 "styleIndex": 9
2071 }
2072 )raw_string",
2073
2074 R"raw_string({
2075 "backendNodeId": 49,
2076 "nodeName": "#text",
2077 "nodeType": 3,
2078 "nodeValue": "\n "
2079 }
2080 )raw_string",
2081
2082 R"raw_string({
2083 "backendNodeId": 50,
2084 "nodeName": "#text",
2085 "nodeType": 3,
2086 "nodeValue": "\n "
2087 }
2088 )raw_string",
2089
2090 R"raw_string({
2091 "backendNodeId": 51,
2092 "nodeName": "#text",
2093 "nodeType": 3,
2094 "nodeValue": "\n"
2095 }
2096 )raw_string",
2097
2098 R"raw_string({
2099 "backendNodeId": 52,
2100 "nodeName": "#text",
2101 "nodeType": 3,
2102 "nodeValue": "\n\n\n"
2103 }
2104 )raw_string"};
2105
2106 EXPECT_EQ(expected_dom_nodes.size(), dom_nodes.size());
2107
2108 for (size_t i = 0; i < dom_nodes.size(); i++) {
2109 std::string result_json;
2110 base::JSONWriter::WriteWithOptions(
2111 *dom_nodes[i], base::JSONWriter::OPTIONS_PRETTY_PRINT, &result_json);
2112
2113 ASSERT_LT(i, expected_dom_nodes.size());
2114 EXPECT_EQ(NormaliseJSON(expected_dom_nodes[i]), result_json)
2115 << " Node # " << i;
2116 }
2117
2118 const std::vector<std::string> expected_styles = {
2119 R"raw_string({
2120 "color": "rgb(0, 0, 0)",
2121 "display": "block",
2122 "font-family": "ahem",
2123 "font-style": "normal",
2124 "margin-bottom": "0px",
2125 "margin-left": "0px",
2126 "margin-right": "0px",
2127 "margin-top": "0px"
2128 })raw_string",
2129
2130 R"raw_string({
2131 "color": "rgb(0, 0, 0)",
2132 "display": "block",
2133 "font-family": "ahem",
2134 "font-style": "normal",
2135 "margin-bottom": "8px",
2136 "margin-left": "8px",
2137 "margin-right": "8px",
2138 "margin-top": "8px"
2139 })raw_string",
2140
2141 R"raw_string({
2142 "color": "rgb(255, 0, 0)",
2143 "display": "block",
2144 "font-family": "ahem",
2145 "font-style": "normal",
2146 "margin-bottom": "21.44px",
2147 "margin-left": "0px",
2148 "margin-right": "0px",
2149 "margin-top": "21.44px"
2150 })raw_string",
2151
2152 R"raw_string({
2153 "color": "rgb(0, 0, 0)",
2154 "display": "inline",
2155 "font-family": "ahem",
2156 "font-style": "normal",
2157 "margin-bottom": "0px",
2158 "margin-left": "0px",
2159 "margin-right": "0px",
2160 "margin-top": "0px"
2161 })raw_string",
2162
2163 R"raw_string({
2164 "color": "rgb(0, 0, 0)",
2165 "display": "block",
2166 "font-family": "\"Times New Roman\"",
2167 "font-style": "normal",
2168 "margin-bottom": "0px",
2169 "margin-left": "0px",
2170 "margin-right": "0px",
2171 "margin-top": "0px"
2172 })raw_string",
2173
2174 R"raw_string({
2175 "color": "rgb(0, 0, 0)",
2176 "display": "block",
2177 "font-family": "\"Times New Roman\"",
2178 "font-style": "normal",
2179 "margin-bottom": "8px",
2180 "margin-left": "8px",
2181 "margin-right": "8px",
2182 "margin-top": "8px"
2183 })raw_string",
2184
2185 R"raw_string({
2186 "color": "rgb(0, 0, 0)",
2187 "display": "block",
2188 "font-family": "\"Times New Roman\"",
2189 "font-style": "normal",
2190 "margin-bottom": "21.44px",
2191 "margin-left": "0px",
2192 "margin-right": "0px",
2193 "margin-top": "21.44px"
2194 })raw_string",
2195
2196 R"raw_string({
2197 "color": "rgb(0, 0, 238)",
2198 "display": "inline",
2199 "font-family": "ahem",
2200 "font-style": "normal",
2201 "margin-bottom": "0px",
2202 "margin-left": "0px",
2203 "margin-right": "0px",
2204 "margin-top": "0px"
2205 })raw_string",
2206
2207 R"raw_string({
2208 "color": "rgb(0, 0, 0)",
2209 "display": "block",
2210 "font-family": "ahem",
2211 "font-style": "normal",
2212 "margin-bottom": "16px",
2213 "margin-left": "0px",
2214 "margin-right": "0px",
2215 "margin-top": "16px"
2216 })raw_string",
2217
2218 R"raw_string({
2219 "color": "rgb(0, 128, 0)",
2220 "display": "block",
2221 "font-family": "ahem",
2222 "font-style": "normal",
2223 "margin-bottom": "0px",
2224 "margin-left": "0px",
2225 "margin-right": "0px",
2226 "margin-top": "0px"
2227 })raw_string",
2228
2229 R"raw_string({
2230 "color": "rgb(0, 128, 0)",
2231 "display": "inline",
2232 "font-family": "ahem",
2233 "font-style": "italic",
2234 "margin-bottom": "0px",
2235 "margin-left": "0px",
2236 "margin-right": "0px",
2237 "margin-top": "0px"
2238 }
2239 )raw_string"};
2240
2241 EXPECT_EQ(expected_styles.size(), computed_styles.size());
2242
2243 for (size_t i = 0; i < computed_styles.size(); i++) {
2244 std::string result_json;
2245 base::JSONWriter::WriteWithOptions(*computed_styles[i],
2246 base::JSONWriter::OPTIONS_PRETTY_PRINT,
2247 &result_json);
2248
2249 ASSERT_LT(i, expected_styles.size());
2250 EXPECT_EQ(NormaliseJSON(expected_styles[i]), result_json)
2251 << " Style # " << i;
2252 }
2253
2254 FinishAsynchronousTest();
2255 }
2256 };
2257
2258 HEADLESS_ASYNC_DEVTOOLED_TEST_F(DomTreeExtractionBrowserTest);
2259
1208 } // namespace headless 2260 } // namespace headless
OLDNEW
« no previous file with comments | « headless/lib/browser/headless_devtools_client_impl.cc ('k') | headless/public/headless_devtools_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698