diff --git a/src/server/report/app.js b/src/server/report/app.js
index 41e803d7..406430ec 100644
--- a/src/server/report/app.js
+++ b/src/server/report/app.js
@@ -1,6 +1,11 @@
-import './test.js';
+import './button.js';
import { css, html, LitElement, nothing } from 'lit';
import { FILTER_STATUS, FULL_MODE, LAYOUTS } from './common.js';
+import { ICON_BROWSERS, ICON_HOME } from './icons.js';
+import { RADIO_STYLE, renderRadio } from './radio.js';
+import { renderResult, RESULT_STYLE } from './result.js';
+import { renderTabButtons, renderTabPanel, TAB_STATUS_TYPE, TAB_STYLE } from './tabs.js';
+import { classMap } from 'lit/directives/class-map.js';
import data from './data.js';
import page from 'page';
@@ -11,9 +16,10 @@ class App extends LitElement {
_filterTest: { state: true },
_fullMode: { state: true },
_layout: { state: true },
- _overlay: { state: true }
+ _overlay: { state: true },
+ _selectedBrowserIndex: { state: true }
};
- static styles = [css`
+ static styles = [RADIO_STYLE, RESULT_STYLE, TAB_STYLE, css`
.container {
display: grid;
grid-auto-flow: row;
@@ -72,6 +78,88 @@ class App extends LitElement {
.padding {
padding: 20px;
}
+ .test-results {
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+ grid-template-areas:
+ 'header'
+ 'content'
+ 'footer';
+ height: 100vh;
+ }
+ .header {
+ border-bottom: 1px solid #cdd5dc;
+ grid-area: header;
+ }
+ .tab-panels {
+ grid-area: content;
+ overflow: auto;
+ }
+ .footer {
+ align-items: center;
+ border-top: 1px solid #cdd5dc;
+ display: flex;
+ gap: 10px;
+ grid-area: footer;
+ padding: 20px;
+ }
+ .footer > svg {
+ flex: 0 0 auto;
+ height: 50px;
+ width: 50px;
+ }
+ .footer-info {
+ flex: 1 0 auto;
+ }
+ .footer-browser-name {
+ font-size: 1.2rem;
+ font-weight: bold;
+ }
+ .footer-timing {
+ flex: 0 0 auto;
+ font-size: 2rem;
+ font-weight: bold;
+ }
+ .header, .footer {
+ background-color: #f0f0f0;
+ box-shadow: 0 0 6px rgba(0,0,0,.07);
+ }
+ .title {
+ display: flex;
+ padding: 20px 20px 0 20px;
+ }
+ .title h2 {
+ margin: 0;
+ }
+ .title-info {
+ flex: 1 0 auto;
+ }
+ .title-navigation {
+ flex: 0 0 auto;
+ }
+ .settings {
+ align-items: center;
+ display: flex;
+ padding: 20px;
+ gap: 20px;
+ }
+ .settings-box {
+ background-color: #ffffff;
+ border: 1px solid #cdd5dc;
+ border-radius: 5px;
+ line-height: 24px;
+ padding: 10px;
+ user-select: none;
+ }
+ .pass {
+ color: #46a661;
+ }
+ .error {
+ color: #cd2026;
+ }
+ .warning {
+ color: #e87511;
+ }
`];
constructor() {
super();
@@ -80,6 +168,7 @@ class App extends LitElement {
this._fullMode = FULL_MODE.GOLDEN.value;
this._layout = LAYOUTS.SPLIT.value;
this._overlay = true;
+ this._selectedBrowserIndex = -1;
}
connectedCallback() {
super.connectedCallback();
@@ -121,17 +210,7 @@ class App extends LitElement {
view = html`
Test not found: ${this._filterTest}.
`;
} else {
hasPadding = false;
- view = html`
-
- `;
+ view = this._renderTestResults(fileData, testData);
}
}
} else {
@@ -156,6 +235,9 @@ class App extends LitElement {
`;
}
+ _handleBackClick() {
+ this._updateSearchParams({ file: undefined, test: undefined });
+ }
_handleFilterBrowserChange(e) {
const browsers = data.browsers.map(b => b.name).filter(b => {
if (b === e.target.value) {
@@ -169,15 +251,8 @@ class App extends LitElement {
_handleFilterStatusChange(e) {
this._updateSearchParams({ status: e.target.value });
}
- _handleNavigation(e) {
- switch (e.detail.location) {
- case 'home':
- this._updateSearchParams({ file: undefined, test: undefined });
- break;
- }
- }
- _handleSettingChange(e) {
- this[`_${e.detail.name}`] = e.detail.value;
+ _handleOverlayChange(e) {
+ this._overlay = e.target.checked;
}
_handleTestClick(e) {
this._updateSearchParams({ file: e.target.dataset.file, test: e.target.dataset.test });
@@ -245,6 +320,41 @@ class App extends LitElement {
${browserFilter}
`;
+ }
+ _renderFooter(selectedBrowser, selectedResult) {
+ const duration = selectedResult.duration;
+ const durationClass = {
+ 'error': duration >= 1000,
+ 'footer-timing': true,
+ 'pass': duration < 500,
+ 'warning': duration >= 500 && duration < 1000
+ };
+ return html`
+
+ `;
+ }
+ _renderTabButtons(tabs) {
+ if (tabs.length < 2) return nothing;
+ return renderTabButtons('browser results', tabs, index => this._selectedBrowserIndex = index);
+ }
+ _renderTabPanels(tabs) {
+
+ let panelsContent;
+ if (tabs.length < 2) {
+ panelsContent = tabs.map(t => t.content);
+ } else {
+ panelsContent = tabs.map(t => renderTabPanel(t));
+ }
+
+ return html`${panelsContent}
`;
+
}
_renderTestResultRow(file, test) {
const results = data.browsers.map(b => {
@@ -264,6 +374,61 @@ class App extends LitElement {
`;
}
+ _renderTestResults(fileData, testData) {
+
+ let fullMode = nothing;
+ if (this._layout === LAYOUTS.FULL.value) {
+ fullMode = renderRadio(
+ 'fullMode',
+ this._fullMode,
+ (val) => this._fullMode = val,
+ [FULL_MODE.GOLDEN, FULL_MODE.NEW]
+ );
+ }
+
+ const browsers = data.browsers.filter(b => this._filterBrowsers.includes(b.name));
+ const selectedBrowser = browsers[this._selectedBrowserIndex] ||
+ browsers.find(b => testData.results.find(r => r.name === b.name && !r.passed)) ||
+ browsers[0];
+ const selectedResult = testData.results.find(r => r.name === selectedBrowser.name);
+
+ const tabs = browsers.map((b) => {
+ const result = testData.results.find(r => r.name === b.name);
+ return {
+ content: html`${renderResult(result, { fullMode: this._fullMode, layout: this._layout, showOverlay: this._overlay })}
`,
+ label: b.name,
+ id: b.name.toLowerCase(),
+ selected: b.name === selectedBrowser.name,
+ status: result.passed ? 'passed' : 'failed',
+ statusType: result.passed ? TAB_STATUS_TYPE.NORMAL : TAB_STATUS_TYPE.ERROR
+ };
+ });
+
+ return html`
+
+
+ ${this._renderTabPanels(tabs)}
+ ${this._renderFooter(selectedBrowser, selectedResult)}
+
+ `;
+
+ }
_updateFiles() {
const files = [];
diff --git a/src/server/report/test.js b/src/server/report/test.js
deleted file mode 100644
index be7139ed..00000000
--- a/src/server/report/test.js
+++ /dev/null
@@ -1,248 +0,0 @@
-import './button.js';
-import { css, html, LitElement, nothing } from 'lit';
-import { FULL_MODE, LAYOUTS } from './common.js';
-import { ICON_BROWSERS, ICON_HOME } from './icons.js';
-import { RADIO_STYLE, renderRadio } from './radio.js';
-import { renderResult, RESULT_STYLE } from './result.js';
-import { renderTabButtons, renderTabPanel, TAB_STATUS_TYPE, TAB_STYLE } from './tabs.js';
-import { classMap } from 'lit/directives/class-map.js';
-import data from './data.js';
-
-class Test extends LitElement {
- static properties = {
- browsers: { type: String },
- file: { type: String },
- fullMode: { attribute: 'full-mode', type: String },
- layout: { type: String },
- showOverlay: { attribute: 'show-overlay', type: Boolean },
- test: { type: String },
- _selectedBrowserIndex: { state: true }
- };
- static styles = [RADIO_STYLE, RESULT_STYLE, TAB_STYLE, css`
- :host {
- display: grid;
- grid-template-rows: auto 1fr auto;
- grid-template-areas:
- 'header'
- 'content'
- 'footer';
- height: 100vh;
- }
- .header {
- border-bottom: 1px solid #cdd5dc;
- grid-area: header;
- }
- .tab-panels {
- grid-area: content;
- overflow: auto;
- }
- .footer {
- align-items: center;
- border-top: 1px solid #cdd5dc;
- display: flex;
- gap: 10px;
- grid-area: footer;
- padding: 20px;
- }
- .footer > svg {
- flex: 0 0 auto;
- height: 50px;
- width: 50px;
- }
- .footer-info {
- flex: 1 0 auto;
- }
- .footer-browser-name {
- font-size: 1.2rem;
- font-weight: bold;
- }
- .footer-timing {
- flex: 0 0 auto;
- font-size: 2rem;
- font-weight: bold;
- }
- .header, .footer {
- background-color: #f0f0f0;
- box-shadow: 0 0 6px rgba(0,0,0,.07);
- }
- .title {
- display: flex;
- padding: 20px 20px 0 20px;
- }
- .title h2 {
- margin: 0;
- }
- .title-info {
- flex: 1 0 auto;
- }
- .title-navigation {
- flex: 0 0 auto;
- }
- .settings {
- align-items: center;
- display: flex;
- padding: 20px;
- gap: 20px;
- }
- .settings-box {
- background-color: #ffffff;
- border: 1px solid #cdd5dc;
- border-radius: 5px;
- line-height: 24px;
- padding: 10px;
- user-select: none;
- }
- .pass {
- color: #46a661;
- }
- .error {
- color: #cd2026;
- }
- .warning {
- color: #e87511;
- }
- `];
- constructor() {
- super();
- this.browsers = [];
- this._selectedBrowserIndex = -1;
- }
- render() {
-
- const { browsers, fileData, testData } = this._fetchData();
- if (!fileData || !testData) return nothing;
-
- let fullMode = nothing;
- if (this.layout === LAYOUTS.FULL.value) {
- fullMode = renderRadio(
- 'fullMode',
- this.fullMode,
- (val) => this._triggerChange('fullMode', val),
- [FULL_MODE.GOLDEN, FULL_MODE.NEW]
- );
- }
-
- const selectedBrowser = this._getSelectedBrowser(browsers, testData);
- const selectedResult = testData.results.find(r => r.name === selectedBrowser.name);
-
- const tabs = browsers.map((b) => {
- const result = testData.results.find(r => r.name === b.name);
- return {
- content: html`${renderResult(result, { fullMode: this.fullMode, layout: this.layout, showOverlay: this.showOverlay })}
`,
- label: b.name,
- id: b.name.toLowerCase(),
- selected: b.name === selectedBrowser.name,
- status: result.passed ? 'passed' : 'failed',
- statusType: result.passed ? TAB_STATUS_TYPE.NORMAL : TAB_STATUS_TYPE.ERROR
- };
- });
-
- return html`
-
- ${this._renderTabPanels(tabs)}
- ${this._renderFooter(selectedBrowser, selectedResult)}
- `;
-
- }
- _fetchData() {
-
- const fileData = data.files.find(f => f.name === this.file);
- if (!fileData) return {};
-
- const testData = fileData.tests.find(t => t.name === this.test);
- if (!testData) return {};
-
- const filteredBrowsers = this.browsers.split(',');
- const browsers = data.browsers.filter(b => filteredBrowsers.includes(b.name));
-
- return { browsers, fileData, testData };
-
- }
- _getSelectedBrowser(browsers, { results }) {
- return browsers[this._selectedBrowserIndex] ||
- browsers.find(b => results.find(r => r.name === b.name && !r.passed)) ||
- browsers[0];
- }
- _handleBackClick() {
- this._triggerNavigation('home');
- }
- _handleOverlayChange(e) {
- this._triggerChange('overlay', e.target.checked);
- }
- _renderFooter(selectedBrowser, selectedResult) {
- const duration = selectedResult.duration;
- const durationClass = {
- 'error': duration >= 1000,
- 'footer-timing': true,
- 'pass': duration < 500,
- 'warning': duration >= 500 && duration < 1000
- };
- return html`
-
- `;
- }
- _renderTabButtons(tabs) {
- if (tabs.length < 2) return nothing;
- return renderTabButtons('browser results', tabs, index => this._selectedBrowserIndex = index);
- }
- _renderTabPanels(tabs) {
-
- let panelsContent;
- if (tabs.length < 2) {
- panelsContent = tabs.map(t => t.content);
- } else {
- panelsContent = tabs.map(t => renderTabPanel(t));
- }
-
- return html`${panelsContent}
`;
-
- }
- _triggerChange(name, value) {
- this.dispatchEvent(new CustomEvent(
- 'setting-change', {
- bubbles: false,
- composed: false,
- detail: {
- name: name,
- value: value
- }
- }
- ));
- }
- _triggerNavigation(location) {
- this.dispatchEvent(new CustomEvent(
- 'navigation', {
- bubbles: false,
- composed: false,
- detail: {
- location: location
- }
- }
- ));
- }
-}
-
-customElements.define('d2l-vdiff-report-test', Test);