Commit f58b31b3 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

Media Engagement: Add a WebUI interface for viewing scores.

Add an internal WebUI interface at chrome://media-engagement for
viewing scores stored in the Media Engagement service.

BUG=734525

Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I9300479df06f48b98049026c9016084bd0abb902
Reviewed-on: https://chromium-review.googlesource.com/549297
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487476}
parent 17f2e2b3
......@@ -4247,7 +4247,7 @@ grit("resources") {
":chrome_internal_resources_gen",
"//chrome/app:chrome_content_manifest_overlays",
"//chrome/browser/engagement:mojo_bindings_js",
"//chrome/browser/media:mojo_bindings__generator",
"//chrome/browser/media:mojo_bindings_js",
"//chrome/browser/ui/webui/omnibox:mojo_bindings_js",
"//chrome/browser/ui/webui/usb_internals:mojo_bindings_js",
"//device/bluetooth/public/interfaces:experimental_interfaces_js",
......
......@@ -674,6 +674,9 @@
<include name="IDR_SANDBOX_INTERNALS_HTML" file="resources\sandbox_internals\sandbox_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
<include name="IDR_SANDBOX_INTERNALS_JS" file="resources\sandbox_internals\sandbox_internals.js" type="BINDATA" compress="gzip" />
</if>
<include name="IDR_MEDIA_ENGAGEMENT_HTML" file="resources\media\media_engagement.html" flattenhtml="true" type="BINDATA" compress="gzip" allowexternalscript="true" />
<include name="IDR_MEDIA_ENGAGEMENT_JS" file="resources\media\media_engagement.js" flattenhtml="true" type="BINDATA" compress="gzip" />
<include name="IDR_MEDIA_ENGAGEMENT_MOJO_JS" file="${root_gen_dir}\chrome\browser\media\media_engagement_score_details.mojom.js" use_base_dir="false" type="BINDATA" compress="gzip" />
</includes>
</release>
</grit>
......@@ -72,6 +72,7 @@
"translate::mojom::ContentTranslateDriver",
// TODO(beng): These should be moved to a separate capability.
"media::mojom::MediaEngagementScoreDetailsProvider",
"mojom::OmniboxPageHandler",
"mojom::PluginsPageHandler",
"mojom::SiteEngagementDetailsProvider",
......
......@@ -13,7 +13,4 @@ mojom("mojo_bindings") {
"//mojo/common:common_custom_types",
"//url/mojo:url_mojom_gurl",
]
# TODO(crbug.com/699569): Convert to use the new JS bindings.
use_new_js_bindings = false
}
......@@ -61,11 +61,12 @@ MediaEngagementScore::MediaEngagementScore(
last_media_playback_time_ = base::Time::FromInternalValue(internal_time);
}
media::mojom::MediaEngagementScoreDetails
// TODO(beccahughes): Add typemap.
media::mojom::MediaEngagementScoreDetailsPtr
MediaEngagementScore::GetScoreDetails() const {
return media::mojom::MediaEngagementScoreDetails(origin_, GetTotalScore(),
visits(), media_playbacks(),
last_media_playback_time());
return media::mojom::MediaEngagementScoreDetails::New(
origin_, GetTotalScore(), visits(), media_playbacks(),
last_media_playback_time().ToJsTime());
}
MediaEngagementScore::~MediaEngagementScore() = default;
......
......@@ -66,7 +66,7 @@ class MediaEngagementScore final {
}
// Get a breakdown of the score that can be serialized by Mojo.
media::mojom::MediaEngagementScoreDetails GetScoreDetails() const;
media::mojom::MediaEngagementScoreDetailsPtr GetScoreDetails() const;
private:
friend class MediaEngagementServiceTest;
......
......@@ -4,7 +4,6 @@
module media.mojom;
import "mojo/common/time.mojom";
import "url/mojo/url.mojom";
struct MediaEngagementScoreDetails {
......@@ -14,5 +13,11 @@ struct MediaEngagementScoreDetails {
// Details of the components which make up |score|.
int32 visits;
int32 media_playbacks;
mojo.common.mojom.Time last_media_playback_time;
// Last media playback time in milliseconds since the epoch format.
double last_media_playback_time;
};
interface MediaEngagementScoreDetailsProvider {
GetMediaEngagementScoreDetails() => (array<MediaEngagementScoreDetails> info);
};
......@@ -97,14 +97,14 @@ class MediaEngagementScoreTest : public ChromeRenderViewHostTestHarness {
void SetVisits(int visits) { score_->visits_ = visits; }
void VerifyGetScoreDetails(MediaEngagementScore* score) {
media::mojom::MediaEngagementScoreDetails details =
media::mojom::MediaEngagementScoreDetailsPtr details =
score->GetScoreDetails();
EXPECT_EQ(details.origin, score->origin_);
EXPECT_EQ(details.total_score, score->GetTotalScore());
EXPECT_EQ(details.visits, score->visits());
EXPECT_EQ(details.media_playbacks, score->media_playbacks());
EXPECT_EQ(details.last_media_playback_time,
score->last_media_playback_time());
EXPECT_EQ(details->origin, score->origin_);
EXPECT_EQ(details->total_score, score->GetTotalScore());
EXPECT_EQ(details->visits, score->visits());
EXPECT_EQ(details->media_playbacks, score->media_playbacks());
EXPECT_EQ(details->last_media_playback_time,
score->last_media_playback_time().ToJsTime());
}
};
......
......@@ -201,11 +201,11 @@ void MediaEngagementService::RecordVisit(const GURL& url) {
score.Commit();
}
std::vector<media::mojom::MediaEngagementScoreDetails>
std::vector<media::mojom::MediaEngagementScoreDetailsPtr>
MediaEngagementService::GetAllScoreDetails() const {
std::set<GURL> origins = GetEngagementOriginsFromContentSettings(profile_);
std::vector<media::mojom::MediaEngagementScoreDetails> details;
std::vector<media::mojom::MediaEngagementScoreDetailsPtr> details;
details.reserve(origins.size());
for (const GURL& origin : origins) {
// TODO(beccahughes): Why would an origin not be valid here?
......
......@@ -62,7 +62,7 @@ class MediaEngagementService : public KeyedService,
// Returns an array of engagement score details for all origins which
// have a score.
std::vector<media::mojom::MediaEngagementScoreDetails> GetAllScoreDetails()
std::vector<media::mojom::MediaEngagementScoreDetailsPtr> GetAllScoreDetails()
const;
// Overridden from history::HistoryServiceObserver:
......
......@@ -196,7 +196,7 @@ class MediaEngagementServiceTest : public ChromeRenderViewHostTestHarness {
void SetNow(base::Time now) { test_clock_->SetNow(now); }
std::vector<media::mojom::MediaEngagementScoreDetails> GetAllScoreDetails()
std::vector<media::mojom::MediaEngagementScoreDetailsPtr> GetAllScoreDetails()
const {
return service_->GetAllScoreDetails();
}
......
# For Media Engagement
mlamouri@chromium.org
beccahughes@chromium.org
# For WebRTC
per-file webrtc_*=file://third_party/webrtc_overrides/OWNERS
# COMPONENT: Internals>Media>UI
<!doctype html>
<html>
<head>
<title>Media Engagement</title>
<meta charset="utf-8">
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<script src="chrome://resources/js/mojo_bindings.js"></script>
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome/browser/media/media_engagement_score_details.mojom.js">
</script>
<script src="chrome://media-engagement/media-engagement.js"></script>
<style>
body {
font-family: 'Roboto', 'Noto', sans-serif;
font-size: 14px;
}
table {
border-collapse: collapse;
}
table td,
table th {
border: 1px solid #777;
padding-left: 4px;
padding-right: 4px;
}
table th {
background: rgb(224, 236, 255);
cursor: pointer;
padding-bottom: 4px;
padding-right: 16px;
padding-top: 4px;
white-space: nowrap;
}
.engagement-bar {
background-color: black;
height: 2px;
}
.engagement-bar-cell {
border: none;
}
.origin-cell {
background-color: rgba(230, 230, 230, 0.5);
min-width: 500px;
}
.visits-count-cell,
.media-playbacks-count-cell,
.last-playback-time-cell {
background-color: rgba(230, 230, 230, 0.5);
text-align: right;
}
.base-score-input {
border: 1px solid #ccc;
border-radius: 2px;
text-align: right;
width: 70px;
}
.base-score-input:focus {
border: 1px solid rgb(143, 185, 252);
box-shadow: 0 0 2px rgb(113, 158, 206);
outline: none;
}
table tr:hover {
background: rgb(255, 255, 187);
}
th.sort-column::after {
content: '▲';
position: absolute;
}
th[sort-reverse].sort-column::after {
content: '▼';
position: absolute;
}
</style>
</head>
<body>
<h1>Media Engagement</h1>
<table>
<thead>
<tr id="engagement-table-header">
<th sort-key="origin">
Origin
</th>
<th sort-key="visits" sort-reverse>
Visits
</th>
<th sort-key="mediaPlaybacks" sort-reverse>
Number of Playbacks
</th>
<th sort-key="lastMediaPlaybackTime" sort-reverse>
Last Playback
</th>
<th sort-key="totalScore" class="sort-column" sort-reverse>
Score
</th>
</tr>
</thead>
<tbody id="engagement-table-body">
</tbody>
</table>
<template id="datarow">
<tr>
<td class="origin-cell"></td>
<td class="visits-count-cell"></td>
<td class="media-playbacks-count-cell"></td>
<td class="last-playback-time-cell"></td>
<td class="total-score-cell"></td>
<td class="engagement-bar-cell">
<div class="engagement-bar"></div>
</td>
</tr>
</template>
</body>
</html>
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
// Allow a function to be provided by tests, which will be called when
// the page has been populated with media engagement details.
var pageIsPopulatedResolver = new PromiseResolver();
function whenPageIsPopulatedForTest() {
return pageIsPopulatedResolver.promise;
}
(function() {
var uiHandler = null;
var info = null;
var engagementTableBody = null;
var sortReverse = true;
var sortKey = 'totalScore';
/**
* Creates a single row in the engagement table.
* @param {!MediaEngagementScoreDetails} rowInfo The info to create the row.
* @return {!HTMLElement}
*/
function createRow(rowInfo) {
var template = $('datarow');
var td = template.content.querySelectorAll('td');
td[0].textContent = rowInfo.origin.url;
td[1].textContent = rowInfo.visits;
td[2].textContent = rowInfo.mediaPlaybacks;
td[3].textContent = rowInfo.lastMediaPlaybackTime ?
new Date(rowInfo.lastMediaPlaybackTime).toISOString() :
'';
td[4].textContent = rowInfo.totalScore ? rowInfo.totalScore.toFixed(2) : '0';
td[5].getElementsByClassName('engagement-bar')[0].style.width =
(rowInfo.totalScore * 50) + 'px';
return document.importNode(template.content, true);
}
/**
* Remove all rows from the engagement table.
*/
function clearTable() {
engagementTableBody.innerHTML = '';
}
/**
* Sort the engagement info based on |sortKey| and |sortReverse|.
*/
function sortInfo() {
info.sort((a, b) => {
return (sortReverse ? -1 : 1) * compareTableItem(sortKey, a, b);
});
}
/**
* Compares two MediaEngagementScoreDetails objects based on |sortKey|.
* @param {string} sortKey The name of the property to sort by.
* @param {number|url.mojom.Url} The first object to compare.
* @param {number|url.mojom.Url} The second object to compare.
* @return {number} A negative number if |a| should be ordered before
* |b|, a positive number otherwise.
*/
function compareTableItem(sortKey, a, b) {
var val1 = a[sortKey];
var val2 = b[sortKey];
// Compare the hosts of the origin ignoring schemes.
if (sortKey == 'origin')
return new URL(val1.url).host > new URL(val2.url).host ? 1 : -1;
if (sortKey == 'visits' || sortKey == 'mediaPlaybacks' ||
sortKey == 'lastMediaPlaybackTime' || sortKey == 'totalScore') {
return val1 - val2;
}
assertNotReached('Unsupported sort key: ' + sortKey);
return 0;
}
/**
* Regenerates the engagement table from |info|.
*/
function renderTable() {
clearTable();
sortInfo();
info.forEach(rowInfo => engagementTableBody.appendChild(createRow(rowInfo)));
}
/**
* Retrieve media engagement info and render the engagement table.
*/
function updateEngagementTable() {
// Populate engagement table.
uiHandler.getMediaEngagementScoreDetails().then(response => {
info = response.info;
renderTable();
pageIsPopulatedResolver.resolve();
});
}
document.addEventListener('DOMContentLoaded', function() {
uiHandler = new media.mojom.MediaEngagementScoreDetailsProviderPtr;
Mojo.bindInterface(
media.mojom.MediaEngagementScoreDetailsProvider.name,
mojo.makeRequest(uiHandler).handle);
updateEngagementTable();
engagementTableBody = $('engagement-table-body');
// Set table header sort handlers.
var engagementTableHeader = $('engagement-table-header');
var headers = engagementTableHeader.children;
for (var i = 0; i < headers.length; i++) {
headers[i].addEventListener('click', (e) => {
var newSortKey = e.target.getAttribute('sort-key');
if (sortKey == newSortKey) {
sortReverse = !sortReverse;
} else {
sortKey = newSortKey;
sortReverse = false;
}
var oldSortColumn = document.querySelector('.sort-column');
oldSortColumn.classList.remove('sort-column');
e.target.classList.add('sort-column');
if (sortReverse)
e.target.setAttribute('sort-reverse', '');
else
e.target.removeAttribute('sort-reverse');
renderTable();
});
}
});
})();
......@@ -367,6 +367,8 @@ split_static_library("ui") {
"webui/local_state/local_state_ui.h",
"webui/log_web_ui_url.cc",
"webui/log_web_ui_url.h",
"webui/media/media_engagement_ui.cc",
"webui/media/media_engagement_ui.h",
"webui/metrics_handler.cc",
"webui/metrics_handler.h",
"webui/mojo_web_ui_controller.cc",
......@@ -479,6 +481,7 @@ split_static_library("ui") {
"//chrome/browser:resource_prefetch_predictor_proto",
"//chrome/browser/devtools",
"//chrome/browser/engagement:mojo_bindings",
"//chrome/browser/media:mojo_bindings",
"//chrome/browser/safe_browsing",
"//chrome/browser/ui/webui/omnibox:mojo_bindings",
"//chrome/browser/ui/webui/usb_internals:mojo_bindings",
......
......@@ -16,6 +16,7 @@
#include "chrome/browser/devtools/devtools_ui_bindings.h"
#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h"
#include "chrome/browser/engagement/site_engagement_service.h"
#include "chrome/browser/media/media_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/search/suggestions/suggestions_ui.h"
......@@ -38,6 +39,7 @@
#include "chrome/browser/ui/webui/invalidations_ui.h"
#include "chrome/browser/ui/webui/local_state/local_state_ui.h"
#include "chrome/browser/ui/webui/log_web_ui_url.h"
#include "chrome/browser/ui/webui/media/media_engagement_ui.h"
#include "chrome/browser/ui/webui/net_export_ui.h"
#include "chrome/browser/ui/webui/net_internals/net_internals_ui.h"
#include "chrome/browser/ui/webui/ntp_tiles_internals_ui.h"
......@@ -626,6 +628,11 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
return &NewWebUI<SiteEngagementUI>;
}
if (MediaEngagementService::IsEnabled() &&
url.host_piece() == chrome::kChromeUIMediaEngagementHost) {
return &NewWebUI<MediaEngagementUI>;
}
return NULL;
}
......
# For Media Engagement
mlamouri@chromium.org
beccahughes@chromium.org
# For WebRTC
per-file webrtc_*=file://third_party/webrtc_overrides/OWNERS
# COMPONENT: Internals>Media>UI
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/media/media_engagement_ui.h"
#include "base/macros.h"
#include "chrome/browser/media/media_engagement_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_data_source.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace {
// Implementation of media::mojom::MediaEngagementScoreDetailsProvider that
// retrieves engagement details from the MediaEngagementService.
class MediaEngagementScoreDetailsProviderImpl
: public media::mojom::MediaEngagementScoreDetailsProvider {
public:
MediaEngagementScoreDetailsProviderImpl(
Profile* profile,
mojo::InterfaceRequest<media::mojom::MediaEngagementScoreDetailsProvider>
request)
: profile_(profile), binding_(this, std::move(request)) {
DCHECK(profile_);
service_ = MediaEngagementService::Get(profile_);
}
~MediaEngagementScoreDetailsProviderImpl() override {}
// media::mojom::MediaEngagementScoreDetailsProvider overrides:
void GetMediaEngagementScoreDetails(
media::mojom::MediaEngagementScoreDetailsProvider::
GetMediaEngagementScoreDetailsCallback callback) override {
std::move(callback).Run(service_->GetAllScoreDetails());
}
private:
Profile* profile_;
MediaEngagementService* service_;
mojo::Binding<media::mojom::MediaEngagementScoreDetailsProvider> binding_;
DISALLOW_COPY_AND_ASSIGN(MediaEngagementScoreDetailsProviderImpl);
};
} // namespace
MediaEngagementUI::MediaEngagementUI(content::WebUI* web_ui)
: MojoWebUIController<media::mojom::MediaEngagementScoreDetailsProvider>(
web_ui) {
// Setup the data source behind chrome://media-engagement.
std::unique_ptr<content::WebUIDataSource> source(
content::WebUIDataSource::Create(chrome::kChromeUIMediaEngagementHost));
source->AddResourcePath("media-engagement.js", IDR_MEDIA_ENGAGEMENT_JS);
source->AddResourcePath(
"chrome/browser/media/media_engagement_score_details.mojom.js",
IDR_MEDIA_ENGAGEMENT_MOJO_JS);
source->AddResourcePath("url/mojo/url.mojom.js", IDR_URL_MOJO_JS);
source->SetDefaultResource(IDR_MEDIA_ENGAGEMENT_HTML);
source->UseGzip(std::unordered_set<std::string>());
content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), source.release());
}
MediaEngagementUI::~MediaEngagementUI() = default;
void MediaEngagementUI::BindUIHandler(
const service_manager::BindSourceInfo& source_info,
media::mojom::MediaEngagementScoreDetailsProviderRequest request) {
ui_handler_ = base::MakeUnique<MediaEngagementScoreDetailsProviderImpl>(
Profile::FromWebUI(web_ui()), std::move(request));
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_
#define CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_
#include "base/macros.h"
#include "chrome/browser/media/media_engagement_score_details.mojom.h"
#include "chrome/browser/ui/webui/mojo_web_ui_controller.h"
// The UI for chrome://media-engagement/.
class MediaEngagementUI
: public MojoWebUIController<
media::mojom::MediaEngagementScoreDetailsProvider> {
public:
explicit MediaEngagementUI(content::WebUI* web_ui);
~MediaEngagementUI() override;
private:
// MojoWebUIController overrides:
void BindUIHandler(const service_manager::BindSourceInfo& source_info,
media::mojom::MediaEngagementScoreDetailsProviderRequest
request) override;
std::unique_ptr<media::mojom::MediaEngagementScoreDetailsProvider>
ui_handler_;
DISALLOW_COPY_AND_ASSIGN(MediaEngagementUI);
};
#endif // CHROME_BROWSER_UI_WEBUI_MEDIA_MEDIA_ENGAGEMENT_UI_H_
......@@ -221,6 +221,7 @@ const char kChromeUILargeIconHost[] = "large-icon";
const char kChromeUILocalStateHost[] = "local-state";
const char kChromeUIMdPolicyHost[] = "md-policy";
const char kChromeUIMdSettingsHost[] = "md-settings";
const char kChromeUIMediaEngagementHost[] = "media-engagement";
const char kChromeUINaClHost[] = "nacl";
const char kChromeUINetExportHost[] = "net-export";
const char kChromeUINetInternalsHost[] = "net-internals";
......
......@@ -62,6 +62,8 @@ extern const char kChromeUIInstantURL[];
extern const char kChromeUIInterstitialURL[];
extern const char kChromeUIInvalidationsURL[];
extern const char kChromeUIMdPolicyURL[];
extern const char kChromeUIMdSettingsURL[];
extern const char kChromeUIMediaEngagementHost[];
extern const char kChromeUINaClURL[];
extern const char kChromeUINetInternalsURL[];
extern const char kChromeUINewProfileURL[];
......@@ -74,7 +76,6 @@ extern const char kChromeUIMdUserManagerUrl[];
extern const char kChromeUIPrintURL[];
extern const char kChromeUIQuitURL[];
extern const char kChromeUIRestartURL[];
extern const char kChromeUIMdSettingsURL[];
extern const char kChromeUISettingsURL[];
extern const char kChromeUIContentSettingsURL[];
// TODO(dbeam): remove settings-frame.
......
......@@ -59,6 +59,7 @@ js2gtest("browser_tests_js_webui") {
"md_downloads/downloads_browsertest.js",
"md_history/md_history_browsertest.js",
"md_user_manager/user_manager_browsertest.js",
"media/media_engagement_browsertest.js",
"media_router/media_router_elements_browsertest.js",
"mock4js_browsertest.js",
"net_internals/bandwidth_view.js",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview Test suite for the Media Engagement WebUI.
*/
var ROOT_PATH = '../../../../../';
var EXAMPLE_URL_1 = 'http://example.com/';
var EXAMPLE_URL_2 = 'http://shmlexample.com/';
GEN('#include "base/command_line.h"');
GEN('#include "chrome/browser/media/media_engagement_service.h"');
GEN('#include "chrome/browser/media/media_engagement_service_factory.h"');
GEN('#include "chrome/browser/ui/browser.h"');
function MediaEngagementWebUIBrowserTest() {}
MediaEngagementWebUIBrowserTest.prototype = {
__proto__: testing.Test.prototype,
browsePreload: 'chrome://media-engagement',
commandLineSwitches: [{
switchName: 'enable-features',
switchValue: 'media-engagement'
}],
runAccessibilityChecks: false,
isAsync: true,
testGenPreamble: function() {
GEN('MediaEngagementService* service =');
GEN(' MediaEngagementServiceFactory::GetForProfile(');
GEN(' browser()->profile());');
GEN('service->RecordVisit(GURL("' + EXAMPLE_URL_1 + '"));');
GEN('service->RecordVisit(GURL("' + EXAMPLE_URL_2 + '"));');
},
extraLibraries: [
ROOT_PATH + 'third_party/mocha/mocha.js',
ROOT_PATH + 'chrome/test/data/webui/mocha_adapter.js',
],
};
TEST_F('MediaEngagementWebUIBrowserTest', 'All', function() {
suiteSetup(function() {
return whenPageIsPopulatedForTest();
});
test('check engagement values are loaded', function() {
var originCells =
Array.from(document.getElementsByClassName('origin-cell'));
assertDeepEquals(
[EXAMPLE_URL_1, EXAMPLE_URL_2], originCells.map(x => x.textContent));
});
mocha.run();
});
......@@ -81,7 +81,7 @@
# START chrome/browser section.
"chrome/browser/browser_resources.grd": {
"includes": [11000],
"structures": [11510],
"structures": [11520],
},
"chrome/browser/resources/component_extension_resources.grd": {
"includes": [11610],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment