OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "base/command_line.h" |
5 #include "base/time.h" | 6 #include "base/time.h" |
6 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
| 8 #include "content/public/common/content_switches.h" |
7 #include "content/public/test/browser_test_utils.h" | 9 #include "content/public/test/browser_test_utils.h" |
8 #include "content/shell/shell.h" | 10 #include "content/shell/shell.h" |
9 #include "content/test/content_browser_test.h" | 11 #include "content/test/content_browser_test.h" |
10 #include "content/test/content_browser_test_utils.h" | 12 #include "content/test/content_browser_test_utils.h" |
| 13 #include "net/test/test_server.h" |
11 | 14 |
12 using std::string; | 15 using std::string; |
13 namespace content { | 16 namespace content { |
14 | 17 |
15 struct EventEntry { | 18 struct EventEntry { |
16 string type; | 19 string type; |
17 string value; | 20 string value; |
18 }; | 21 }; |
19 | 22 |
20 struct StatsUnit { | 23 struct StatsUnit { |
21 string GetString() const { | 24 string GetString() const { |
22 std::stringstream ss; | 25 std::stringstream ss; |
23 ss << "{timestamp:" << timestamp << ", values:["; | 26 ss << "{timestamp:" << timestamp << ", values:["; |
24 std::map<string, string>::const_iterator iter; | 27 std::map<string, string>::const_iterator iter; |
25 for (iter = values.begin(); iter != values.end(); iter++) { | 28 for (iter = values.begin(); iter != values.end(); iter++) { |
26 ss << "'" << iter->first << "','" << iter->second << "',"; | 29 ss << "'" << iter->first << "','" << iter->second << "',"; |
27 } | 30 } |
28 ss << "]}"; | 31 ss << "]}"; |
29 return ss.str(); | 32 return ss.str(); |
30 } | 33 } |
31 | 34 |
32 int64 timestamp; | 35 int64 timestamp; |
33 std::map<string, string> values; | 36 std::map<string, string> values; |
34 }; | 37 }; |
35 | 38 |
36 struct StatsEntry { | 39 struct StatsEntry { |
37 string type; | 40 string type; |
38 string id; | 41 string id; |
39 StatsUnit local; | 42 StatsUnit stats; |
40 StatsUnit remote; | |
41 }; | 43 }; |
42 | 44 |
43 typedef std::map<string, std::vector<string> > StatsMap; | 45 typedef std::map<string, std::vector<string> > StatsMap; |
44 | 46 |
45 class PeerConnectionEntry { | 47 class PeerConnectionEntry { |
46 public: | 48 public: |
47 PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {} | 49 PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {} |
48 | 50 |
49 void AddEvent(const string& type, const string& value) { | 51 void AddEvent(const string& type, const string& value) { |
50 EventEntry entry = {type, value}; | 52 EventEntry entry = {type, value}; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 std::map<string, StatsMap> stats_; | 86 std::map<string, StatsMap> stats_; |
85 }; | 87 }; |
86 | 88 |
87 static const int64 FAKE_TIME_STAMP = 0; | 89 static const int64 FAKE_TIME_STAMP = 0; |
88 | 90 |
89 class WebRTCInternalsBrowserTest: public ContentBrowserTest { | 91 class WebRTCInternalsBrowserTest: public ContentBrowserTest { |
90 public: | 92 public: |
91 WebRTCInternalsBrowserTest() {} | 93 WebRTCInternalsBrowserTest() {} |
92 virtual ~WebRTCInternalsBrowserTest() {} | 94 virtual ~WebRTCInternalsBrowserTest() {} |
93 | 95 |
| 96 virtual void SetUpOnMainThread() OVERRIDE { |
| 97 // We need fake devices in this test since we want to run on naked VMs. We |
| 98 // assume this switch is set by default in content_browsertests. |
| 99 ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch( |
| 100 switches::kUseFakeDeviceForMediaStream)); |
| 101 |
| 102 ASSERT_TRUE(test_server()->Start()); |
| 103 } |
| 104 |
94 protected: | 105 protected: |
95 bool ExecuteJavascript(const string& javascript) { | 106 bool ExecuteJavascript(const string& javascript) { |
96 return ExecuteScript(shell()->web_contents(), javascript); | 107 return ExecuteScript(shell()->web_contents(), javascript); |
97 } | 108 } |
98 | 109 |
| 110 void ExpectTitle(const std::string& expected_title) const { |
| 111 string16 expected_title16(ASCIIToUTF16(expected_title)); |
| 112 TitleWatcher title_watcher(shell()->web_contents(), expected_title16); |
| 113 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle()); |
| 114 } |
| 115 |
99 // Execute the javascript of addPeerConnection. | 116 // Execute the javascript of addPeerConnection. |
100 void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) { | 117 void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) { |
101 std::stringstream ss; | 118 std::stringstream ss; |
102 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " << | 119 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " << |
103 "url:'u', servers:'s', constraints:'c'}"; | 120 "url:'u', servers:'s', constraints:'c'}"; |
104 ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");")); | 121 ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");")); |
105 } | 122 } |
106 | 123 |
107 // Execute the javascript of removePeerConnection. | 124 // Execute the javascript of removePeerConnection. |
108 void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) { | 125 void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << | 180 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << |
164 ", type:'" << type << "', value:'" << value << "'}"; | 181 ", type:'" << type << "', value:'" << value << "'}"; |
165 ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")")); | 182 ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")")); |
166 | 183 |
167 VerifyPeerConnectionEntry(pc); | 184 VerifyPeerConnectionEntry(pc); |
168 } | 185 } |
169 | 186 |
170 // Execute addStats and verifies that the stats table has the right content. | 187 // Execute addStats and verifies that the stats table has the right content. |
171 void ExecuteAndVerifyAddStats( | 188 void ExecuteAndVerifyAddStats( |
172 PeerConnectionEntry& pc, const string& type, const string& id, | 189 PeerConnectionEntry& pc, const string& type, const string& id, |
173 StatsUnit& local, StatsUnit& remote) { | 190 StatsUnit& stats) { |
174 StatsEntry entry = {type, id, local, remote}; | 191 StatsEntry entry = {type, id, stats}; |
175 | 192 |
176 // Adds each new value to the map of stats history. | 193 // Adds each new value to the map of stats history. |
177 std::map<string, string>::iterator iter; | 194 std::map<string, string>::iterator iter; |
178 for (iter = local.values.begin(); iter != local.values.end(); iter++) { | 195 for (iter = stats.values.begin(); iter != stats.values.end(); iter++) { |
179 pc.stats_[type + "-" + id][iter->first].push_back(iter->second); | 196 pc.stats_[type + "-" + id][iter->first].push_back(iter->second); |
180 } | 197 } |
181 for (iter = remote.values.begin(); iter != remote.values.end(); iter++) { | |
182 pc.stats_[type + "-" + id][iter->first].push_back(iter->second); | |
183 } | |
184 | |
185 std::stringstream ss; | 198 std::stringstream ss; |
186 ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << "," | 199 ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << "," |
187 "reports:[" << "{id:'" << id << "', type:'" << type << "', " | 200 "reports:[" << "{id:'" << id << "', type:'" << type << "', " |
188 "local:" << local.GetString() << ", " | 201 "stats:" << stats.GetString() << "}]}"; |
189 "remote:" << remote.GetString() << "}]}"; | |
190 | 202 |
191 ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")")); | 203 ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")")); |
192 VerifyStatsTable(pc, entry); | 204 VerifyStatsTable(pc, entry); |
193 } | 205 } |
194 | 206 |
195 | 207 |
196 // Verifies that the stats table has the right content. | 208 // Verifies that the stats table has the right content. |
197 void VerifyStatsTable(const PeerConnectionEntry& pc, | 209 void VerifyStatsTable(const PeerConnectionEntry& pc, |
198 const StatsEntry& report) { | 210 const StatsEntry& report) { |
199 string table_id = | 211 string table_id = |
200 pc.getIdString() + "-table-" + report.type + "-" + report.id; | 212 pc.getIdString() + "-table-" + report.type + "-" + report.id; |
201 VerifyElementWithId(table_id); | 213 VerifyElementWithId(table_id); |
202 | 214 |
203 std::map<string, string>::const_iterator iter; | 215 std::map<string, string>::const_iterator iter; |
204 for (iter = report.local.values.begin(); | 216 for (iter = report.stats.values.begin(); |
205 iter != report.local.values.end(); iter++) { | 217 iter != report.stats.values.end(); iter++) { |
206 VerifyStatsTableRow(table_id, iter->first, iter->second); | |
207 } | |
208 for (iter = report.remote.values.begin(); | |
209 iter != report.remote.values.end(); iter++) { | |
210 VerifyStatsTableRow(table_id, iter->first, iter->second); | 218 VerifyStatsTableRow(table_id, iter->first, iter->second); |
211 } | 219 } |
212 } | 220 } |
213 | 221 |
214 // Verifies that the row named as |name| of the stats table |table_id| has | 222 // Verifies that the row named as |name| of the stats table |table_id| has |
215 // the correct content as |name| : |value|. | 223 // the correct content as |name| : |value|. |
216 void VerifyStatsTableRow(const string& table_id, | 224 void VerifyStatsTableRow(const string& table_id, |
217 const string& name, | 225 const string& name, |
218 const string& value) { | 226 const string& value) { |
219 VerifyElementWithId(table_id + "-" + name); | 227 VerifyElementWithId(table_id + "-" + name); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 // Tests that adding random named stats updates the dataSeries and graphs. | 336 // Tests that adding random named stats updates the dataSeries and graphs. |
329 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddStats) { | 337 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, AddStats) { |
330 GURL url("chrome://webrtc-internals"); | 338 GURL url("chrome://webrtc-internals"); |
331 NavigateToURL(shell(), url); | 339 NavigateToURL(shell(), url); |
332 | 340 |
333 PeerConnectionEntry pc(1, 0); | 341 PeerConnectionEntry pc(1, 0); |
334 ExecuteAddPeerConnectionJs(pc); | 342 ExecuteAddPeerConnectionJs(pc); |
335 | 343 |
336 const string type = "ssrc"; | 344 const string type = "ssrc"; |
337 const string id = "1234"; | 345 const string id = "1234"; |
338 StatsUnit local = {FAKE_TIME_STAMP}; | 346 StatsUnit stats = {FAKE_TIME_STAMP}; |
339 local.values["bitrate"] = "2000"; | 347 stats.values["bitrate"] = "2000"; |
340 local.values["framerate"] = "30"; | 348 stats.values["framerate"] = "30"; |
341 StatsUnit remote = {FAKE_TIME_STAMP}; | |
342 remote.values["jitter"] = "1"; | |
343 remote.values["rtt"] = "20"; | |
344 | 349 |
345 // Add new stats and verify the stats table and graphs. | 350 // Add new stats and verify the stats table and graphs. |
346 ExecuteAndVerifyAddStats(pc, type, id, local, remote); | 351 ExecuteAndVerifyAddStats(pc, type, id, stats); |
347 VerifyStatsGraph(pc); | 352 VerifyStatsGraph(pc); |
348 | 353 |
349 // Update existing stats and verify the stats table and graphs. | 354 // Update existing stats and verify the stats table and graphs. |
350 local.values["bitrate"] = "2001"; | 355 stats.values["bitrate"] = "2001"; |
351 local.values["framerate"] = "31"; | 356 stats.values["framerate"] = "31"; |
352 ExecuteAndVerifyAddStats(pc, type, id, local, remote); | 357 ExecuteAndVerifyAddStats(pc, type, id, stats); |
353 VerifyStatsGraph(pc); | 358 VerifyStatsGraph(pc); |
354 } | 359 } |
355 | 360 |
356 // Tests that the bandwidth estimation values are drawn on a single graph. | 361 // Tests that the bandwidth estimation values are drawn on a single graph. |
357 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, BweCompoundGraph) { | 362 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, BweCompoundGraph) { |
358 GURL url("chrome://webrtc-internals"); | 363 GURL url("chrome://webrtc-internals"); |
359 NavigateToURL(shell(), url); | 364 NavigateToURL(shell(), url); |
360 | 365 |
361 PeerConnectionEntry pc(1, 0); | 366 PeerConnectionEntry pc(1, 0); |
362 ExecuteAddPeerConnectionJs(pc); | 367 ExecuteAddPeerConnectionJs(pc); |
363 | 368 |
364 StatsUnit local = {FAKE_TIME_STAMP}; | 369 StatsUnit stats = {FAKE_TIME_STAMP}; |
365 local.values["googAvailableSendBandwidth"] = "1000000"; | 370 stats.values["googAvailableSendBandwidth"] = "1000000"; |
366 local.values["googTargetEncBitrate"] = "1000"; | 371 stats.values["googTargetEncBitrate"] = "1000"; |
367 local.values["googActualEncBitrate"] = "1000000"; | 372 stats.values["googActualEncBitrate"] = "1000000"; |
368 local.values["googRetransmitBitrate"] = "10"; | 373 stats.values["googRetransmitBitrate"] = "10"; |
369 local.values["googTransmitBitrate"] = "1000000"; | 374 stats.values["googTransmitBitrate"] = "1000000"; |
370 const string stats_type = "bwe"; | 375 const string stats_type = "bwe"; |
371 const string stats_id = "videobwe"; | 376 const string stats_id = "videobwe"; |
372 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, local); | 377 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats); |
373 | 378 |
374 string graph_id = | 379 string graph_id = |
375 pc.getIdString() + "-" + stats_type + "-" + stats_id + "-bweCompound"; | 380 pc.getIdString() + "-" + stats_type + "-" + stats_id + "-bweCompound"; |
376 bool result = false; | 381 bool result = false; |
377 // Verify that the bweCompound graph exists. | 382 // Verify that the bweCompound graph exists. |
378 ASSERT_TRUE(ExecuteScriptAndExtractBool( | 383 ASSERT_TRUE(ExecuteScriptAndExtractBool( |
379 shell()->web_contents(), | 384 shell()->web_contents(), |
380 "window.domAutomationController.send(" | 385 "window.domAutomationController.send(" |
381 " graphViews['" + graph_id + "'] != null)", | 386 " graphViews['" + graph_id + "'] != null)", |
382 &result)); | 387 &result)); |
383 EXPECT_TRUE(result); | 388 EXPECT_TRUE(result); |
384 | 389 |
385 // Verify that the bweCompound graph contains multiple dataSeries. | 390 // Verify that the bweCompound graph contains multiple dataSeries. |
386 int count = 0; | 391 int count = 0; |
387 ASSERT_TRUE(ExecuteScriptAndExtractInt( | 392 ASSERT_TRUE(ExecuteScriptAndExtractInt( |
388 shell()->web_contents(), | 393 shell()->web_contents(), |
389 "window.domAutomationController.send(" | 394 "window.domAutomationController.send(" |
390 " graphViews['" + graph_id + "'].getDataSeriesCount())", | 395 " graphViews['" + graph_id + "'].getDataSeriesCount())", |
391 &count)); | 396 &count)); |
392 EXPECT_EQ((int)local.values.size(), count); | 397 EXPECT_EQ((int)stats.values.size(), count); |
393 } | 398 } |
394 | 399 |
395 // Tests that the total packet/byte count is converted to count per second, | 400 // Tests that the total packet/byte count is converted to count per second, |
396 // and the converted data is drawn. | 401 // and the converted data is drawn. |
397 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { | 402 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, ConvertedGraphs) { |
398 GURL url("chrome://webrtc-internals"); | 403 GURL url("chrome://webrtc-internals"); |
399 NavigateToURL(shell(), url); | 404 NavigateToURL(shell(), url); |
400 | 405 |
401 PeerConnectionEntry pc(1, 0); | 406 PeerConnectionEntry pc(1, 0); |
402 ExecuteAddPeerConnectionJs(pc); | 407 ExecuteAddPeerConnectionJs(pc); |
403 | 408 |
404 const string stats_type = "s"; | 409 const string stats_type = "s"; |
405 const string stats_id = "1"; | 410 const string stats_id = "1"; |
406 const int num_converted_stats = 4; | 411 const int num_converted_stats = 4; |
407 const string stats_names[] = | 412 const string stats_names[] = |
408 {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"}; | 413 {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"}; |
409 const string converted_names[] = | 414 const string converted_names[] = |
410 {"packetsSentPerSecond", "bitsSentPerSecond", | 415 {"packetsSentPerSecond", "bitsSentPerSecond", |
411 "packetsReceivedPerSecond", "bitsReceivedPerSecond"}; | 416 "packetsReceivedPerSecond", "bitsReceivedPerSecond"}; |
412 const string first_value = "1000"; | 417 const string first_value = "1000"; |
413 const string second_value = "2000"; | 418 const string second_value = "2000"; |
414 const string converted_values[] = {"1000", "8000", "1000", "8000"}; | 419 const string converted_values[] = {"1000", "8000", "1000", "8000"}; |
415 | 420 |
416 // Send the first data point. | 421 // Send the first data point. |
417 StatsUnit remote = {FAKE_TIME_STAMP}; | 422 StatsUnit stats = {FAKE_TIME_STAMP}; |
418 StatsUnit local = {FAKE_TIME_STAMP}; | |
419 for (int i = 0; i < num_converted_stats; ++i) | 423 for (int i = 0; i < num_converted_stats; ++i) |
420 local.values[stats_names[i]] = first_value; | 424 stats.values[stats_names[i]] = first_value; |
421 | 425 |
422 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote); | 426 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats); |
423 | 427 |
424 // Send the second data point at 1000ms after the first data point. | 428 // Send the second data point at 1000ms after the first data point. |
425 local.timestamp += 1000; | 429 stats.timestamp += 1000; |
426 for (int i = 0; i < num_converted_stats; ++i) | 430 for (int i = 0; i < num_converted_stats; ++i) |
427 local.values[stats_names[i]] = second_value; | 431 stats.values[stats_names[i]] = second_value; |
428 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, local, remote); | 432 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats); |
429 | 433 |
430 // Verifies the graph data matches converted_values. | 434 // Verifies the graph data matches converted_values. |
431 string graph_id_prefix = pc.getIdString() + "-" + stats_type + "-" + stats_id; | 435 string graph_id_prefix = pc.getIdString() + "-" + stats_type + "-" + stats_id; |
432 for (int i = 0; i < num_converted_stats; ++i) { | 436 for (int i = 0; i < num_converted_stats; ++i) { |
433 VerifyGraphDataPoint( | 437 VerifyGraphDataPoint( |
434 graph_id_prefix + "-" + converted_names[i], 1, converted_values[i]); | 438 graph_id_prefix + "-" + converted_names[i], 1, converted_values[i]); |
435 } | 439 } |
436 } | 440 } |
437 | 441 |
| 442 // Sanity check of the page content under a real PeerConnection call. |
| 443 IN_PROC_BROWSER_TEST_F(WebRTCInternalsBrowserTest, withRealPeerConnectionCall) { |
| 444 // Start a peerconnection call in the first window. |
| 445 GURL url(test_server()->GetURL("files/media/peerconnection-call.html")); |
| 446 NavigateToURL(shell(), url); |
| 447 ASSERT_TRUE(ExecuteJavascript("call({video:true});")); |
| 448 ExpectTitle("OK"); |
| 449 |
| 450 // Open webrtc-internals in the second window. |
| 451 GURL url2("chrome://webrtc-internals"); |
| 452 Shell* shell2 = CreateBrowser(); |
| 453 NavigateToURL(shell2, url2); |
| 454 |
| 455 const int NUMBER_OF_PEER_CONNECTIONS = 2; |
| 456 |
| 457 // Verifies the number of peerconnections. |
| 458 int count = 0; |
| 459 ASSERT_TRUE(ExecuteScriptAndExtractInt( |
| 460 shell2->web_contents(), |
| 461 "window.domAutomationController.send(" |
| 462 "$('peer-connections-list').getElementsByTagName('li').length);", |
| 463 &count)); |
| 464 EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count); |
| 465 |
| 466 // Verifies the the event tables. |
| 467 ASSERT_TRUE(ExecuteScriptAndExtractInt( |
| 468 shell2->web_contents(), |
| 469 "window.domAutomationController.send(" |
| 470 "$('peer-connections-list').getElementsByClassName('log-table')[0]" |
| 471 ".rows.length);", |
| 472 &count)); |
| 473 EXPECT_GT(count, 1); |
| 474 |
| 475 ASSERT_TRUE(ExecuteScriptAndExtractInt( |
| 476 shell2->web_contents(), |
| 477 "window.domAutomationController.send(" |
| 478 "$('peer-connections-list').getElementsByClassName('log-table')[1]" |
| 479 ".rows.length);", |
| 480 &count)); |
| 481 EXPECT_GT(count, 1); |
| 482 |
| 483 // Wait until the stats table containers are created. |
| 484 count = 0; |
| 485 while (count != NUMBER_OF_PEER_CONNECTIONS) { |
| 486 ASSERT_TRUE(ExecuteScriptAndExtractInt( |
| 487 shell2->web_contents(), |
| 488 "window.domAutomationController.send(" |
| 489 "$('peer-connections-list').getElementsByClassName(" |
| 490 "'stats-table-container').length);", |
| 491 &count)); |
| 492 } |
| 493 |
| 494 // Verifies each stats table having more than one rows. |
| 495 bool result = false; |
| 496 ASSERT_TRUE(ExecuteScriptAndExtractBool( |
| 497 shell2->web_contents(), |
| 498 "var tableContainers = $('peer-connections-list')" |
| 499 ".getElementsByClassName('stats-table-container');" |
| 500 "var result = true;" |
| 501 "for (var i = 0; i < tableContainers.length && result; ++i) {" |
| 502 "var tables = tableContainers[i].getElementsByTagName('table');" |
| 503 "for (var j = 0; j < tables.length && result; ++j) {" |
| 504 "result = (tables[j].rows.length > 1);" |
| 505 "}" |
| 506 "if (!result) {" |
| 507 "console.log(tableContainers[i].innerHTML);" |
| 508 "}" |
| 509 "}" |
| 510 "window.domAutomationController.send(result);", |
| 511 &result)); |
| 512 |
| 513 EXPECT_TRUE(result); |
| 514 } |
| 515 |
438 } // namespace content | 516 } // namespace content |
OLD | NEW |