12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h"
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_reader.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_switches.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test.h"
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/test/content_browser_test_utils.h"
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/shell/browser/shell.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "media/base/media_switches.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using std::string;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct SsrcEntry {
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string GetSsrcAttributeString() const {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::stringstream ss;
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss << "a=ssrc:" << id;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::map<string, string>::const_iterator iter;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (iter = properties.begin(); iter != properties.end(); ++iter) {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ss << " " << iter->first << ":" << iter->second;
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ss.str();
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string GetAsJSON() const {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::stringstream ss;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss << "{";
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::map<string, string>::const_iterator iter;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (iter = properties.begin(); iter != properties.end(); ++iter) {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (iter != properties.begin())
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ss << ",";
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ss << "\"" << iter->first << "\":\"" << iter->second << "\"";
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss << "}";
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ss.str();
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string id;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::map<string, string> properties;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct EventEntry {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string type;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string value;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct StatsUnit {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string GetString() const {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{timestamp:" << timestamp << ", values:[";
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<string, string>::const_iterator iter;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (iter = values.begin(); iter != values.end(); ++iter) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ss << "'" << iter->first << "','" << iter->second << "',";
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "]}";
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ss.str();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 timestamp;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<string, string> values;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct StatsEntry {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string type;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string id;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StatsUnit stats;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::map<string, std::vector<string> > StatsMap;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PeerConnectionEntry {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry(int pid, int lid) : pid_(pid), lid_(lid) {}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddEvent(const string& type, const string& value) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EventEntry entry = {type, value};
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    events_.push_back(entry);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string getIdString() const {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << pid_ << "-" << lid_;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ss.str();
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string getLogIdString() const {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss << pid_ << "-" << lid_ << "-update-log";
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ss.str();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string getAllUpdateString() const {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{pid:" << pid_ << ", lid:" << lid_ << ", log:[";
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < events_.size(); ++i) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ss << "{type:'" << events_[i].type <<
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "', value:'" << events_[i].value << "'},";
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "]}";
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ss.str();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int pid_;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int lid_;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<EventEntry> events_;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is a record of the history of stats value reported for each stats
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // report id (e.g. ssrc-1234) for each stats name (e.g. framerate).
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It a 2-D map with each map entry is a vector of reported values.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // It is used to verify the graph data series.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<string, StatsMap> stats_;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class UserMediaRequestEntry {
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UserMediaRequestEntry(int pid,
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        int rid,
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& origin,
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& audio_constraints,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        const std::string& video_constraints)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : pid(pid),
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rid(rid),
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        origin(origin),
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        audio_constraints(audio_constraints),
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        video_constraints(video_constraints) {}
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int pid;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rid;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string origin;
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string audio_constraints;
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string video_constraints;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)static const int64 FAKE_TIME_STAMP = 3600000;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_WIN)
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// All tests are flaky on Windows: crbug.com/277322.
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_WebRtcInternalsBrowserTest DISABLED_WebRtcInternalsBrowserTest
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MAYBE_WebRtcInternalsBrowserTest WebRtcInternalsBrowserTest
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MAYBE_WebRtcInternalsBrowserTest: public ContentBrowserTest {
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MAYBE_WebRtcInternalsBrowserTest() {}
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~MAYBE_WebRtcInternalsBrowserTest() {}
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We need fake devices in this test since we want to run on naked VMs. We
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // assume these switches are set by default in content_browsertests.
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        switches::kUseFakeDeviceForMediaStream));
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ASSERT_TRUE(CommandLine::ForCurrentProcess()->HasSwitch(
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        switches::kUseFakeUIForMediaStream));
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ExecuteJavascript(const string& javascript) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ExecuteScript(shell()->web_contents(), javascript);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ExpectTitle(const std::string& expected_title) const {
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 expected_title16(base::ASCIIToUTF16(expected_title));
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TitleWatcher title_watcher(shell()->web_contents(), expected_title16);
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(expected_title16, title_watcher.WaitAndGetTitle());
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Execute the javascript of addPeerConnection.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExecuteAddPeerConnectionJs(const PeerConnectionEntry& pc) {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << ", " <<
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)           "url:'u', rtcConfiguration:'s', constraints:'c'}";
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteJavascript("addPeerConnection(" + ss.str() + ");"));
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Execute the javascript of removePeerConnection.
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExecuteRemovePeerConnectionJs(const PeerConnectionEntry& pc) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ << "}";
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteJavascript("removePeerConnection(" + ss.str() + ");"));
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Execute the javascript of addGetUserMedia.
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ExecuteAddGetUserMediaJs(const UserMediaRequestEntry& request) {
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::stringstream ss;
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ss << "{pid:" << request.pid << ", rid:" << request.rid << ", origin:'"
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       << request.origin << "', audio:'" << request.audio_constraints
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       << "', video:'" << request.video_constraints << "'}";
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(ExecuteJavascript("addGetUserMedia(" + ss.str() + ");"));
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Execute the javascript of removeGetUserMediaForRenderer.
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ExecuteRemoveGetUserMediaForRendererJs(int rid) {
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::stringstream ss;
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ss << "{rid:" << rid << "}";
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ExecuteJavascript("removeGetUserMediaForRenderer(" + ss.str() + ");"));
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the DOM element with id |id| exists.
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyElementWithId(const string& id) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = false;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractBool(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send($('" + id + "') != null);",
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(result);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the DOM element with id |id| does not exist.
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyNoElementWithId(const string& id) {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = false;
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractBool(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send($('" + id + "') == null);",
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(result);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verifies the JS Array of userMediaRequests matches |requests|.
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void VerifyUserMediaRequest(
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::vector<UserMediaRequestEntry>& requests) {
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    string json_requests;
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractString(
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        shell()->web_contents(),
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        "window.domAutomationController.send("
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "JSON.stringify(userMediaRequests));",
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &json_requests));
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::Value> value_requests;
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    value_requests.reset(base::JSONReader::Read(json_requests));
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::Value::TYPE_LIST, value_requests->GetType());
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ListValue* list_request =
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        static_cast<base::ListValue*>(value_requests.get());
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(requests.size(), list_request->GetSize());
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < requests.size(); ++i) {
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue* dict = NULL;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(list_request->GetDictionary(i, &dict));
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int pid, rid;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string origin, audio, video;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(dict->GetInteger("pid", &pid));
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(dict->GetInteger("rid", &rid));
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(dict->GetString("origin", &origin));
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(dict->GetString("audio", &audio));
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ASSERT_TRUE(dict->GetString("video", &video));
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(requests[i].pid, pid);
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(requests[i].rid, rid);
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(requests[i].origin, origin);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(requests[i].audio_constraints, audio);
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(requests[i].video_constraints, video);
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool user_media_tab_existed = false;
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractBool(
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        shell()->web_contents(),
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "window.domAutomationController.send("
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "$('user-media-tab-id') != null);",
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        &user_media_tab_existed));
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(!requests.empty(), user_media_tab_existed);
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (user_media_tab_existed) {
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      int user_media_request_count = -1;
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_TRUE(ExecuteScriptAndExtractInt(
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          shell()->web_contents(),
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "window.domAutomationController.send("
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              "$('user-media-tab-id').childNodes.length);",
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          &user_media_request_count));
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ASSERT_EQ(requests.size(), static_cast<size_t>(user_media_request_count));
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that DOM for |pc| is correctly created with the right content.
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyPeerConnectionEntry(const PeerConnectionEntry& pc) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyElementWithId(pc.getIdString());
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pc.events_.size() == 0)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string log_id = pc.getLogIdString();
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyElementWithId(log_id);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string result;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < pc.events_.size(); ++i) {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::stringstream ss;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ss << "var row = $('" << log_id << "').rows[" << (i + 1) << "];"
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "var cell = row.lastChild;"
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            "window.domAutomationController.send(cell.firstChild.textContent);";
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(ExecuteScriptAndExtractString(
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shell()->web_contents(), ss.str(), &result));
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EXPECT_EQ(pc.events_[i].type + pc.events_[i].value, result);
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Executes the javascript of updatePeerConnection and verifies the result.
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExecuteAndVerifyUpdatePeerConnection(
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PeerConnectionEntry& pc, const string& type, const string& value) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pc.AddEvent(type, value);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{pid:" << pc.pid_ <<", lid:" << pc.lid_ <<
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ", type:'" << type << "', value:'" << value << "'}";
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteJavascript("updatePeerConnection(" + ss.str() + ")"));
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyPeerConnectionEntry(pc);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Execute addStats and verifies that the stats table has the right content.
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExecuteAndVerifyAddStats(
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PeerConnectionEntry& pc, const string& type, const string& id,
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      StatsUnit& stats) {
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StatsEntry entry = {type, id, stats};
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Adds each new value to the map of stats history.
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<string, string>::iterator iter;
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (iter = stats.values.begin(); iter != stats.values.end(); iter++) {
324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      pc.stats_[id][iter->first].push_back(iter->second);
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ss << "{pid:" << pc.pid_ << ", lid:" << pc.lid_ << ","
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           "reports:[" << "{id:'" << id << "', type:'" << type << "', "
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           "stats:" << stats.GetString() << "}]}";
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteJavascript("addStats(" + ss.str() + ")"));
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyStatsTable(pc, entry);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the stats table has the right content.
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyStatsTable(const PeerConnectionEntry& pc,
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        const StatsEntry& report) {
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string table_id =
340a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        pc.getIdString() + "-table-" + report.id;
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyElementWithId(table_id);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<string, string>::const_iterator iter;
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (iter = report.stats.values.begin();
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         iter != report.stats.values.end(); iter++) {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      VerifyStatsTableRow(table_id, iter->first, iter->second);
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the row named as |name| of the stats table |table_id| has
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the correct content as |name| : |value|.
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyStatsTableRow(const string& table_id,
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const string& name,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const string& value) {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyElementWithId(table_id + "-" + name);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string result;
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractString(
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "var row = $('" + table_id + "-" + name + "');"
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "var name = row.cells[0].textContent;"
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "var value = row.cells[1].textContent;"
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send(name + ':' + value)",
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result));
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(name + ":" + value, result);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the graph data series consistent with pc.stats_.
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyStatsGraph(const PeerConnectionEntry& pc) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<string, StatsMap>::const_iterator stream_iter;
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (stream_iter = pc.stats_.begin();
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         stream_iter != pc.stats_.end(); stream_iter++) {
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StatsMap::const_iterator stats_iter;
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      for (stats_iter = stream_iter->second.begin();
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stats_iter != stream_iter->second.end();
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           stats_iter++) {
37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        string graph_id = stream_iter->first + "-" + stats_iter->first;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (size_t i = 0; i < stats_iter->second.size(); ++i) {
379a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          float number;
380a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          std::stringstream stream(stats_iter->second[i]);
381a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          stream >> number;
382a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          if (stream.fail())
383a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            continue;
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          VerifyGraphDataPoint(
38590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              pc.getIdString(), graph_id, i, stats_iter->second[i]);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that the graph data point at index |index| has value |value|.
39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void VerifyGraphDataPoint(const string& pc_id, const string& graph_id,
39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                            int index, const string& value) {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool result = false;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractBool(
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send("
39890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)           "graphViews['" + pc_id + "-" + graph_id + "'] != null)",
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result));
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(result);
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::stringstream ss;
40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ss << "var dp = peerConnectionDataStore['" << pc_id << "']"
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          ".getDataSeries('" << graph_id << "').dataPoints_[" << index << "];"
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          "window.domAutomationController.send(dp.value.toString())";
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    string actual_value;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractString(
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(), ss.str(), &actual_value));
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(value, actual_value);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the JSON string of the ssrc info from the page.
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string GetSsrcInfo(const string& ssrc_id) {
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    string result;
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_TRUE(ExecuteScriptAndExtractString(
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        shell()->web_contents(),
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "window.domAutomationController.send(JSON.stringify("
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           "ssrcInfoManager.streamInfoContainer_['" + ssrc_id + "']))",
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &result));
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return result;
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
422b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
423b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int GetSsrcInfoBlockCount(Shell* shell) {
424b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    int count = 0;
425b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    EXPECT_TRUE(ExecuteScriptAndExtractInt(
426b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        shell->web_contents(),
427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        "window.domAutomationController.send("
428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            "document.getElementsByClassName("
429b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                "ssrcInfoManager.SSRC_INFO_BLOCK_CLASS).length);",
430b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        &count));
431b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return count;
432b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Verifies |dump| contains |peer_connection_number| peer connection dumps,
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // each containing |update_number| updates and |stats_number| stats tables.
4367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void VerifyPageDumpStructure(base::Value* dump,
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               int peer_connection_number,
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               int update_number,
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               int stats_number) {
4407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_NE((base::Value*)NULL, dump);
4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(base::Value::TYPE_DICTIONARY, dump->GetType());
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::DictionaryValue* dict_dump =
4447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        static_cast<base::DictionaryValue*>(dump);
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ((size_t) peer_connection_number, dict_dump->size());
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::DictionaryValue::Iterator it(*dict_dump);
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (; !it.IsAtEnd(); it.Advance()) {
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::Value* value = NULL;
45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      dict_dump->Get(it.key(), &value);
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::DictionaryValue* pc_dump =
4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          static_cast<base::DictionaryValue*>(value);
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_TRUE(pc_dump->HasKey("updateLog"));
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_TRUE(pc_dump->HasKey("stats"));
45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Verifies the number of updates.
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      pc_dump->Get("updateLog", &value);
4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      EXPECT_EQ(base::Value::TYPE_LIST, value->GetType());
4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::ListValue* list = static_cast<base::ListValue*>(value);
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_EQ((size_t) update_number, list->GetSize());
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      // Verifies the number of stats tables.
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      pc_dump->Get("stats", &value);
4657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(value);
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      EXPECT_EQ((size_t) stats_number, dict->size());
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
46990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Verifies |dump| contains the correct statsTable and statsDataSeries for
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // |pc|.
4737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void VerifyStatsDump(base::Value* dump,
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       const PeerConnectionEntry& pc,
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       const string& report_type,
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       const string& report_id,
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                       const StatsUnit& stats) {
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_NE((base::Value*)NULL, dump);
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(base::Value::TYPE_DICTIONARY, dump->GetType());
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::DictionaryValue* dict_dump =
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        static_cast<base::DictionaryValue*>(dump);
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::Value* value = NULL;
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    dict_dump->Get(pc.getIdString(), &value);
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::DictionaryValue* pc_dump = static_cast<base::DictionaryValue*>(value);
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Verifies there is one data series per stats name.
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    value = NULL;
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    pc_dump->Get("stats", &value);
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_EQ(base::Value::TYPE_DICTIONARY, value->GetType());
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    base::DictionaryValue* dataSeries =
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        static_cast<base::DictionaryValue*>(value);
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(stats.values.size(), dataSeries->size());
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       AddAndRemovePeerConnection) {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add two PeerConnections and then remove them.
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_1(1, 0);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc_1);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPeerConnectionEntry(pc_1);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_2(2, 1);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc_2);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPeerConnectionEntry(pc_2);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteRemovePeerConnectionJs(pc_1);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyNoElementWithId(pc_1.getIdString());
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPeerConnectionEntry(pc_2);
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteRemovePeerConnectionJs(pc_2);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyNoElementWithId(pc_2.getIdString());
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       UpdateAllPeerConnections) {
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_0(1, 0);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pc_0.AddEvent("e1", "v1");
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pc_0.AddEvent("e2", "v2");
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_1(1, 1);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pc_1.AddEvent("e3", "v3");
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pc_1.AddEvent("e4", "v4");
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string pc_array = "[" + pc_0.getAllUpdateString() + ", " +
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          pc_1.getAllUpdateString() + "]";
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(ExecuteJavascript("updateAllPeerConnections(" + pc_array + ");"));
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPeerConnectionEntry(pc_0);
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPeerConnectionEntry(pc_1);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, UpdatePeerConnection) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add one PeerConnection and send one update.
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_1(1, 0);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc_1);
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAndVerifyUpdatePeerConnection(pc_1, "e1", "v1");
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add another PeerConnection and send two updates.
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc_2(1, 1);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc_2);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SsrcEntry ssrc1, ssrc2;
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ssrc1.id = "ssrcid1";
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ssrc1.properties["msid"] = "mymsid";
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ssrc2.id = "ssrcid2";
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ssrc2.properties["label"] = "mylabel";
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ssrc2.properties["cname"] = "mycname";
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyUpdatePeerConnection(pc_2, "setRemoteDescription",
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ssrc1.GetSsrcAttributeString());
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyUpdatePeerConnection(pc_2, "setLocalDescription",
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ssrc2.GetSsrcAttributeString());
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ssrc1.GetAsJSON(), GetSsrcInfo(ssrc1.id));
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ssrc2.GetAsJSON(), GetSsrcInfo(ssrc2.id));
567b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
568b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  StatsUnit stats = {FAKE_TIME_STAMP};
569b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  stats.values["ssrc"] = ssrc1.id;
570b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc_2, "ssrc", "dummyId", stats);
571b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_GT(GetSsrcInfoBlockCount(shell()), 0);
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that adding random named stats updates the dataSeries and graphs.
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, AddStats) {
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc(1, 0);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string type = "ssrc";
583a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const string id = "ssrc-1234";
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StatsUnit stats = {FAKE_TIME_STAMP};
585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  stats.values["trackId"] = "abcd";
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["bitrate"] = "2000";
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["framerate"] = "30";
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add new stats and verify the stats table and graphs.
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc, type, id, stats);
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyStatsGraph(pc);
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Update existing stats and verify the stats table and graphs.
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["bitrate"] = "2001";
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["framerate"] = "31";
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc, type, id, stats);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyStatsGraph(pc);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that the bandwidth estimation values are drawn on a single graph.
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, BweCompoundGraph) {
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc(1, 0);
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc);
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StatsUnit stats = {FAKE_TIME_STAMP};
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["googAvailableSendBandwidth"] = "1000000";
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["googTargetEncBitrate"] = "1000";
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["googActualEncBitrate"] = "1000000";
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["googRetransmitBitrate"] = "10";
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.values["googTransmitBitrate"] = "1000000";
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string stats_type = "bwe";
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string stats_id = "videobwe";
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string graph_id =
619a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      pc.getIdString() + "-" + stats_id + "-bweCompound";
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = false;
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that the bweCompound graph exists.
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractBool(
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send("
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "   graphViews['" + graph_id + "'] != null)",
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &result));
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(result);
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that the bweCompound graph contains multiple dataSeries.
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int count = 0;
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shell()->web_contents(),
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send("
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "   graphViews['" + graph_id + "'].getDataSeriesCount())",
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &count));
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ((int)stats.values.size(), count);
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that the total packet/byte count is converted to count per second,
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// and the converted data is drawn.
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, ConvertedGraphs) {
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigateToURL(shell(), url);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PeerConnectionEntry pc(1, 0);
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExecuteAddPeerConnectionJs(pc);
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string stats_type = "s";
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string stats_id = "1";
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int num_converted_stats = 4;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string stats_names[] =
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      {"packetsSent", "bytesSent", "packetsReceived", "bytesReceived"};
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string converted_names[] =
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      {"packetsSentPerSecond", "bitsSentPerSecond",
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       "packetsReceivedPerSecond", "bitsReceivedPerSecond"};
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string first_value = "1000";
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string second_value = "2000";
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string converted_values[] = {"1000", "8000", "1000", "8000"};
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send the first data point.
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StatsUnit stats = {FAKE_TIME_STAMP};
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < num_converted_stats; ++i)
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    stats.values[stats_names[i]] = first_value;
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send the second data point at 1000ms after the first data point.
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  stats.timestamp += 1000;
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < num_converted_stats; ++i)
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    stats.values[stats_names[i]] = second_value;
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies the graph data matches converted_values.
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < num_converted_stats; ++i) {
67590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    VerifyGraphDataPoint(pc.getIdString(), stats_id + "-" + converted_names[i],
67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                         1, converted_values[i]);
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
680b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Timing out on ARM linux bot: http://crbug.com/238490
6813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Disabling due to failure on Linux, Mac, Win: http://crbug.com/272413
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Sanity check of the page content under a real PeerConnection call.
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
6843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       DISABLED_WithRealPeerConnectionCall) {
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start a peerconnection call in the first window.
68690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
68790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL url(embedded_test_server()->GetURL("/media/peerconnection-call.html"));
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateToURL(shell(), url);
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteJavascript("call({video:true});"));
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExpectTitle("OK");
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Open webrtc-internals in the second window.
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url2("chrome://webrtc-internals");
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Shell* shell2 = CreateBrowser();
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigateToURL(shell2, url2);
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int NUMBER_OF_PEER_CONNECTIONS = 2;
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verifies the number of peerconnections.
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int count = 0;
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell2->web_contents(),
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "window.domAutomationController.send("
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "$('peer-connections-list').getElementsByTagName('li').length);",
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &count));
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verifies the the event tables.
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell2->web_contents(),
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "window.domAutomationController.send($('peer-connections-list')"
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          ".getElementsByClassName('update-log-table').length);",
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &count));
714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(NUMBER_OF_PEER_CONNECTIONS, count);
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell2->web_contents(),
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "window.domAutomationController.send($('peer-connections-list')"
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          ".getElementsByClassName('update-log-table')[0].rows.length);",
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &count));
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_GT(count, 1);
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell2->web_contents(),
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "window.domAutomationController.send($('peer-connections-list')"
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          ".getElementsByClassName('update-log-table')[1].rows.length);",
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &count));
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_GT(count, 1);
729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Wait until the stats table containers are created.
731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  count = 0;
732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (count != NUMBER_OF_PEER_CONNECTIONS) {
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ASSERT_TRUE(ExecuteScriptAndExtractInt(
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        shell2->web_contents(),
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "window.domAutomationController.send("
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            "$('peer-connections-list').getElementsByClassName("
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "'stats-table-container').length);",
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &count));
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verifies each stats table having more than one rows.
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool result = false;
743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractBool(
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      shell2->web_contents(),
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "var tableContainers = $('peer-connections-list')"
746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          ".getElementsByClassName('stats-table-container');"
747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "var result = true;"
748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "for (var i = 0; i < tableContainers.length && result; ++i) {"
749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "var tables = tableContainers[i].getElementsByTagName('table');"
750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "for (var j = 0; j < tables.length && result; ++j) {"
751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "result = (tables[j].rows.length > 1);"
752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "}"
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "if (!result) {"
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          "console.log(tableContainers[i].innerHTML);"
755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "}"
756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "}"
757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "window.domAutomationController.send(result);",
758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      &result));
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(result);
761b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
762b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  count = GetSsrcInfoBlockCount(shell2);
763b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_GT(count, 0);
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, CreatePageDump) {
76790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL url("chrome://webrtc-internals");
76890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  NavigateToURL(shell(), url);
76990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
77090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PeerConnectionEntry pc_0(1, 0);
77190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pc_0.AddEvent("e1", "v1");
77290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pc_0.AddEvent("e2", "v2");
77390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  PeerConnectionEntry pc_1(1, 1);
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pc_1.AddEvent("e3", "v3");
77590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  pc_1.AddEvent("e4", "v4");
77690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  string pc_array =
77790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "[" + pc_0.getAllUpdateString() + ", " + pc_1.getAllUpdateString() + "]";
77890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(ExecuteJavascript("updateAllPeerConnections(" + pc_array + ");"));
77990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Verifies the peer connection data store can be created without stats.
78190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  string dump_json;
78290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractString(
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shell()->web_contents(),
78490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "window.domAutomationController.send("
78590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "JSON.stringify(peerConnectionDataStore));",
78690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &dump_json));
7877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<base::Value> dump;
78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  dump.reset(base::JSONReader::Read(dump_json));
78990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  VerifyPageDumpStructure(dump.get(),
79090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          2 /*peer_connection_number*/,
79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          2 /*update_number*/,
79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          0 /*stats_number*/);
79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
79490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Adds a stats report.
79590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const string type = "dummy";
79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const string id = "1234";
79790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  StatsUnit stats = { FAKE_TIME_STAMP };
79890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  stats.values["bitrate"] = "2000";
79990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  stats.values["framerate"] = "30";
80090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ExecuteAndVerifyAddStats(pc_0, type, id, stats);
80190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
80290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractString(
80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      shell()->web_contents(),
80490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "window.domAutomationController.send("
80590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "JSON.stringify(peerConnectionDataStore));",
80690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      &dump_json));
80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  dump.reset(base::JSONReader::Read(dump_json));
80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  VerifyStatsDump(dump.get(), pc_0, type, id, stats);
80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest, UpdateGetUserMedia) {
8125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL url("chrome://webrtc-internals");
8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateToURL(shell(), url);
8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UserMediaRequestEntry request1(1, 1, "origin", "ac", "vc");
8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UserMediaRequestEntry request2(2, 2, "origin2", "ac2", "vc2");
8175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteAddGetUserMediaJs(request1);
8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteAddGetUserMediaJs(request2);
8195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<UserMediaRequestEntry> list;
8215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  list.push_back(request1);
8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  list.push_back(request2);
8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VerifyUserMediaRequest(list);
8245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteRemoveGetUserMediaForRendererJs(1);
8265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  list.erase(list.begin());
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VerifyUserMediaRequest(list);
8285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteRemoveGetUserMediaForRendererJs(2);
8305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  list.erase(list.begin());
8315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VerifyUserMediaRequest(list);
8325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Tests that the received propagation delta values are converted and drawn
8355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// correctly.
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcInternalsBrowserTest,
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       ReceivedPropagationDelta) {
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL url("chrome://webrtc-internals");
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  NavigateToURL(shell(), url);
8405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PeerConnectionEntry pc(1, 0);
8425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteAddPeerConnectionJs(pc);
8435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StatsUnit stats = {FAKE_TIME_STAMP};
8455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stats.values["googReceivedPacketGroupArrivalTimeDebug"] =
8465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "[1000, 1100, 1200]";
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stats.values["googReceivedPacketGroupPropagationDeltaDebug"] =
8485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "[10, 20, 30]";
8495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const string stats_type = "bwe";
8505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const string stats_id = "videobwe";
8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExecuteAndVerifyAddStats(pc, stats_type, stats_id, stats);
8525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string graph_id = pc.getIdString() + "-" + stats_id +
8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "-googReceivedPacketGroupPropagationDeltaDebug";
8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  string data_series_id =
8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      stats_id + "-googReceivedPacketGroupPropagationDeltaDebug";
8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool result = false;
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that the graph exists.
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractBool(
8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shell()->web_contents(),
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "window.domAutomationController.send("
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "   graphViews['" + graph_id + "'] != null)",
8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &result));
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(result);
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Verify that the graph contains multiple data points.
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int count = 0;
8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shell()->web_contents(),
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "window.domAutomationController.send("
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "   graphViews['" + graph_id + "'].getDataSeriesCount())",
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &count));
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, count);
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(ExecuteScriptAndExtractInt(
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shell()->web_contents(),
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "window.domAutomationController.send("
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "   peerConnectionDataStore['" + pc.getIdString() + "']" +
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "       .getDataSeries('" + data_series_id + "').getCount())",
8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      &count));
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3, count);
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
884