Skip to content

frontend: Support suite & platform filters #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 36 additions & 26 deletions frontend/src/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<h2>
<nav>
{{#navbar}}
<a href="#{{ path }}">{{ name }}</a>
<a href="{{ route }}">{{ name }}</a>
{{/navbar}}
</nav>
<span> : {{ total }} files</span>
Expand Down Expand Up @@ -47,7 +47,7 @@ <h2>
<h2>
<nav>
{{#navbar}}
<a href="#{{ revision }}:{{ path }}">{{ name }}</a>
<a href="{{ route }}">{{ name }}</a>
{{/navbar}}
</nav>
</h2>
Expand All @@ -73,7 +73,7 @@ <h2>
<h2>
<nav>
{{#navbar}}
<a href="#{{ revision }}:{{ path }}">{{ name }}</a>
<a href="{{ route }}">{{ name }}</a>
{{/navbar}}
</nav>
<span> : {{ files.length }} files</span>
Expand All @@ -88,7 +88,7 @@ <h2>

{{#files}}
<div class="row">
<span class="filename"><a href="#{{ revision }}:{{ path }}">{{ file_name }}</a></span>
<span class="filename"><a href="{{ route }}">{{ file_name }}</a></span>
<span>{{ children }}</span>
<span>{{ coveragePercent }} %</span>
</div>
Expand All @@ -102,29 +102,39 @@ <h2>
<span>Revision <samp>{{ revision }}</samp> from {{ date }}</span>
</script>

<header>
<div id="menu_browser">
<a href="#zero:">View the zero coverage report</a>
&bull;
<input type="text" id="revision" placeholder="Mercurial revision" </input>
</div>
<script id="menu_browser" type="x-tmpl-mustache">
<a href="#view=zero">View the zero coverage report</a>
&bull;
<input type="text" name="revision" placeholder="Mercurial revision" value="{{revision}}"></input>
&bull;
<select name="platform">
<option value="all">All platforms</option>
{{#platforms}}
<option {{#selected}}selected="selected"{{/selected}} value="{{name}}">{{name}}</option>
{{/platforms}}
</select>
<select name="suite">
<option value="all">All test suites</option>
{{#suites}}
<option {{#selected}}selected="selected"{{/selected}} value="{{name}}">{{name}}</option>
{{/suites}}
</select>
</script>

<div id="menu_zero">
<input type="checkbox" name="third_party" id="third_party" checked="checked"><label for="third_party">Show third-party files</label>
<input type="checkbox" name="headers" id="headers"><label for="headers">Show headers</label>
<input type="checkbox" name="completely_uncovered" id="completely_uncovered"><label for="completely_uncovered">Show completely uncovered files only</label>
<input type="checkbox" name="cpp" id="cpp" checked="checked"><label for="cpp">C/C++</label>
<input type="checkbox" name="js" id="js" checked="checked"><label for="js">JavaScript</label>
<input type="checkbox" name="java" id="java" checked="checked"><label for="java">Java</label>
<input type="checkbox" name="rust" id="rust" checked="checked"><label for="rust">Rust</label>
<select id="last_push">
<option value="all">All</option>
<option value="one_year">0 &lt; 1 year</option>
<option value="two_years">1 &lt; 2 years</option>
<option value="older_than_two_years">Older than 2 years</option>
</select>
</div>
</header>
<script id="menu_zero" type="x-tmpl-mustache">
{{#filters}}
<input type="checkbox" name="{{ key }}" id="{{ key }}" {{#checked}}checked="checked"{{/checked}}>
<label for="{{ key }}">{{ message }}</label>
{{/filters}}

<select name="last_push" id="last_push">
{{#last_pushes}}
<option {{#selected}}selected="selected"{{/selected}} value="{{value}}">{{message}}</option>
{{/last_pushes}}
</select>
</script>

<header id="menu"></header>

<main id="main">
<div id="message" class="message loading">Loading...</div>
Expand Down
109 changes: 81 additions & 28 deletions frontend/src/common.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
import Mustache from 'mustache';
import { buildRoute, readRoute, updateRoute } from './route.js';
import {ZERO_COVERAGE_FILTERS} from './zero_coverage_report.js';

export const REV_LATEST = 'latest';

function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion failed");
}
}

function domContentLoaded() {
return new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve));
}
export const DOM_READY = domContentLoaded();

export async function main(load, display, opts) {
// Immediately listen to DOM event

export async function main(load, display) {
// Load initial data before DOM is available
let data = await load();

// Wait for DOM to be ready before displaying
await DOM_READY;
await display(data);
monitor_options();

// Full workflow, loading then displaying data
// used for following updates
let full = async function() {
let data = await load();
await display(data);
monitor_options();
};
monitor_options(opts, full);

// React to url changes
window.onhashchange = full;
}


// Coverage retrieval.

const COVERAGE_BACKEND_HOST = process.env.BACKEND_URL;
Expand Down Expand Up @@ -64,8 +60,9 @@ function cache_set(cache, key, value) {
}

let path_coverage_cache = {};
export async function get_path_coverage(path, changeset) {
let data = cache_get(path_coverage_cache, `${changeset}_${path}`);
export async function get_path_coverage(path, changeset, platform, suite) {
let cache_key = `${changeset}_${path}_${platform}_${suite}`;
let data = cache_get(path_coverage_cache, cache_key);
if (data) {
return data;
}
Expand All @@ -74,33 +71,47 @@ export async function get_path_coverage(path, changeset) {
if (changeset && changeset !== REV_LATEST) {
params += `&changeset=${changeset}`;
}
if (platform && platform !== 'all') {
params += `&platform=${platform}`;
}
if (suite && suite !== 'all') {
params += `&suite=${suite}`;
}
let response = await fetch(`${COVERAGE_BACKEND_HOST}/v2/path?${params}`).catch(alert);
if (response.status !== 200) {
throw new Error(response.status + ' - ' + response.statusText);
}
data = await response.json();

cache_set(path_coverage_cache, `${changeset}_${path}`, data);
cache_set(path_coverage_cache, cache_key, data);

return data;
}

let history_cache = {};
export async function get_history(path) {
export async function get_history(path, platform, suite) {
// Backend needs path without trailing /
if (path && path.endsWith('/')) {
path = path.substring(0, path.length-1);
}

let data = cache_get(history_cache, path);
let cache_key = `${path}_${platform}_${suite}`;
let data = cache_get(history_cache, cache_key);
if (data) {
return data;
}

let response = await fetch(`${COVERAGE_BACKEND_HOST}/v2/history?path=${path}`);
let params = `path=${path}`;
if (platform && platform !== 'all') {
params += `&platform=${platform}`;
}
if (suite && suite !== 'all') {
params += `&suite=${suite}`;
}
let response = await fetch(`${COVERAGE_BACKEND_HOST}/v2/history?${params}`);
data = await response.json();

cache_set(history_cache, path, data);
cache_set(history_cache, cache_key, data);

// Check data has coverage values
// These values are missing when going above 2 levels right now
Expand Down Expand Up @@ -131,20 +142,62 @@ export async function get_zero_coverage_data() {
}


// Option handling.
let filters_cache = {};
export async function get_filters() {
let data = cache_get(filters_cache, '');
if (data) {
return data;
}

let response = await fetch(`${COVERAGE_BACKEND_HOST}/v2/filters`);
data = await response.json();

cache_set(filters_cache, '', data);

function is_enabled(opt) {
let elem = document.getElementById(opt);
return elem.checked;
return data;
}

function monitor_options(opts, callback) {
for (let opt of opts) {
let elem = document.getElementById(opt);
elem.onchange = callback;

// Option handling.

export function is_enabled(opt) {
let route = readRoute();
let value = 'off';
if (route[opt]) {
value = route[opt];
} else if (ZERO_COVERAGE_FILTERS[opt]) {
value = ZERO_COVERAGE_FILTERS[opt].default_value;
}
return value === 'on';
}

function monitor_options() {
// Monitor input & select changes
let fields = document.querySelectorAll('input, select');
for(let field of fields) {
if (field.type == 'text') {
// React on enter
field.onkeydown = async (evt) => {
if(evt.keyCode === 13) {
let params = {};
params[evt.target.name] = evt.target.value;
updateRoute(params);
}
}
} else {
// React on change
field.onchange = async (evt) => {
let value = evt.target.value;
if (evt.target.type == 'checkbox') {
value = evt.target.checked ? 'on' : 'off';
}
let params = {};
params[evt.target.name] = value;
updateRoute(params);
}
}
}
}

// hgmo.

Expand Down Expand Up @@ -267,14 +320,14 @@ export function build_navbar(path, revision) {
let links = [
{
'name': 'mozilla-central',
'path': '',
'route': buildRoute({path: '', revision})
}
];
return links.concat(path.split('/').map(file => {
base += (base ? '/' : '') + file;
return {
'name': file,
'path': base,
'route': buildRoute({path: base, revision})
};
}));
}
Expand Down
Loading