| 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 .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 |
| OLD | NEW |