products/Sources/formale Sprachen/C/Firefox/testing/web-platform/tests/tools/wave/www/results.html
<!DOCTYPE html >
<html lang="en" style ="overflow: auto;" >
<head >
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title >Session Results - Web Platform Test</title >
<link rel="stylesheet" href="css/bulma-0.7.5/bulma.min.css" />
<link rel="stylesheet" href="css/fontawesome-5.7.2.min.css" />
<!-- <link rel="stylesheet" href="css/result.css" /> -->
<script src="lib/utils.js" ></script >
<script src="lib/wave-service.js" ></script >
<script src="lib/ui.js" ></script >
<style >
.site-logo {
max-width: 300px;
margin: 0 0 30px -15px;
}
</style >
</head >
<body >
<script >
let token = null;
window.onload = () => {
const query = utils.parseQuery(location.search);
token = query.token;
if (token) {
resultUi.render();
resultUi.refreshData();
} else {
location.href = WEB_ROOT + "overview.html" + location.search;
}
WaveService.addRecentSession(token);
};
const resultUi = {
state: {
details : null,
results: null,
referenceSessions: [],
lastCompletedTests: [],
malfunctioningTests: [],
addLabelVisible: false,
},
refreshData: (toUpdate) => {
WaveService.readStatus(function (config) {
resultUi.state.reportsEnabled = config.reportsEnabled;
resultUi.renderApiResults();
});
switch (toUpdate) {
case "test_completed" :
resultUi.refreshSessionStatus(() => {
resultUi.refreshSessionResults(() => {
resultUi.renderApiResults();
});
});
resultUi.refreshLastCompletedTests(() => {
resultUi.renderLastCompletedTests();
});
break;
case "status" :
resultUi.refreshSessionStatus(() => {
resultUi.renderControls();
resultUi.renderSessionDetails();
});
break;
case "" :
case null:
case undefined:
resultUi.refreshSessionConfiguration(() => {
resultUi.refreshSessionStatus(() => {
resultUi.refreshSessionResults(() => {
resultUi.refreshReferenceSessions(() =>
resultUi.renderReferenceSessions()
);
resultUi.renderControls();
resultUi.renderSessionDetails();
resultUi.renderApiResults();
resultUi.renderExportView();
resultUi.refreshLastCompletedTests(() => {
resultUi.renderLastCompletedTests();
});
resultUi.refreshMalfunctioningTests(() => {
resultUi.renderMalfunctioningTests();
});
});
});
});
break;
}
},
refreshSessionConfiguration(callback = () => {}) {
WaveService.readSession(token, (configuration) => {
resultUi.state.configuration = configuration;
callback(configuration);
});
},
refreshSessionStatus(callback = () => {}) {
WaveService.readSessionStatus(token, (status) => {
resultUi.state.status = status;
if (status.status !== "completed" && status.status !== "aborted" )
WaveService.addSessionEventListener(
token,
resultUi.handleSessionEvent
);
callback(status);
});
},
refreshReferenceSessions(callback = () => {}) {
const { configuration } = resultUi.state;
if (!configuration) return;
const { referenceTokens } = configuration;
if (!referenceTokens) return;
WaveService.readMultipleSessions(referenceTokens, (configuration) => {
resultUi.state.referenceSessions = configuration;
resultUi.renderReferenceSessions();
callback(configuration);
});
},
refreshSessionResults(callback = () => {}) {
WaveService.readResultsCompact(token, (results) => {
resultUi.state.results = results;
callback(results);
});
},
refreshLastCompletedTests(callback = () => {}) {
if (resultUi.state.configuration.isPublic) return;
WaveService.readLastCompletedTests(token, ["timeout" ], (tests) => {
resultUi.state.lastCompletedTests = tests;
callback();
});
},
refreshMalfunctioningTests(callback = () => {}) {
WaveService.readMalfunctioningTests(token, (tests) => {
resultUi.state.malfunctioningTests = tests;
callback();
});
},
handleSessionEvent(message) {
resultUi.refreshData(message.type);
},
openResultsOverview() {
location.href = WEB_ROOT + "overview.html" ;
},
stopSession() {
WaveService.stopSession(token, resultUi.refreshData);
},
deleteSession() {
WaveService.deleteSession(token, () =>
resultUi.openResultsOverview()
);
},
showDeleteModal() {
const modal = UI.getElement("delete-modal" );
const className = modal.getAttribute("class" );
modal.setAttribute("class" , className + " is-active" );
},
hideDeleteModal() {
const modal = UI.getElement("delete-modal" );
let className = modal.getAttribute("class" );
className = className.replace(" is-active" , "" );
modal.setAttribute("class" , className);
},
downloadApiResultJson(api) {
const { results } = resultUi.state;
WaveService.downloadApiResult(token, api);
},
openHtmlReport(api) {
const { results } = resultUi.state;
if (results[api].complete != results[api].total) return;
WaveService.readReportUri(token, api, function (uri) {
window.open(uri, "_blank" );
});
},
downloadFinishedApiJsons() {
WaveService.downloadAllApiResults(token);
},
downloadHtmlZip() {
WaveService.downloadResultsOverview(token);
},
downloadResults() {
if (resultUi.state.status.status !== "completed" ) return;
WaveService.downloadResults(token);
},
addMalfunctioningTest(testPath) {
const { malfunctioningTests } = resultUi.state;
if (malfunctioningTests.indexOf(testPath) !== -1) return;
malfunctioningTests.push(testPath);
WaveService.updateMalfunctioningTests(
token,
malfunctioningTests,
() => {
resultUi.renderMalfunctioningTests();
}
);
resultUi.renderLastCompletedTests();
},
removeMalfunctioningTest(testPath) {
const { malfunctioningTests } = resultUi.state;
malfunctioningTests.splice(malfunctioningTests.indexOf(testPath), 1);
WaveService.updateMalfunctioningTests(
token,
malfunctioningTests,
() => {
resultUi.renderMalfunctioningTests();
}
);
resultUi.renderLastCompletedTests();
},
isTestOnMalfunctioningList(test) {
const { malfunctioningTests } = resultUi.state;
return malfunctioningTests.indexOf(test) !== -1;
},
showExcluded() {
resultUi.state.showExcluded = true;
resultUi.renderSessionDetails();
},
hideExcluded() {
resultUi.state.showExcluded = false;
resultUi.renderSessionDetails();
},
addLabel() {
const label = UI.getElement("session-label-input" ).value;
if (!label ) return;
const { configuration } = resultUi.state;
configuration.labels.push(label );
WaveService.updateLabels(token, configuration.labels);
resultUi.renderSessionDetails();
UI.getElement("session-label-input" ).focus();
},
removeLabel(index) {
const { configuration } = resultUi.state;
configuration.labels.splice(index, 1);
WaveService.updateLabels(token, configuration.labels);
resultUi.renderSessionDetails();
},
showAddLabel() {
resultUi.state.addLabelVisible = true;
resultUi.renderSessionDetails();
UI.getElement("session-label-input" ).focus();
},
hideAddLabel() {
resultUi.state.addLabelVisible = false;
resultUi.renderSessionDetails();
},
render() {
const resultView = UI.createElement({
className: "section" ,
children: [
{
className: "container" ,
style : "margin-bottom: 2em" ,
children: [
{
className: "columns" ,
children: [
{
className: "column" ,
children: [
{
element: "img" ,
src: "res/wavelogo_2016.jpg" ,
className: "site-logo" ,
},
],
},
{
className: "column is-narrow" ,
children: {
className: "button is-dark is-outlined" ,
onclick: resultUi.openResultsOverview,
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className: "fas fa-arrow-left" ,
},
],
},
{
text: "Results Overview" ,
element: "span" ,
},
],
},
},
],
},
{
className: "container" ,
children: {
className: "columns" ,
children: [
{
className: "column" ,
children: { className: "title" , text: "Result" },
},
{
className: "column is-narrow" ,
children: { id: "controls" },
},
],
},
},
],
},
{
id: "session-details" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
{
id: "last-completed-tests" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
{
id: "api-results" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
{
id: "timeout-files" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
{
id: "export" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
{
id: "malfunctioning-tests" ,
className: "container" ,
style : "margin-bottom: 2em" ,
},
],
});
const root = UI.getRoot();
root.innerHTML = "" ;
root.appendChild(resultView);
resultUi.renderControls();
resultUi.renderSessionDetails();
resultUi.renderApiResults();
resultUi.renderExportView();
},
renderControls() {
const { state } = resultUi;
if (!state.status) return;
const { status } = state.status;
const { isPublic } = state.configuration;
const controlsView = UI.createElement({
className: "field is-grouped is-grouped-multiline" ,
});
if (
status &&
status !== "aborted" &&
status !== "completed" &&
status !== "pending"
) {
const pauseResumeButton = UI.createElement({
id: "pause-resume-button" ,
className: "control button is-dark is-outlined" ,
onclick: function () {
if (status === "running" ) {
WaveService.pauseSession(token, resultUi.refreshData);
} else {
WaveService.startSession(token, resultUi.refreshData);
}
},
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className:
status === "running" ? "fas fa-pause" : "fas fa-play" ,
},
],
},
{
text: status === "running" ? "Pause" : "Resume" ,
element: "span" ,
},
],
});
controlsView.appendChild(pauseResumeButton);
}
if (status && status !== "aborted" && status !== "completed" ) {
const stopButton = UI.createElement({
id: "stop-button" ,
className: "control button is-dark is-outlined" ,
onclick: resultUi.stopSession,
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className: "fas fa-square" ,
},
],
},
{
text: "Stop" ,
element: "span" ,
},
],
});
controlsView.appendChild(stopButton);
}
if (!isPublic) {
const deleteButton = UI.createElement({
id: "delete-button" ,
className: "control button is-dark is-outlined" ,
onclick: resultUi.showDeleteModal,
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className: "fas fa-trash-alt" ,
},
],
},
{
text: "Delete" ,
element: "span" ,
},
],
});
controlsView.appendChild(deleteButton);
}
const deleteModal = UI.createElement({
id: "delete-modal" ,
className: "modal" ,
children: [
{
className: "modal-background" ,
onclick: resultUi.hideDeleteModal,
},
{
className: "modal-card" ,
children: [
{
className: "modal-card-head" ,
children: [
{
element: "p" ,
className: "modal-card-title" ,
text: "Delete Session" ,
},
],
},
{
className: "modal-card-body" ,
children: [
{
element: "p" ,
text: "Are you sure you want to delete this session?" ,
},
{ element: "p" , text: "This action cannot be undone." },
],
},
{
className: "modal-card-foot" ,
children: [
{
className: "button is-danger" ,
text: "Delete Session" ,
onclick: resultUi.deleteSession,
},
{
className: "button" ,
text: "Cancel" ,
onclick: resultUi.hideDeleteModal,
},
],
},
],
},
],
});
controlsView.appendChild(deleteModal);
const controls = UI.getElement("controls" );
controls.innerHTML = "" ;
controls.appendChild(controlsView);
},
renderSessionDetails() {
const { state } = resultUi;
const { configuration, status, results } = state;
if (!configuration || !status) return;
const sessionDetailsView = UI.createElement({
style : "margin-bottom: 20px" ,
});
const heading = UI.createElement({
text: "Session details" ,
className: "title is-4" ,
});
sessionDetailsView.appendChild(heading);
const getTagStyle = (status) => {
switch (status) {
case "completed" :
return "is-success" ;
case "running" :
return "is-info" ;
case "aborted" :
return "is-danger" ;
case "paused" :
return "is-warning" ;
case "pending" :
return "is-primary" ;
}
};
if (status.dateFinished) {
if (state.durationInterval) clearInterval(state.durationInterval);
} else if (status.dateStarted) {
if (!state.durationInterval)
state.durationInterval = setInterval(() => {
UI.getElement("duration" ).innerHTML = utils.millisToTimeString(
Date.now() - status.dateStarted.getTime()
);
}, 1000);
}
const { addLabelVisible } = state;
const { showExcluded } = state;
const tokenField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Token" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
text: configuration.token,
},
},
},
],
});
sessionDetailsView.appendChild(tokenField);
const userAgentField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "User Agent" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
text: configuration.userAgent || "" ,
},
},
},
],
});
sessionDetailsView.appendChild(userAgentField);
const testPathsField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Test Paths" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
text: configuration.tests.include
.reduce((text, test) => text + test + ", " , "" )
.slice(0, -2),
},
},
},
],
});
sessionDetailsView.appendChild(testPathsField);
const excludedTestsField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Excluded Test Paths" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
children: [
{
element: "span" ,
text: configuration.tests.exclude.length,
},
{
element: "span" ,
className: "button is-small is-rounded" ,
style : "margin-left: 10px" ,
text: showExcluded ? "hide" : "show" ,
onClick: showExcluded
? resultUi.hideExcluded
: resultUi.showExcluded,
},
showExcluded
? {
style :
"max-height: 250px; overflow: auto; margin-bottom: 10px" ,
children: configuration.tests.exclude.map (
(test) => ({
text: test,
})
),
}
: null,
],
},
},
},
],
});
sessionDetailsView.appendChild(excludedTestsField);
const referenceSessionField = UI.createElement({
style : "display: none" ,
id: "reference-session-field" ,
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Reference Sessions" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
children: { id: "reference-sessions" },
},
},
},
],
});
sessionDetailsView.appendChild(referenceSessionField);
const totalTestFilesField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Total Test Files" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: "control" ,
text: Object .keys(results).reduce(
(sum, api) => (sum += results[api].total),
0
),
},
},
},
],
});
sessionDetailsView.appendChild(totalTestFilesField);
const statusField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Status" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: `control tag ${getTagStyle(status.status)}`,
text: status.status,
},
},
},
],
});
sessionDetailsView.appendChild(statusField);
const timeoutsField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Test Timeouts" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: `control`,
text: Object .keys(configuration.timeouts).reduce(
(text, timeout) =>
`${text}${timeout}: ${
configuration.timeouts[timeout] / 1000
}s\n`,
""
),
},
},
},
],
});
sessionDetailsView.appendChild(timeoutsField);
if (status.dateStarted) {
const startedField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Date Started" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: `control`,
text: new Date(status.dateStarted).toLocaleString(),
},
},
},
],
});
sessionDetailsView.appendChild(startedField);
}
if (status.dateFinished) {
const finishedField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Date Finished" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: `control`,
text: new Date(status.dateFinished).toLocaleString(),
},
},
},
],
});
sessionDetailsView.appendChild(finishedField);
}
if (status.dateStarted) {
const durationField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Duration" },
},
{
className: "field-body" ,
children: {
className: "field" ,
children: {
className: `control`,
id: "duration" ,
text: utils.millisToTimeString(
status.dateFinished
? status.dateFinished.getTime() -
status.dateStarted.getTime()
: Date.now() - status.dateStarted.getTime()
),
},
},
},
],
});
sessionDetailsView.appendChild(durationField);
}
const labelsField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Labels" },
},
{
className: "field-body" ,
children: {
className: "field is-grouped is-grouped-multiline" ,
children: configuration.labels
.map ((label , index) => ({
className: "control" ,
children: {
className: "tags has-addons" ,
children: [
{
element: "span" ,
className: "tag is-info" ,
text: label ,
},
{
element: "a" ,
className: "tag is-delete" ,
onClick: () => resultUi.removeLabel(index),
},
],
},
}))
.concat(
resultUi.state.configuration.isPublic
? []
: addLabelVisible
? [
{
className: "control field is-grouped" ,
children: [
{
element: "input" ,
className: "input is-small control" ,
style : "width: 10rem" ,
id: "session-label-input" ,
type: "text" ,
onKeyUp: (event) =>
event.keyCode === 13
? resultUi.addLabel()
: null,
},
{
className:
"button is-dark is-outlined is-small is-rounded control" ,
text: "save" ,
onClick: resultUi.addLabel,
},
{
className:
"button is-dark is-outlined is-small is-rounded control" ,
text: "cancel" ,
onClick: resultUi.hideAddLabel,
},
],
},
]
: [
{
className: "button is-rounded is-small" ,
text: "Add" ,
onClick: resultUi.showAddLabel,
},
]
),
},
},
],
});
sessionDetailsView.appendChild(labelsField);
const sessionDetails = UI.getElement("session-details" );
sessionDetails.innerHTML = "" ;
sessionDetails.appendChild(sessionDetailsView);
resultUi.renderReferenceSessions();
},
renderReferenceSessions() {
const { referenceSessions } = resultUi.state;
if (!referenceSessions || referenceSessions.length === 0) return;
const referenceSessionsList = UI.createElement({
className: "field is-grouped is-grouped-multiline" ,
});
const getBrowserIcon = (browser) => {
switch (browser.toLowerCase()) {
case "firefox" :
return "fab fa-firefox" ;
case "edge" :
return "fab fa-edge" ;
case "chrome" :
case "chromium" :
return "fab fa-chrome" ;
case "safari" :
case "webkit" :
return "fab fa-safari" ;
}
};
referenceSessions.forEach((session) => {
const { token, browser } = session;
const referenceSessionItem = UI.createElement({
className:
"control button is-dark is-small is-rounded is-outlined" ,
onClick: () => WaveService.openSession(token),
children: [
{
element: "span" ,
className: "icon" ,
children: {
element: "i" ,
className: getBrowserIcon(browser.name),
},
},
{
element: "span" ,
text: token.split("-" ).shift(),
},
],
});
referenceSessionsList.appendChild(referenceSessionItem);
});
const referenceSessionsTarget = UI.getElement("reference-sessions" );
referenceSessionsTarget.innerHTML = "" ;
referenceSessionsTarget.appendChild(referenceSessionsList);
const field = UI.getElement("reference-session-field" );
field.style ["display" ] = "flex" ;
},
renderLastCompletedTests() {
if (resultUi.state.configuration.isPublic) return;
const lastCompletedTestsView = UI.createElement({});
const heading = UI.createElement({
className: "title is-4" ,
children: [
{ element: "span" , text: "Last Timed-Out Test Files" },
{
element: "span" ,
className: "title is-7" ,
text: " (most recent first)" ,
},
],
});
lastCompletedTestsView.appendChild(heading);
const { lastCompletedTests } = resultUi.state;
const testsTable = UI.createElement({
element: "table" ,
className: "table" ,
style : "min-width: 100%" ,
children: [
{
element: "thead" ,
children: [
{
element: "tr" ,
children: [
{ element: "td" , text: "Test File" },
{ element: "td" , text: "Malfunctioning List" },
],
},
],
},
{
element: "tbody" ,
children: lastCompletedTests.map (({ path, status }) => ({
element: "tr" ,
children: [
{ element: "td" , text: path },
{
element: "td" ,
children: [
{
element: "button" ,
className: "button is-dark is-outlined is-small" ,
onClick: () => resultUi.addMalfunctioningTest(path),
title : "Add to malfunctioning tests list." ,
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className: resultUi.isTestOnMalfunctioningList(
path
)
? "fas fa-check"
: "fas fa-plus" ,
},
],
},
],
},
],
},
],
})),
},
],
});
if (lastCompletedTests.length > 0) {
lastCompletedTestsView.appendChild(
UI.createElement({
className: "container" ,
style : "overflow-x: auto;" ,
id: "last-completed-overflow" ,
children: testsTable,
})
);
} else {
const noTestsLabel = UI.createElement({
text: "- No Timed-Out Tests -" ,
style : "text-align: center" ,
});
lastCompletedTestsView.appendChild(noTestsLabel);
}
UI.saveScrollPosition("last-completed-overflow" );
const lastCompletedTestsElement = UI.getElement(
"last-completed-tests"
);
lastCompletedTestsElement.innerHTML = "" ;
lastCompletedTestsElement.appendChild(lastCompletedTestsView);
UI.loadScrollPosition("last-completed-overflow" );
},
renderApiResults() {
const { results, status } = resultUi.state;
const apiResultsView = UI.createElement({
style : "margin-bottom: 20px" ,
});
const heading = UI.createElement({
text: "API Results" ,
className: "title is-4" ,
});
apiResultsView.appendChild(heading);
if (!results) {
const loadingIndicator = UI.createElement({
className: "level" ,
children: {
element: "span" ,
className: "level-item" ,
children: [
{
element: "i" ,
className: "fas fa-spinner fa-pulse" ,
},
{
style : "margin-left: 0.4em;" ,
text: "Loading results ..." ,
},
],
},
});
apiResultsView.appendChild(loadingIndicator);
const apiResults = UI.getElement("api-results" );
apiResults.innerHTML = "" ;
apiResults.appendChild(apiResultsView);
return;
}
const width = status.status === "running" ? "7.5em" : "auto" ;
const header = UI.createElement({
element: "thead" ,
children: [
{
element: "tr" ,
children: [
{ element: "th" , text: "API" },
{ element: "th" , text: "Pass" , style : `min-width: ${width}` },
{ element: "th" , text: "Fail" , style : `min-width: ${width}` },
{
element: "th" ,
text: "Timeout" ,
style : `min-width: ${width}`,
},
{
element: "th" ,
text: "Not Run" ,
style : `min-width: ${width}`,
},
{
element: "th" ,
text: "Test Files Run" ,
style : `min-width: ${width}`,
},
{ element: "th" , text: "Export" },
],
},
],
});
const apis = Object .keys(results).sort((apiA, apiB) =>
apiA.toLowerCase() > apiB.toLowerCase() ? 1 : -1
);
const rows = apis.map ((api) => {
const {
complete = 0,
pass = 0,
fail = 0,
timeout = 0,
timeoutfiles = [],
not_run: notRun = 0,
total,
} = results[api];
isDone = results[api].complete == results[api].total;
const totalTestResults = pass + fail + timeout + notRun;
return UI.createElement({
element: "tr" ,
style : "white-space: nowrap" ,
children: [
{ element: "td" , text: api },
{
element: "td" ,
children: {
style : `color: hsl(141, 71%, 38%); overflow: visible; white-space: nowrap; width: ${width}`,
text: `${pass} (${utils.percent(pass, totalTestResults)}%)`,
},
},
{
element: "td" ,
children: {
className: "has-text-danger" ,
style : `overflow: visible; white-space: nowrap; width: ${width}`,
text: `${fail} (${utils.percent(fail, totalTestResults)}%)`,
},
},
{
element: "td" ,
children: {
style : `color: hsl(48, 100%, 40%); overflow: visible; white-space: nowrap; width: ${width}`,
text: `${timeout} (${utils.percent(
timeout,
totalTestResults
)}%)`,
},
},
{
element: "td" ,
children: {
className: "has-text-info" ,
style : `overflow: visible; white-space: nowrap; width: ${width}`,
text: `${notRun} (${utils.percent(
notRun,
totalTestResults
)}%)`,
},
},
{
element: "td" ,
children: {
style : `overflow: visible; white-space: nowrap; width: ${width}`,
text: `${complete}/${total} (${utils.percent(
complete,
total
)}%)`,
},
},
{
element: "td" ,
children: {
className: "field has-addons" ,
children: [
{
className: "control" ,
children: {
className: "button is-dark is-outlined is-small" ,
onclick: () => resultUi.downloadApiResultJson(api),
text: "json" ,
title : `Download results of ${api} API as JSON file.`,
},
},
resultUi.state.reportsEnabled
? {
className: "control" ,
children: {
className: "button is-dark is-outlined is-small" ,
disabled: !isDone,
onclick: () => resultUi.openHtmlReport(api),
text: "report" ,
title : `Show results of ${api} API in WPT Report format.`,
},
}
: null,
],
},
},
],
});
});
const { pass, fail, timeout, not_run, complete, total } = apis.reduce(
(sum, api) => {
Object .keys(sum).forEach(
(key) => (sum[key] += results[api][key] ? results[api][key] : 0)
);
return sum;
},
{ complete: 0, total: 0, pass: 0, fail: 0, timeout: 0, not_run: 0 }
);
const totalTestResults = pass + fail + timeout + not_run;
const footer = UI.createElement({
element: "tfoot" ,
children: [
{
element: "tr" ,
children: [
{ element: "th" , text: "Total" },
{
element: "th" ,
children: {
style : `color: hsl(141, 71%, 38%); overflow: visible; white-space: nowrap; width: ${width}`,
text: `${pass} (${utils.percent(
pass,
totalTestResults
)}%)`,
},
},
{
element: "th" ,
children: {
style : `overflow: visible; white-space: nowrap; width: ${width}`,
className: "has-text-danger" ,
text: `${fail} (${utils.percent(
fail,
totalTestResults
)}%)`,
},
},
{
element: "th" ,
children: {
style : `color: hsl(48, 100%, 40%); overflow: visible; white-space: nowrap; width: ${width}`,
text: `${timeout} (${utils.percent(
timeout,
totalTestResults
)}%)`,
},
},
{
element: "th" ,
children: {
style : `overflow: visible; white-space: nowrap; width: ${width}`,
className: "has-text-info" ,
text: `${not_run} (${utils.percent(
not_run,
totalTestResults
)}%)`,
},
},
{
element: "th" ,
children: {
style : `overflow: visible; white-space: nowrap; width: ${width}`,
text: `${complete}/${total} (${utils.percent(
complete,
total
)}%)`,
},
},
{ element: "th" },
],
},
],
});
const resultsTable = UI.createElement({
className: "container" ,
style : "overflow-x: auto" ,
id: "results-overflow" ,
children: {
element: "table" ,
className: "table" ,
id: "results-table" ,
style :
"width: 100%; min-width: 30em; border-radius: 3px; border: 2px solid hsl(0, 0%, 86%);" ,
children: [header , { element: "tbody" , children: rows }, footer ],
},
});
apiResultsView.appendChild(resultsTable);
UI.saveScrollPosition("results-overflow" );
const apiResults = UI.getElement("api-results" );
apiResults.innerHTML = "" ;
apiResults.appendChild(apiResultsView);
UI.loadScrollPosition("results-overflow" );
},
renderExportView() {
const { status } = resultUi.state;
if (!status) return;
const exportElement = UI.getElement("export" );
exportElement.innerHTML = "" ;
const heading = UI.createElement({
className: "title is-4" ,
text: "Export" ,
});
exportElement.appendChild(heading);
const resultsField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: { className: "label" , text: "Results" },
},
{
className: "field-body" ,
children: {
className: "control columns" ,
style : "width: 100%" ,
children: [
{
className: "column is-9" ,
text:
"Download results for import into other WMAS Test Suite instances." ,
},
{
className: "column is-3" ,
children: {
className:
"button is-dark is-outlined is-small is-fullwidth" ,
onClick: resultUi.downloadResults,
disabled: status.status !== "completed" ,
children: [
{
element: "span" ,
className: "icon" ,
children: {
element: "i" ,
className: "fas fa-file-archive" ,
},
},
{ element: "span" , text: "Download Zip" },
],
},
},
],
},
},
],
});
exportElement.appendChild(resultsField);
const jsonField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: {
className: "label" ,
text: "All JSON Files" ,
},
},
{
className: "field-body" ,
children: {
className: "control columns" ,
style : "width: 100%" ,
children: [
{
className: "column is-9" ,
text:
"Download JSON files containing results of completed test files." ,
},
{
className: "column is-3" ,
children: {
className:
"button is-dark is-outlined is-small is-fullwidth" ,
onclick: resultUi.downloadFinishedApiJsons,
children: [
{
element: "span" ,
className: "icon" ,
children: {
element: "i" ,
className: "fas fa-file-archive" ,
},
},
{ element: "span" , text: "Download Zip" },
],
},
},
],
},
},
],
});
exportElement.appendChild(jsonField);
const htmlField = UI.createElement({
className: "field is-horizontal" ,
children: [
{
className: "field-label" ,
children: {
className: "label" ,
text: "Session result HTML" ,
},
},
{
className: "field-body" ,
children: {
className: "control columns" ,
style : "width: 100%" ,
children: [
{
className: "column is-9" ,
text:
"Download this sessions result as standalone HTML page, similar to this page." ,
},
{
className: "column is-3" ,
children: {
className:
"button is-dark is-outlined is-small is-fullwidth" ,
onClick: resultUi.downloadHtmlZip,
children: [
{
element: "span" ,
className: "icon" ,
children: {
element: "i" ,
className: "fas fa-code" ,
},
},
{ element: "span" , text: "Download HTML" },
],
},
},
],
},
},
],
});
exportElement.appendChild(htmlField);
},
renderMalfunctioningTests() {
const malfunctioningTestsView = UI.createElement({});
const heading = UI.createElement({
className: "title is-4" ,
text: "Malfunctioning Tests" ,
});
malfunctioningTestsView.appendChild(heading);
const { malfunctioningTests } = resultUi.state;
const testsTable = UI.createElement({
element: "table" ,
className: "table" ,
style : "min-width: 100%" ,
children: [
{
element: "thead" ,
children: [
{
element: "tr" ,
children: [
{ element: "td" , text: "Test File" },
{ element: "td" , text: "" },
],
},
],
},
{
element: "tbody" ,
children: malfunctioningTests.map ((path) => ({
element: "tr" ,
children: [
{ element: "td" , text: path },
{
element: "td" ,
children: resultUi.state.configuration.isPublic
? null
: {
element: "button" ,
className: "button is-dark is-outlined is-small" ,
onClick: () =>
resultUi.removeMalfunctioningTest(path),
title : "Remove from malfunctioning tests list." ,
children: [
{
element: "span" ,
className: "icon" ,
children: [
{
element: "i" ,
className: "fas fa-trash-alt" ,
},
],
},
],
},
},
],
})),
},
],
});
if (malfunctioningTests.length > 0) {
malfunctioningTestsView.appendChild(
UI.createElement({
className: "container" ,
style : "overflow-x: auto" ,
id: "malfunctioning-overflow" ,
children: testsTable,
})
);
} else {
const noTestsLabel = UI.createElement({
text: "- No Tests Available -" ,
style : "text-align: center" ,
});
malfunctioningTestsView.appendChild(noTestsLabel);
}
UI.saveScrollPosition("malfunctioning-overflow" );
const malfunctioningTestsElement = UI.getElement(
"malfunctioning-tests"
);
malfunctioningTestsElement.innerHTML = "" ;
malfunctioningTestsElement.appendChild(malfunctioningTestsView);
UI.loadScrollPosition("malfunctioning-overflow" );
},
};
</script >
</body >
</html >
Messung V0.5 C=97 H=97 G=96
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland