Skip to content

Commit 1cfa658

Browse files
Fix proto skew error and minor nits.
- Update names of some variables. - Ignore unknown fields when marshalling from JSON (to avoid proto skew errors). - Add minor unit tests and flesh out existing coverage.
1 parent 36c5799 commit 1cfa658

9 files changed

+208
-37
lines changed

web/src/APIClient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export class APIClientImpl implements APIClient {
1515
const dashboards: Array<String> = [];
1616

1717
fetch(`${this.host}/api/v1/dashboards`).then(async response => {
18-
const resp = ListDashboardsResponse.fromJson(await response.json());
18+
const resp = ListDashboardsResponse.fromJson(await response.json(), {ignoreUnknownFields: true});
1919
resp.dashboards.forEach(db => {
2020
dashboards.push(db.name);
2121
});
@@ -28,7 +28,7 @@ export class APIClientImpl implements APIClient {
2828
const dashboardGroups: Array<String> = [];
2929

3030
fetch(`${this.host}/api/v1/dashboard-groups`).then(async response => {
31-
const resp = ListDashboardGroupsResponse.fromJson(await response.json());
31+
const resp = ListDashboardGroupsResponse.fromJson(await response.json(), {ignoreUnknownFields: true});
3232
resp.dashboardGroups.forEach(db => {
3333
dashboardGroups.push(db.name);
3434
});

web/src/testgrid-app.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LitElement, html } from 'lit';
1+
import { LitElement, html, css } from 'lit';
22
import { customElement } from 'lit/decorators.js';
33
import './testgrid-router';
44

@@ -8,6 +8,14 @@ import './testgrid-router';
88
*/
99
@customElement('testgrid-app')
1010
export class TestgridApp extends LitElement {
11+
static styles = css`
12+
:host {
13+
display: block;
14+
width: 100vw;
15+
height: 100vh;
16+
}
17+
`;
18+
1119
/**
1220
* Lit-element lifecycle method.
1321
* Invoked on each update to perform rendering tasks.

web/src/testgrid-dashboard-summary.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { LitElement, html } from 'lit';
33
import { customElement, property, state } from 'lit/decorators.js';
44
import { map } from 'lit/directives/map.js';
55
import { Timestamp } from './gen/google/protobuf/timestamp.js';
6-
import { FailuresSummary, ListTabSummariesResponse, TabSummary } from './gen/pb/api/v1/data.js';
6+
import { ListTabSummariesResponse, TabSummary } from './gen/pb/api/v1/data.js';
77
import './tab-summary.js';
88

99
export interface TabSummaryInfo {
@@ -161,7 +161,7 @@ export class TestgridDashboardSummary extends LitElement {
161161
if (!response.ok) {
162162
throw new Error(`HTTP error: ${response.status}`);
163163
}
164-
const data = ListTabSummariesResponse.fromJson(await response.json());
164+
const data = ListTabSummariesResponse.fromJson(await response.json(), {ignoreUnknownFields: true});
165165
const tabSummaries: Array<TabSummaryInfo> = [];
166166
data.tabSummaries.forEach(ts => {
167167
const si = convertResponse(ts);

web/src/testgrid-group-summary.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class TestgridGroupSummary extends LitElement {
7171
throw new Error(`HTTP error: ${response.status}`);
7272
}
7373
const data = ListDashboardSummariesResponse.fromJson(
74-
await response.json()
74+
await response.json(), {ignoreUnknownFields: true}
7575
);
7676
const summaries: RenderedDashboardSummary[] = [];
7777
data.dashboardSummaries.forEach(summary =>

web/src/testgrid-healthiness-summary.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import { map } from 'lit/directives/map.js';
55
import { TabSummaryInfo } from './testgrid-dashboard-summary';
66

77
@customElement('testgrid-healthiness-summary')
8-
export class TestgridTabTable extends LitElement {
9-
@state() showHealthinesSummary = false;
8+
export class TestgridHealthinessSummary extends LitElement {
9+
@state() showHealthinessSummary = false;
1010

1111
@property() info?: TabSummaryInfo;
1212

1313
render() {
1414
return html`
1515
<div class="dropdown-container">
1616
<button @click="${() => this.dropdownTable()}" class="btn">
17-
${this.showHealthinesSummary
17+
${this.showHealthinessSummary
1818
? html`- Hide Healthiness Report -`
1919
: html`- Show Healthiness Report -`}
2020
</button>
21-
${this.showHealthinesSummary
21+
${this.showHealthinessSummary
2222
? html` <table class="dropdown-menu">
2323
<tr>
2424
<th>Test Name</th>
@@ -57,7 +57,7 @@ export class TestgridTabTable extends LitElement {
5757
}
5858

5959
private dropdownTable() {
60-
this.showHealthinesSummary = !this.showHealthinesSummary;
60+
this.showHealthinessSummary = !this.showHealthinessSummary;
6161
}
6262

6363
static styles = css`

web/src/testgrid-index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class TestgridIndex extends LitElement {
113113
fetch(
114114
`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboards`
115115
).then(async response => {
116-
const resp = ListDashboardsResponse.fromJson(await response.json());
116+
const resp = ListDashboardsResponse.fromJson(await response.json(), {ignoreUnknownFields: true});
117117
const dashboards: string[] = [];
118118

119119
resp.dashboards.forEach(db => {
@@ -135,7 +135,7 @@ export class TestgridIndex extends LitElement {
135135
`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboard-groups`
136136
).then(async response => {
137137
const resp = ListDashboardGroupsResponse.fromJson(
138-
await response.json()
138+
await response.json(), {ignoreUnknownFields: true}
139139
);
140140
const dashboardGroups: string[] = [];
141141

@@ -157,7 +157,7 @@ export class TestgridIndex extends LitElement {
157157
fetch(
158158
`http://${process.env.API_HOST}:${process.env.API_PORT}/api/v1/dashboard-groups/${name}`
159159
).then(async response => {
160-
const resp = ListDashboardsResponse.fromJson(await response.json());
160+
const resp = ListDashboardsResponse.fromJson(await response.json(), {ignoreUnknownFields: true});
161161
const respectiveDashboards: string[] = [];
162162

163163
resp.dashboards.forEach(ts => {

web/src/testgrid-router.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LitElement, html } from 'lit';
1+
import { LitElement, html, css } from 'lit';
22
import { customElement } from 'lit/decorators.js';
33
import { Router } from '@lit-labs/router';
44
import './testgrid-data-content';
@@ -15,6 +15,14 @@ interface RouteParameter {
1515
*/
1616
@customElement('testgrid-router')
1717
export class TestgridRouter extends LitElement {
18+
static styles = css`
19+
:host {
20+
display: block;
21+
width: 100%;
22+
height: 100%;
23+
}
24+
`;
25+
1826
private router = new Router(this, [
1927
{
2028
path: '/:dashboard/*',

web/test/testgrid-dashboard-summary.test.ts

Lines changed: 123 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
} from '@open-wc/testing';
1010

1111
import { TestgridDashboardSummary } from '../src/testgrid-dashboard-summary.js';
12+
import { TestgridFailuresSummary } from '../src/testgrid-failures-summary.js';
13+
import { TabSummary } from '../src/tab-summary.js';
1214

1315
describe('Testgrid Dashboard Summary page', () => {
1416
let element: TestgridDashboardSummary;
@@ -17,29 +19,139 @@ describe('Testgrid Dashboard Summary page', () => {
1719
// See https://open-wc.org/docs/testing/helpers/#test-a-custom-class-with-properties
1820
const tagName = defineCE(class extends TestgridDashboardSummary {});
1921
const tag = unsafeStatic(tagName);
20-
element = await fixture(html`<${tag} .dashboardName=${'fake-dashboard-1'}></${tag}>`);
22+
element = await fixture(
23+
html`<${tag} .dashboardName=${'fake-dashboard-1'}></${tag}>`
24+
);
2125
});
2226

2327
// TODO - add accessibility tests
2428
it('renders the tab summaries', async () => {
25-
2629
// waiting until list items (dashboards and groups) are fully rendered
2730
await waitUntil(
2831
() => element.shadowRoot!.querySelector('tab-summary'),
2932
'Dashboard summary did not render tab summaries',
3033
{
3134
timeout: 4000,
32-
},
35+
}
3336
);
3437

3538
expect(element.tabSummariesInfo.length).to.equal(4);
36-
expect(element.tabSummariesInfo[0].name).to.equal("fake-tab-1");
37-
expect(element.tabSummariesInfo[0].overallStatus).to.equal("PASSING");
38-
expect(element.tabSummariesInfo[0].failuresSummary?.failureStats.numFailingTests).to.equal(1);
39-
expect(element.tabSummariesInfo[0].failuresSummary?.topFailingTests[0].failCount).to.equal(1);
40-
expect(element.tabSummariesInfo[0].failuresSummary?.topFailingTests[0].displayName).to.equal("fake-test-1");
41-
expect(element.tabSummariesInfo[0].healthinessSummary?.topFlakyTests[0].displayName).to.equal("fake-test-2");
42-
expect(element.tabSummariesInfo[0].healthinessSummary?.topFlakyTests[0].flakiness).to.equal(2);
43-
expect(element.tabSummariesInfo[0].healthinessSummary?.healthinessStats.numFlakyTests).to.equal(2);
39+
expect(element.tabSummariesInfo[0].name).to.equal('fake-tab-1');
40+
expect(element.tabSummariesInfo[0].overallStatus).to.equal('PASSING');
41+
expect(
42+
element.tabSummariesInfo[0].failuresSummary?.failureStats.numFailingTests
43+
).to.equal(1);
44+
expect(
45+
element.tabSummariesInfo[0].failuresSummary?.topFailingTests[0].failCount
46+
).to.equal(1);
47+
expect(
48+
element.tabSummariesInfo[0].failuresSummary?.topFailingTests[0]
49+
.displayName
50+
).to.equal('fake-test-1');
51+
expect(
52+
element.tabSummariesInfo[0].healthinessSummary?.topFlakyTests[0]
53+
.displayName
54+
).to.equal('fake-test-2');
55+
expect(
56+
element.tabSummariesInfo[0].healthinessSummary?.topFlakyTests[0].flakiness
57+
).to.equal(2);
58+
expect(
59+
element.tabSummariesInfo[0].healthinessSummary?.healthinessStats
60+
.numFlakyTests
61+
).to.equal(2);
62+
63+
const tabSummaries: NodeListOf<TabSummary> =
64+
element.shadowRoot!.querySelectorAll('tab-summary');
65+
await waitUntil(
66+
() =>
67+
tabSummaries[0]!.shadowRoot!.querySelector(
68+
'testgrid-healthiness-summary'
69+
),
70+
'Dashboard summary did not render healthiness summary',
71+
{
72+
timeout: 4000,
73+
}
74+
);
75+
76+
await waitUntil(
77+
() =>
78+
tabSummaries[0]!.shadowRoot!.querySelector('testgrid-failures-summary'),
79+
'Dashboard summary did not render failures summary',
80+
{
81+
timeout: 4000,
82+
}
83+
);
84+
});
85+
86+
it('show alerts when toggled', async () => {
87+
// waiting until list items (dashboards and groups) are fully rendered
88+
await waitUntil(
89+
() => element.shadowRoot!.querySelector('tab-summary'),
90+
'Dashboard summary did not render tab summaries',
91+
{
92+
timeout: 4000,
93+
}
94+
);
95+
96+
const dropdowns: NodeListOf<HTMLDivElement> = element
97+
.shadowRoot!.querySelectorAll('tab-summary')[0]!
98+
.shadowRoot!.querySelector('testgrid-failures-summary')!
99+
.shadowRoot!.querySelectorAll('.dropdown-container');
100+
const table: HTMLTableElement | null = dropdowns[0]!.querySelector('table');
101+
expect(table).to.not.exist;
102+
103+
// Show alerts.
104+
const buttons: NodeListOf<HTMLButtonElement> | null =
105+
dropdowns[0]!.querySelectorAll('button.btn');
106+
buttons[0]!.click();
107+
108+
await waitUntil(
109+
() =>
110+
element
111+
.shadowRoot!.querySelectorAll('tab-summary')[0]!
112+
.shadowRoot!.querySelector('testgrid-failures-summary')!
113+
.shadowRoot!.querySelectorAll('.dropdown-container')[0]!
114+
.querySelector('table'),
115+
'Dashboard summary did not render healthiness table',
116+
{
117+
timeout: 4000,
118+
}
119+
);
120+
});
121+
122+
it('show healthiness summary when toggled', async () => {
123+
// waiting until list items (dashboards and groups) are fully rendered
124+
await waitUntil(
125+
() => element.shadowRoot!.querySelector('tab-summary'),
126+
'Dashboard summary did not render tab summaries',
127+
{
128+
timeout: 4000,
129+
}
130+
);
131+
132+
const dropdowns: NodeListOf<HTMLDivElement> = element
133+
.shadowRoot!.querySelectorAll('tab-summary')[0]!
134+
.shadowRoot!.querySelector('testgrid-healthiness-summary')!
135+
.shadowRoot!.querySelectorAll('.dropdown-container');
136+
const table: HTMLTableElement | null = dropdowns[0]!.querySelector('table');
137+
expect(table).to.not.exist;
138+
139+
// Show healthiness summary.
140+
const buttons: NodeListOf<HTMLButtonElement> | null =
141+
dropdowns[0]!.querySelectorAll('button.btn');
142+
buttons[0]!.click();
143+
144+
await waitUntil(
145+
() =>
146+
element
147+
.shadowRoot!.querySelectorAll('tab-summary')[0]!
148+
.shadowRoot!.querySelector('testgrid-healthiness-summary')!
149+
.shadowRoot!.querySelectorAll('.dropdown-container')[0]!
150+
.querySelector('table'),
151+
'Dashboard summary did not render healthiness table',
152+
{
153+
timeout: 4000,
154+
}
155+
);
44156
});
45157
});

0 commit comments

Comments
 (0)