IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / media / webrtc_internals_browsertest.cc
blob9750073897187630fe87bf15cf118cb1fa566766
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
3 // found in the LICENSE file.
5 #include "base/command_line.h"
6 #include "base/json/json_reader.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/time/time.h"
9 #include "base/values.h"
10 #include "content/public/common/content_switches.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "content/shell/browser/shell.h"
13 #include "content/test/content_browser_test.h"
14 #include "content/test/content_browser_test_utils.h"
15 #include "net/test/embedded_test_server/embedded_test_server.h"
17 using std::string;
18 namespace content {
20 struct SsrcEntry {
21 string GetSsrcAttributeString() const {
22 std::stringstream ss;
23 ss << "a=ssrc:" << id;
24 std::map<string, string>::const_iterator iter;
25 for (iter = properties.begin(); iter != properties.end(); ++iter) {
26 ss << " " << iter->first << ":" << iter->second;
28 return ss.str();
31 string GetAsJSON() const {
32 std::stringstream ss;
33 ss << "{";
34 std::map<string, string>::const_iterator iter;
35 for (iter = properties.begin(); iter != properties.end(); ++iter) {
36 if (iter != properties.begin())
37 ss << ",";
38 ss << "\"" << iter->first << "\":\"" << iter->second << "\"";
40 ss << "}";
41 return ss.str();
44 string id;
45 std::map<string, string> properties;
48 struct EventEntry {
49 string type;
50 string value;
53 struct StatsUnit {
54 string GetString() const {
55 std::stringstream ss;
56 ss << "{timestamp:" << timestamp << ", values:[";
57 std::map<string, string>::const_iterator iter;
58 for (iter = values.begin(); iter != values.end(); ++iter) {
59 ss << "'" << iter->first << "','" << iter->second << "',";
61 ss << "]}";
62 return ss.str();
65 int64 timestamp;
66 std::map<string, string> values;
69 struct StatsEntry {
70 string type;
71 string id;
72 StatsUnit stats;
75 typedef std::map<string, std::vector<string> > StatsMap;
77 class PeerConnectionEntry {
78 public:
79 PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {}
81 void AddEvent(const string& type, const string& value) {
82 EventEntry entry = {type, value};
83 events_.push_back(entry);
86 string getIdString() const {
87 std::stringstream ss;
88 ss << pid_ << "-" << lid_;
89 return ss.str();
92 string getLogIdString() const {
93 std::stringstream ss;
94 ss << pid_ << "-" << lid_ << "-update-log";
95 return ss.str();
98 string getAllUpdateString() const {
99 std::stringstream ss;
100 ss << "{pid:" << pid_ << ", lid:" << lid_ << ", log:[";
101 for (size_t i = 0; i < events_.size(); ++i) {
102 ss << "{type:'" << events_[i].type <<
103 "', value:'" << events_[i].value << "'},";
105 ss << "]}";
106 return ss.str();
109 int pid_;
110 int lid_;
111 std::vector<EventEntry> events_;
112 // This is a record of the history of stats value reported for each stats
113 // report id (e.g. ssrc-1234) for each stats name (e.g. framerate).
114 // It a 2-D map with each map entry is a vector of reported values.
115 // It is used to verify the graph data series.
116 std::map<string, StatsMap> stats_;
119 static const int64 FAKE_TIME_STAMP = 3600000;
121 #if defined(OS_WIN)
122 // All tests are flaky on Windows: crbug.com/277322.
123 #define MAYBE_WebRTCInternalsBrowserTest DISABLED_WebRTCInternalsBrowserTest
124 #else
125 #define MAYBE_WebRTCInternalsBrowserTest WebRTCInternalsBrowserTest
126 #endif
128 class MAYBE_WebRTCInternalsBrowserTest: public ContentBrowserTest {
129 public:
130 MAYBE_WebRTCInternalsBrowserTest() {}
131 virtual ~MAYBE_WebRTCInternalsBrowserTest() {}
133 virtual void SetUpOnMainThread() OVERRIDE {
134 // We need fake devices in this test since we want to run on naked VMs. We
135 // assume these switches are set by default in content_browsertests.
136 ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
137 switches::kUseFakeDeviceForMediaStream));
138 ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
139 switches::kUseFakeUIForMediaStream));
142 protected:
143 bool ExecuteJavascript(const string& javascript) {
144 return ExecuteScript(shell()->web_contents(), javascript);
147 void ExpectTitle(const std::string& expected_title) const {
148 base::string16 expected_title16(base::ASCIIToUTF16(expected_title));
149 TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
150 EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
153 // Execute the javascript of addPeerConnection.
154 void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) {
155 std::stringstream ss;
156 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " <<
157 "url:'u', servers:'s', constraints:'c'}";
158 ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");"));
161 // Execute the javascript of removePeerConnection.
162 void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) {
163 std::stringstream ss;
164 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << "}";
166 ASSERT_TRUE(ExecuteJavascript("removePeerConnection(" + ss.str() + ");"));
169 // Verifies that the DOM element with id |id| exists.
170 void VerifyElementWithId(const string& id) {
171 bool result = false;
172 ASSERT_TRUE(ExecuteScriptAndExtractBool(
173 shell()->web_contents(),
174 "window.domAutomationController.send($('" + id + "') != null);",
175 &result));
176 EXPECT_TRUE(result);
179 // Verifies that the DOM element with id |id| does not exist.
180 void VerifyNoElementWithId(const string& id) {
181 bool result = false;
182 ASSERT_TRUE(ExecuteScriptAndExtractBool(
183 shell()->web_contents(),
184 "window.domAutomationController.send($('" + id + "') == null);",
185 &result));
186 EXPECT_TRUE(result);
189 // Verifies that DOM for |pc| is correctly created with the right content.
190 void VerifyPeerConnectionEntry(const PeerConnectionEntry& pc) {
191 VerifyElementWithId(pc.getIdString());
192 if (pc.events_.size() == 0)
193 return;
195 string log_id = pc.getLogIdString();
196 VerifyElementWithId(log_id);
197 string result;
198 for (size_t i = 0; i < pc.events_.size(); ++i) {
199 std::stringstream ss;
200 ss << "var row = $('" << log_id << "').rows[" << (i + 1) << "];"
201 "var cell = row.lastChild;"
202 "window.domAutomationController.send(cell.firstChild.textContent);";
203 ASSERT_TRUE(ExecuteScriptAndExtractString(
204 shell()->web_contents(), ss.str(), &result));
205 EXPECT_EQ(pc.events_[i].type + pc.events_[i].value, result);
209 // Executes the javascript of updatePeerConnection and verifies the result.
210 void ExecuteAndVerifyUpdatePeerConnection(
211 PeerConnectionEntry& pc, const string& type, const string& value) {
212 pc.AddEvent(type, value);
214 std::stringstream ss;
215 ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ <<
216 ", type:'" << type << "', value:'" << value << "'}";
217 ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")"));
219 VerifyPeerConnectionEntry(pc);
222 // Execute addStats and verifies that the stats table has the right content.
223 void ExecuteAndVerifyAddStats(
224 PeerConnectionEntry& pc, const string& type, const string& id,
225 StatsUnit& stats) {
226 StatsEntry entry = {type, id, stats};
228 // Adds each new value to the map of stats history.
229 std::map<string, string>::iterator iter;
230 for (iter = stats.values.begin(); iter != stats.values.end(); iter++) {
231 pc.stats_[id][iter->first].push_back(iter->second);
233 std::stringstream ss;
234 ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << ","
235 "reports:[" << "{id:'" << id << "', type:'" << type << "', "
236 "stats:" << stats.GetString() << "}]}";
238 ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")"));
239 VerifyStatsTable(pc, entry);
243 // Verifies that the stats table has the right content.
244 void VerifyStatsTable(const PeerConnectionEntry& pc,
245 const StatsEntry& report) {
246 string table_id =
247 pc.getIdString() + "-table-" + report.id;
248 VerifyElementWithId(table_id);
250 std::map<string, string>::const_iterator iter;
251 for (iter = report.stats.values.begin();
252 iter != report.stats.values.end(); iter++) {
253 VerifyStatsTableRow(table_id, iter->first, iter->second);
257 // Verifies that the row named as |name| of the stats table |table_id| has
258 // the correct content as |name| : |value|.
259 void VerifyStatsTableRow(const string& table_id,
260 const string& name,
261 const string& value) {
262 VerifyElementWithId(table_id + "-" + name);
264 string result;
265 ASSERT_TRUE(ExecuteScriptAndExtractString(
266 shell()->web_contents(),
267 "var row = $('" + table_id + "-" + name + "');"
268 "var name = row.cells[0].textContent;"
269 "var value = row.cells[1].textContent;"
270 "window.domAutomationController.send(name + ':' + value)",
271 &result));
272 EXPECT_EQ(name + ":" + value, result);
275 // Verifies that the graph data series consistent with pc.stats_.
276 void VerifyStatsGraph(const PeerConnectionEntry& pc) {
277 std::map<string, StatsMap>::const_iterator stream_iter;
278 for (stream_iter = pc.stats_.begin();
279 stream_iter != pc.stats_.end(); stream_iter++) {
280 StatsMap::const_iterator stats_iter;
281 for (stats_iter = stream_iter->second.begin();
282 stats_iter != stream_iter->second.end();
283 stats_iter++) {
284 string graph_id = stream_iter->first + "-" + stats_iter->first;
285 for (size_t i = 0; i < stats_iter->second.size(); ++i) {
286 float number;
287 std::stringstream stream(stats_iter->second[i]);
288 stream >> number;
289 if (stream.fail())
290 continue;
291 VerifyGraphDataPoint(
292 pc.getIdString(), graph_id, i, stats_iter->second[i]);
298 // Verifies that the graph data point at index |index| has value |value|.
299 void VerifyGraphDataPoint(const string& pc_id, const string& graph_id,
300 int index, const string& value) {
301 bool result = false;
302 ASSERT_TRUE(ExecuteScriptAndExtractBool(
303 shell()->web_contents(),
304 "window.domAutomationController.send("
305 "graphViews['" + pc_id + "-" + graph_id + "'] != null)",
306 &result));
307 EXPECT_TRUE(result);
309 std::stringstream ss;
310 ss << "var dp = peerConnectionDataStore['" << pc_id << "']"
311 ".getDataSeries('" << graph_id << "').dataPoints_[" << index << "];"
312 "window.domAutomationController.send(dp.value.toString())";
313 string actual_value;
314 ASSERT_TRUE(ExecuteScriptAndExtractString(
315 shell()->web_contents(), ss.str(), &actual_value));
316 EXPECT_EQ(value, actual_value);
319 // Get the JSON string of the ssrc info from the page.
320 string GetSsrcInfo(const string& ssrc_id) {
321 string result;
322 EXPECT_TRUE(ExecuteScriptAndExtractString(
323 shell()->web_contents(),
324 "window.domAutomationController.send(JSON.stringify("
325 "ssrcInfoManager.streamInfoContainer_['" + ssrc_id + "']))",
326 &result));
327 return result;
330 int GetSsrcInfoBlockCount(Shell* shell) {
331 int count = 0;
332 EXPECT_TRUE(ExecuteScriptAndExtractInt(
333 shell->web_contents(),
334 "window.domAutomationController.send("
335 "document.getElementsByClassName("
336 "ssrcInfoManager.SSRC_INFO_BLOCK_CLASS).length);",
337 &count));
338 return count;
341 // Verifies |dump| contains |peer_connection_number| peer connection dumps,
342 // each containing |update_number| updates and |stats_number| stats tables.
343 void VerifyPageDumpStructure(base::Value* dump,
344 int peer_connection_number,
345 int update_number,
346 int stats_number) {
347 EXPECT_NE((base::Value*)NULL, dump);
348 EXPECT_EQ(base::Value::TYPE_DICTIONARY, dump->GetType());
350 base::DictionaryValue* dict_dump =
351 static_cast<base::DictionaryValue*>(dump);
352 EXPECT_EQ((size_t) peer_connection_number, dict_dump->size());
354 base::DictionaryValue::Iterator it(*dict_dump);
355 for (; !it.IsAtEnd(); it.Advance()) {
356 base::Value* value = NULL;
357 dict_dump->Get(it.key(), &value);
358 EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
359 base::DictionaryValue* pc_dump =
360 static_cast<base::DictionaryValue*>(value);
361 EXPECT_TRUE(pc_dump->HasKey("updateLog"));
362 EXPECT_TRUE(pc_dump->HasKey("stats"));
364 // Verifies the number of updates.
365 pc_dump->Get("updateLog", &value);
366 EXPECT_EQ(base::Value::TYPE_LIST, value->GetType());
367 base::ListValue* list = static_cast<base::ListValue*>(value);
368 EXPECT_EQ((size_t) update_number, list->GetSize());
370 // Verifies the number of stats tables.
371 pc_dump->Get("stats", &value);
372 EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
373 base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(value);
374 EXPECT_EQ((size_t) stats_number, dict->size());
378 // Verifies |dump| contains the correct statsTable and statsDataSeries for
379 // |pc|.
380 void VerifyStatsDump(base::Value* dump,
381 const PeerConnectionEntry& pc,
382 const string& report_type,
383 const string& report_id,
384 const StatsUnit& stats) {
385 EXPECT_NE((base::Value*)NULL, dump);
386 EXPECT_EQ(base::Value::TYPE_DICTIONARY, dump->GetType());
388 base::DictionaryValue* dict_dump =
389 static_cast<base::DictionaryValue*>(dump);
390 base::Value* value = NULL;
391 dict_dump->Get(pc.getIdString(), &value);
392 base::DictionaryValue* pc_dump = static_cast<base::DictionaryValue*>(value);
394 // Verifies there is one data series per stats name.
395 value = NULL;
396 pc_dump->Get("stats", &value);
397 EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
399 base::DictionaryValue* dataSeries =
400 static_cast<base::DictionaryValue*>(value);
401 EXPECT_EQ(stats.values.size(), dataSeries->size());
405 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest,
406 AddAndRemovePeerConnection) {
407 GURL url("chrome://webrtc-internals");
408 NavigateToURL(shell(), url);
410 // Add two PeerConnections and then remove them.
411 PeerConnectionEntry pc_1(1, 0);
412 ExecuteAddPeerConnectionJs(pc_1);
413 VerifyPeerConnectionEntry(pc_1);
415 PeerConnectionEntry pc_2(2, 1);
416 ExecuteAddPeerConnectionJs(pc_2);
417 VerifyPeerConnectionEntry(pc_2);
419 ExecuteRemovePeerConnectionJs(pc_1);
420 VerifyNoElementWithId(pc_1.getIdString());
421 VerifyPeerConnectionEntry(pc_2);
423 ExecuteRemovePeerConnectionJs(pc_2);
424 VerifyNoElementWithId(pc_2.getIdString());
427 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest,
428 UpdateAllPeerConnections) {
429 GURL url("chrome://webrtc-internals");
430 NavigateToURL(shell(), url);
432 PeerConnectionEntry pc_0(1, 0);
433 pc_0.AddEvent("e1", "v1");
434 pc_0.AddEvent("e2", "v2");
435 PeerConnectionEntry pc_1(1, 1);
436 pc_1.AddEvent("e3", "v3");
437 pc_1.AddEvent("e4", "v4");
438 string pc_array = "[" + pc_0.getAllUpdateString() + ", " +
439 pc_1.getAllUpdateString() + "]";
440 EXPECT_TRUE(ExecuteJavascript("updateAllPeerConnections(" + pc_array + ");"));
441 VerifyPeerConnectionEntry(pc_0);
442 VerifyPeerConnectionEntry(pc_1);
445 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest, UpdatePeerConnection) {
446 GURL url("chrome://webrtc-internals");
447 NavigateToURL(shell(), url);
449 // Add one PeerConnection and send one update.
450 PeerConnectionEntry pc_1(1, 0);
451 ExecuteAddPeerConnectionJs(pc_1);
453 ExecuteAndVerifyUpdatePeerConnection(pc_1, "e1", "v1");
455 // Add another PeerConnection and send two updates.
456 PeerConnectionEntry pc_2(1, 1);
457 ExecuteAddPeerConnectionJs(pc_2);
459 SsrcEntry ssrc1, ssrc2;
460 ssrc1.id = "ssrcid1";
461 ssrc1.properties["msid"] = "mymsid";
462 ssrc2.id = "ssrcid2";
463 ssrc2.properties["label"] = "mylabel";
464 ssrc2.properties["cname"] = "mycname";
466 ExecuteAndVerifyUpdatePeerConnection(pc_2, "setRemoteDescription",
467 ssrc1.GetSsrcAttributeString());
469 ExecuteAndVerifyUpdatePeerConnection(pc_2, "setLocalDescription",
470 ssrc2.GetSsrcAttributeString());
472 EXPECT_EQ(ssrc1.GetAsJSON(), GetSsrcInfo(ssrc1.id));
473 EXPECT_EQ(ssrc2.GetAsJSON(), GetSsrcInfo(ssrc2.id));
475 StatsUnit stats = {FAKE_TIME_STAMP};
476 stats.values["ssrc"] = ssrc1.id;
477 ExecuteAndVerifyAddStats(pc_2, "ssrc", "dummyId", stats);
478 EXPECT_GT(GetSsrcInfoBlockCount(shell()), 0);
481 // Tests that adding random named stats updates the dataSeries and graphs.
482 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest, AddStats) {
483 GURL url("chrome://webrtc-internals");
484 NavigateToURL(shell(), url);
486 PeerConnectionEntry pc(1, 0);
487 ExecuteAddPeerConnectionJs(pc);
489 const string type = "ssrc";
490 const string id = "ssrc-1234";
491 StatsUnit stats = {FAKE_TIME_STAMP};
492 stats.values["trackId"] = "abcd";
493 stats.values["bitrate"] = "2000";
494 stats.values["framerate"] = "30";
496 // Add new stats and verify the stats table and graphs.
497 ExecuteAndVerifyAddStats(pc, type, id, stats);
498 VerifyStatsGraph(pc);
500 // Update existing stats and verify the stats table and graphs.
501 stats.values["bitrate"] = "2001";
502 stats.values["framerate"] = "31";
503 ExecuteAndVerifyAddStats(pc, type, id, stats);
504 VerifyStatsGraph(pc);
507 // Tests that the bandwidth estimation values are drawn on a single graph.
508 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest, BweCompoundGraph) {
509 GURL url("chrome://webrtc-internals");
510 NavigateToURL(shell(), url);
512 PeerConnectionEntry pc(1, 0);
513 ExecuteAddPeerConnectionJs(pc);
515 StatsUnit stats = {FAKE_TIME_STAMP};
516 stats.values["googAvailableSendBandwidth"] = "1000000";
517 stats.values["googTargetEncBitrate"] = "1000";
518 stats.values["googActualEncBitrate"] = "1000000";
519 stats.values["googRetransmitBitrate"] = "10";
520 stats.values["googTransmitBitrate"] = "1000000";
521 const string stats_type = "bwe";
522 const string stats_id = "videobwe";
523 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
525 string graph_id =
526 pc.getIdString() + "-" + stats_id + "-bweCompound";
527 bool result = false;
528 // Verify that the bweCompound graph exists.
529 ASSERT_TRUE(ExecuteScriptAndExtractBool(
530 shell()->web_contents(),
531 "window.domAutomationController.send("
532 " graphViews['" + graph_id + "'] != null)",
533 &result));
534 EXPECT_TRUE(result);
536 // Verify that the bweCompound graph contains multiple dataSeries.
537 int count = 0;
538 ASSERT_TRUE(ExecuteScriptAndExtractInt(
539 shell()->web_contents(),
540 "window.domAutomationController.send("
541 " graphViews['" + graph_id + "'].getDataSeriesCount())",
542 &count));
543 EXPECT_EQ((int)stats.values.size(), count);
546 // Tests that the total packet/byte count is converted to count per second,
547 // and the converted data is drawn.
548 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest, ConvertedGraphs) {
549 GURL url("chrome://webrtc-internals");
550 NavigateToURL(shell(), url);
552 PeerConnectionEntry pc(1, 0);
553 ExecuteAddPeerConnectionJs(pc);
555 const string stats_type = "s";
556 const string stats_id = "1";
557 const int num_converted_stats = 4;
558 const string stats_names[] =
559 {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"};
560 const string converted_names[] =
561 {"packetsSentPerSecond", "bitsSentPerSecond",
562 "packetsReceivedPerSecond", "bitsReceivedPerSecond"};
563 const string first_value = "1000";
564 const string second_value = "2000";
565 const string converted_values[] = {"1000", "8000", "1000", "8000"};
567 // Send the first data point.
568 StatsUnit stats = {FAKE_TIME_STAMP};
569 for (int i = 0; i < num_converted_stats; ++i)
570 stats.values[stats_names[i]] = first_value;
572 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
574 // Send the second data point at 1000ms after the first data point.
575 stats.timestamp += 1000;
576 for (int i = 0; i < num_converted_stats; ++i)
577 stats.values[stats_names[i]] = second_value;
578 ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
580 // Verifies the graph data matches converted_values.
581 for (int i = 0; i < num_converted_stats; ++i) {
582 VerifyGraphDataPoint(pc.getIdString(), stats_id + "-" + converted_names[i],
583 1, converted_values[i]);
587 // Timing out on ARM linux bot: http://crbug.com/238490
588 // Disabling due to failure on Linux, Mac, Win: http://crbug.com/272413
589 // Sanity check of the page content under a real PeerConnection call.
590 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest,
591 DISABLED_WithRealPeerConnectionCall) {
592 // Start a peerconnection call in the first window.
593 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
594 GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
595 NavigateToURL(shell(), url);
596 ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
597 ExpectTitle("OK");
599 // Open webrtc-internals in the second window.
600 GURL url2("chrome://webrtc-internals");
601 Shell* shell2 = CreateBrowser();
602 NavigateToURL(shell2, url2);
604 const int NUMBER_OF_PEER_CONNECTIONS = 2;
606 // Verifies the number of peerconnections.
607 int count = 0;
608 ASSERT_TRUE(ExecuteScriptAndExtractInt(
609 shell2->web_contents(),
610 "window.domAutomationController.send("
611 "$('peer-connections-list').getElementsByTagName('li').length);",
612 &count));
613 EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
615 // Verifies the the event tables.
616 ASSERT_TRUE(ExecuteScriptAndExtractInt(
617 shell2->web_contents(),
618 "window.domAutomationController.send($('peer-connections-list')"
619 ".getElementsByClassName('update-log-table').length);",
620 &count));
621 EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
623 ASSERT_TRUE(ExecuteScriptAndExtractInt(
624 shell2->web_contents(),
625 "window.domAutomationController.send($('peer-connections-list')"
626 ".getElementsByClassName('update-log-table')[0].rows.length);",
627 &count));
628 EXPECT_GT(count, 1);
630 ASSERT_TRUE(ExecuteScriptAndExtractInt(
631 shell2->web_contents(),
632 "window.domAutomationController.send($('peer-connections-list')"
633 ".getElementsByClassName('update-log-table')[1].rows.length);",
634 &count));
635 EXPECT_GT(count, 1);
637 // Wait until the stats table containers are created.
638 count = 0;
639 while (count != NUMBER_OF_PEER_CONNECTIONS) {
640 ASSERT_TRUE(ExecuteScriptAndExtractInt(
641 shell2->web_contents(),
642 "window.domAutomationController.send("
643 "$('peer-connections-list').getElementsByClassName("
644 "'stats-table-container').length);",
645 &count));
648 // Verifies each stats table having more than one rows.
649 bool result = false;
650 ASSERT_TRUE(ExecuteScriptAndExtractBool(
651 shell2->web_contents(),
652 "var tableContainers = $('peer-connections-list')"
653 ".getElementsByClassName('stats-table-container');"
654 "var result = true;"
655 "for (var i = 0; i < tableContainers.length && result; ++i) {"
656 "var tables = tableContainers[i].getElementsByTagName('table');"
657 "for (var j = 0; j < tables.length && result; ++j) {"
658 "result = (tables[j].rows.length > 1);"
660 "if (!result) {"
661 "console.log(tableContainers[i].innerHTML);"
664 "window.domAutomationController.send(result);",
665 &result));
667 EXPECT_TRUE(result);
669 count = GetSsrcInfoBlockCount(shell2);
670 EXPECT_GT(count, 0);
673 IN_PROC_BROWSER_TEST_F(MAYBE_WebRTCInternalsBrowserTest, CreatePageDump) {
674 GURL url("chrome://webrtc-internals");
675 NavigateToURL(shell(), url);
677 PeerConnectionEntry pc_0(1, 0);
678 pc_0.AddEvent("e1", "v1");
679 pc_0.AddEvent("e2", "v2");
680 PeerConnectionEntry pc_1(1, 1);
681 pc_1.AddEvent("e3", "v3");
682 pc_1.AddEvent("e4", "v4");
683 string pc_array =
684 "[" + pc_0.getAllUpdateString() + ", " + pc_1.getAllUpdateString() + "]";
685 EXPECT_TRUE(ExecuteJavascript("updateAllPeerConnections(" + pc_array + ");"));
687 // Verifies the peer connection data store can be created without stats.
688 string dump_json;
689 ASSERT_TRUE(ExecuteScriptAndExtractString(
690 shell()->web_contents(),
691 "window.domAutomationController.send("
692 "JSON.stringify(peerConnectionDataStore));",
693 &dump_json));
694 scoped_ptr<base::Value> dump;
695 dump.reset(base::JSONReader::Read(dump_json));
696 VerifyPageDumpStructure(dump.get(),
697 2 /*peer_connection_number*/,
698 2 /*update_number*/,
699 0 /*stats_number*/);
701 // Adds a stats report.
702 const string type = "dummy";
703 const string id = "1234";
704 StatsUnit stats = { FAKE_TIME_STAMP };
705 stats.values["bitrate"] = "2000";
706 stats.values["framerate"] = "30";
707 ExecuteAndVerifyAddStats(pc_0, type, id, stats);
709 ASSERT_TRUE(ExecuteScriptAndExtractString(
710 shell()->web_contents(),
711 "window.domAutomationController.send("
712 "JSON.stringify(peerConnectionDataStore));",
713 &dump_json));
714 dump.reset(base::JSONReader::Read(dump_json));
715 VerifyStatsDump(dump.get(), pc_0, type, id, stats);
718 } // namespace content