blob: 8e40dd6d7d7d16cc1b7d7e9cb27346e065762684 [file] [log] [blame]
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
WI.AuditTestGroupContentView = class AuditTestGroupContentView extends WI.AuditTestContentView
{
constructor(representedObject)
{
console.assert(representedObject instanceof WI.AuditTestGroup || representedObject instanceof WI.AuditTestGroupResult);
super(representedObject);
this.element.classList.add("audit-test-group");
this.element.classList.toggle("contains-test-case", this._subobjects().some((test) => test instanceof WI.AuditTestCase || test instanceof WI.AuditTestCaseResult));
this.element.classList.toggle("contains-test-group", this._subobjects().some((test) => test instanceof WI.AuditTestGroup || test instanceof WI.AuditTestGroupResult));
this._levelScopeBar = null;
}
// Protected
initialLayout()
{
super.initialLayout();
let informationContainer = this.headerView.element.appendChild(document.createElement("div"));
informationContainer.classList.add("information");
let nameElement = informationContainer.appendChild(document.createElement("h1"));
nameElement.textContent = this.representedObject.name;
if (this.representedObject.description) {
let descriptionElement = informationContainer.appendChild(document.createElement("p"));
descriptionElement.textContent = this.representedObject.description;
}
this._levelNavigationBar = new WI.NavigationBar(document.createElement("nav"));
this._levelNavigationBar.element.dataset.prefix = WI.UIString("Showing:");
this.headerView.addSubview(this._levelNavigationBar);
this._percentageContainer = this.headerView.element.appendChild(document.createElement("div"));
this._percentageContainer.classList.add("percentage-pass");
this._percentageContainer.hidden = true;
this._percentageTextElement = document.createElement("span");
const format = WI.UIString("%s%%", "Percentage (of audits)", "The number of tests that passed expressed as a percentage, followed by a literal %.");
String.format(format, [this._percentageTextElement], String.standardFormatters, this._percentageContainer, (a, b) => {
a.append(b);
return a;
});
}
layout()
{
if (this.layoutReason !== WI.View.LayoutReason.Dirty)
return;
super.layout();
let result = this.representedObject.result;
if (!result) {
if (this._levelScopeBar) {
this._levelNavigationBar.removeNavigationItem(this._levelScopeBar);
this._levelScopeBar = null;
}
this._percentageContainer.hidden = true;
this._percentageTextElement.textContent = "";
if (this.representedObject.runningState === WI.AuditManager.RunningState.Inactive)
this.showNoResultPlaceholder();
else if (this.representedObject.runningState === WI.AuditManager.RunningState.Active)
this.showRunningPlaceholder();
else if (this.representedObject.runningState === WI.AuditManager.RunningState.Stopping)
this.showStoppingPlaceholder();
return;
}
let levelCounts = result.levelCounts;
let totalCount = Object.values(levelCounts).reduce((accumulator, current) => accumulator + current);
this._percentageTextElement.textContent = Math.floor(100 * levelCounts[WI.AuditTestCaseResult.Level.Pass] / totalCount);
this._percentageContainer.hidden = false;
if (!this._levelScopeBar) {
let scopeBarItems = [];
let addScopeBarItem = (level, labelSingular, labelPlural) => {
let count = levelCounts[level];
if (isNaN(count) || count <= 0)
return;
let label = (labelPlural && count !== 1) ? labelPlural : labelSingular;
let scopeBarItem = new WI.ScopeBarItem(level, label.format(count), {
className: level,
exclusive: false,
independent: true,
});
scopeBarItem.selected = true;
scopeBarItem.element.insertBefore(document.createElement("img"), scopeBarItem.element.firstChild);
scopeBarItems.push(scopeBarItem);
};
addScopeBarItem(WI.AuditTestCaseResult.Level.Pass, WI.UIString("%d Passed", "%d Passed (singular)"), WI.UIString("%d Passed", "%d Passed (plural)"));
addScopeBarItem(WI.AuditTestCaseResult.Level.Warn, WI.UIString("%d Warning"), WI.UIString("%d Warnings"));
addScopeBarItem(WI.AuditTestCaseResult.Level.Fail, WI.UIString("%d Failed", "%d Failed (singular)"), WI.UIString("%d Failed", "%d Failed (plural)"));
addScopeBarItem(WI.AuditTestCaseResult.Level.Error, WI.UIString("%d Error"), WI.UIString("%d Errors"));
addScopeBarItem(WI.AuditTestCaseResult.Level.Unsupported, WI.UIString("%d Unsupported", "%d Unsupported (singular)"), WI.UIString("%d Unsupported", "%d Unsupported (plural)"));
this._levelScopeBar = new WI.ScopeBar(null, scopeBarItems);
this._levelScopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._handleLevelScopeBarSelectionChanged, this);
this._levelNavigationBar.addNavigationItem(this._levelScopeBar);
}
if (this.applyFilter())
this.hidePlaceholder();
else
this.showFilteredPlaceholder();
}
shown()
{
super.shown();
if (this.representedObject instanceof WI.AuditTestGroup) {
this.representedObject.addEventListener(WI.AuditTestBase.Event.Progress, this._handleTestGroupProgress, this);
this.representedObject.addEventListener(WI.AuditTestBase.Event.Scheduled, this._handleTestGroupScheduled, this);
}
for (let subobject of this._subobjects()) {
if (subobject instanceof WI.AuditTestBase && subobject.disabled)
continue;
let view = WI.ContentView.contentViewForRepresentedObject(subobject);
this.contentView.addSubview(view);
view.shown();
}
}
hidden()
{
for (let view of this.contentView.subviews)
view.hidden();
this.contentView.removeAllSubviews();
super.hidden();
}
applyFilter(levels)
{
if (this._levelScopeBar && !levels)
levels = this._levelScopeBar.selectedItems.map((item) => item.id);
this._updateLevelScopeBar(levels);
return super.applyFilter(levels);
}
resetFilter()
{
this._updateLevelScopeBar(Object.values(WI.AuditTestCaseResult.Level));
super.resetFilter();
}
showRunningPlaceholder()
{
if (!this.placeholderElement || !this.placeholderElement.__placeholderRunning) {
this.placeholderElement = WI.createMessageTextView(WI.UIString("Running the \u201C%s\u201D audit").format(this.representedObject.name));
this.placeholderElement.__placeholderRunning = true;
this.placeholderElement.__progress = document.createElement("progress");
this.placeholderElement.__progress.value = 0;
this.placeholderElement.appendChild(this.placeholderElement.__progress);
}
super.showRunningPlaceholder();
}
// Private
_subobjects()
{
if (this.representedObject instanceof WI.AuditTestGroup)
return this.representedObject.tests;
if (this.representedObject instanceof WI.AuditTestGroupResult)
return this.representedObject.results;
console.error("Unknown representedObject", this.representedObject);
return [];
}
_updateLevelScopeBar(levels)
{
if (!this._levelScopeBar)
return;
for (let item of this._levelScopeBar.items)
item.selected = levels.includes(item.id);
for (let view of this.contentView.subviews) {
if (view instanceof WI.AuditTestGroupContentView)
view._updateLevelScopeBar(levels);
}
}
_handleTestGroupProgress(event)
{
let {index, count} = event.data;
if (this.placeholderElement && this.placeholderElement.__progress)
this.placeholderElement.__progress.value = (index + 1) / count;
}
_handleTestGroupScheduled(event)
{
if (this.placeholderElement && this.placeholderElement.__progress)
this.placeholderElement.__progress.value = 0;
}
_handleLevelScopeBarSelectionChanged(event)
{
this.needsLayout();
}
};