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