Skip to content

Commit fb2f49f

Browse files
committed
Fix bugs associated with disabling nav bar buttons
The current path when the app first started is the HTTP/2 page. The local `state`, however, does not point to the same thing. This commit ensures the initial `curPage` state in `ProtocolSelect.tsx` is consistent with `currPath` and the request fields and contents are updated accordingly. Tests are also updated to handle the disabling feature
1 parent db33fdd commit fb2f49f

File tree

5 files changed

+92
-34
lines changed

5 files changed

+92
-34
lines changed

src/client/components/navbar/ProtocolSelect.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import { Link, useLocation } from 'react-router-dom';
33

44
// Import actions so that the navbar can interact with the Redux store.
@@ -60,13 +60,15 @@ const SelectedButton = styled(CustomButton)`
6060
background-color: #58a4b0;
6161
`;
6262

63+
const HTTP_NAME = 'HTTP/2';
64+
const HTTP_VALUE = 'rest';
6365
/**
6466
* name: The display name for the button.
6567
* route: The React Router route to redirect to on click (see MainContainer.tsx)
6668
* value: The value of the button used to update the Redux store.
6769
*/
6870
const pages: page[] = [
69-
{ name: 'HTTP/2', route: '/', value: 'rest' },
71+
{ name: HTTP_NAME, route: '/', value: HTTP_VALUE },
7072
{ name: 'GraphQL', route: '/graphql', value: 'graphQL' },
7173
{ name: 'WebSocket', route: '/websocket', value: 'ws' },
7274
];
@@ -102,6 +104,22 @@ function ProtocolSelect() {
102104
};
103105
const [curPage, setCurPage] = useState('');
104106

107+
useEffect(() => {
108+
const currentPage: page | undefined = [...pages, ...experimentalPages].find(
109+
({ route }) => route === currPath
110+
);
111+
if (!currentPage) {
112+
console.warn(
113+
`Current page path cannot be found. Default to ${HTTP_NAME}`
114+
);
115+
onProtocolSelect(HTTP_VALUE);
116+
setCurPage(HTTP_NAME);
117+
} else {
118+
onProtocolSelect(currentPage.value);
119+
setCurPage(currentPage.name);
120+
}
121+
}, []);
122+
105123
const handleClick = (value: string, name: string): void => {
106124
onProtocolSelect(value);
107125
setCurPage(name);

test/subSuites/graphqlTest.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,15 @@ module.exports = () => {
7777

7878
beforeEach(() => (num = 0));
7979

80-
afterEach(
81-
async () => await page.locator('button >> text=Clear Workspace').click()
82-
);
80+
afterEach(async () => {
81+
await page.locator('button >> text=Clear Workspace').click();
82+
// Any button in the nav bar that is selected is disabled
83+
// And hard refreshing the page in a test environment is not entirely robust
84+
// since the app can take a bit to load. In that case,
85+
// we work around the limitation by clicking another feature and return to HTTP/2
86+
await page.locator('button>> text=HTTP/2').click();
87+
await page.locator('button>> text=GraphQL').click();
88+
});
8389

8490
it('it should be able to introspect the schema (PUBLIC API)', async () => {
8591
try {
@@ -283,6 +289,10 @@ module.exports = () => {
283289
}, 500);
284290
});
285291

292+
// Purely a workaround to ensure `fillAndSendRequest()` can select `MUTATION` correctly
293+
await page.locator('button#graphql-method').click();
294+
await page.locator(`div[id^="composer"] >> a >> text=QUERY`).click();
295+
286296
// SEND ADDITIONAL MUTATION AFTER UNSUBSCRIBED FROM SERVER
287297
const query3 =
288298
'mutation {post(url: "www.moreexamples.com" description: "Fake site") {description}}';
@@ -349,19 +359,26 @@ module.exports = () => {
349359
await page.waitForLoadState(`domcontentloaded`);
350360
});
351361

352-
beforeEach(() => (num = 0));
362+
beforeEach(async () => {
363+
num = 0;
364+
});
353365

354-
afterEach(
355-
async () => await page.locator('button >> text=Clear Workspace').click()
356-
);
366+
afterEach(async () => {
367+
await page.locator('button >> text=Clear Workspace').click();
368+
// Any button in the nav bar that is selected is disabled
369+
// And hard refreshing the page in a test environment is not entirely robust
370+
// since the app can take a bit to load. In that case,
371+
// we work around the limitation by clicking another feature and return to HTTP/2
372+
await page.locator('button>> text=HTTP/2').click();
373+
await page.locator('button>> text=GraphQL').click();
374+
});
357375

358376
// limiting the amount of time required to simulate the load test
359-
const loadTestDuration = 3;
377+
const stressTestDuration = 3;
360378

361-
it('Load test run button is disabled with no request in workspace window', async () => {
379+
it('Stress test run button is disabled with no request in workspace window', async () => {
362380
try {
363-
await page.locator('button>> text=GraphQL').click();
364-
await page.locator('span >> text=Load Test').click();
381+
await page.locator('span >> text=View Stress Test').click();
365382
const runButton = page.locator('button>> text=Run');
366383
pwTest.expect(runButton).toBeDisabled();
367384
} catch (err) {
@@ -376,25 +393,25 @@ module.exports = () => {
376393
const query = 'subscription {newLink {id description url}}';
377394
await fillGQLRequest(page, url, method, query);
378395
await page.locator('button >> text=Add to Workspace').click();
379-
await page.locator('span >> text=Load Test').click();
396+
await page.locator('span >> text=View Stress Test').click();
380397
const runButton = page.locator('button>> text=Run');
381398
pwTest.expect(runButton).toBeDisabled();
382399
} catch (err) {
383400
console.error(err);
384401
}
385402
});
386403

387-
it('Successful load test with `QUERY`', async () => {
404+
it('Successful stress test with `QUERY`', async () => {
388405
try {
389406
const method = 'QUERY';
390407
const url = 'http://localhost:4000/graphql';
391408
const query = 'query {feed {descriptions}}';
392409
await fillGQLRequest(page, url, method, query);
393410
await page.locator('button >> text=Add to Workspace').click();
394-
await page.locator('span >> text=Load Test').click();
411+
await page.locator('span >> text=View Stress Test').click();
395412
await page
396413
.locator('[placeholder="Duration"]')
397-
.fill(loadTestDuration.toString());
414+
.fill(stressTestDuration.toString());
398415
await page.locator('button>> text=Run').click();
399416

400417
// The load test takes a minimum of 4 seconds to execute

test/subSuites/httpTest.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ const chaiHttp = require('chai-http');
1717
chai.use(chaiHttp);
1818
const path = require('path');
1919
const fs = require('fs');
20-
const { fillRestRequest, addAndSend } = require('./testHelper');
20+
const {
21+
isButtonDisabled,
22+
fillRestRequest,
23+
addAndSend,
24+
} = require('./testHelper');
2125

2226
let electronApp,
2327
page,
@@ -252,7 +256,7 @@ module.exports = () => {
252256
});
253257
});
254258

255-
describe('HTTP/S load testing', () => {
259+
describe('HTTP/S stress testing', () => {
256260
before(async () => {
257261
page = electronApp.windows()[0]; // In case there is more than one window
258262
await page.waitForLoadState(`domcontentloaded`);
@@ -266,17 +270,20 @@ module.exports = () => {
266270

267271
beforeEach(() => (num = 0));
268272

269-
afterEach(
270-
async () => await page.locator('button >> text=Clear Workspace').click()
271-
);
273+
afterEach(async () => {
274+
await page.locator('span >> text=Hide Stress Test').click();
275+
await page.locator('button >> text=Clear Workspace').click();
276+
});
272277

273-
// limiting the amount of time required to simulate the load test
274-
const loadTestDuration = 3;
278+
// limiting the amount of time required to simulate the stress test
279+
const stressTestDuration = 3;
275280

276-
it('Load test run button is disabled with no request in workspace window', async () => {
281+
it('Stress test run button is disabled with no request in workspace window', async () => {
277282
try {
278-
await page.locator('button>> text=HTTP/2').click();
279-
await page.locator('span >> text=Load Test').click();
283+
const httpPath = 'button>> text=HTTP/2';
284+
if (!isButtonDisabled(page, httpPath))
285+
await page.locator(httpPath).click();
286+
await page.locator('span >> text=View Stress Test').click();
280287
const runButton = page.locator('button>> text=Run');
281288
pwTest.expect(runButton).toBeDisabled();
282289
} catch (err) {
@@ -292,27 +299,27 @@ module.exports = () => {
292299
'{"title": "HarryPotter", "author": "JK Rowling", "pages": 500}';
293300
await fillRestRequest(page, url, method, body);
294301
await page.locator('button >> text=Add to Workspace').click();
295-
await page.locator('span >> text=Load Test').click();
302+
await page.locator('span >> text=View Stress Test').click();
296303
const runButton = page.locator('button>> text=Run');
297304
pwTest.expect(runButton).toBeDisabled();
298305
} catch (err) {
299306
console.error(err);
300307
}
301308
});
302309

303-
it('Successful load test with `GET` request', async () => {
310+
it('Successful stress test with `GET` request', async () => {
304311
try {
305312
const url = 'http://localhost:3004/book';
306313
const method = 'GET';
307314
await fillRestRequest(page, url, method);
308315
await page.locator('button >> text=Add to Workspace').click();
309-
await page.locator('span >> text=Load Test').click();
316+
await page.locator('span >> text=View Stress Test').click();
310317
await page
311318
.locator('[placeholder="Duration"]')
312-
.fill(loadTestDuration.toString());
319+
.fill(stressTestDuration.toString());
313320
await page.locator('button>> text=Run').click();
314321

315-
// The load test takes a minimum of 4 seconds to execute
322+
// The stress test takes a minimum of 4 seconds to execute
316323
await new Promise((resolve) => {
317324
setTimeout(async () => {
318325
try {

test/subSuites/reqInputTests.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,12 @@ module.exports = () => {
146146
});
147147

148148
describe('HTTP/2 URL input successful', () => {
149+
// Any button in the nav bar that is selected is disabled
150+
// And hard refreshing the page in a test environment is not entirely robust
151+
// since the app can take a bit to load. In that case,
152+
// we work around the limitation by clicking another feature and return to HTTP/2
149153
before(async () => {
154+
await page.locator('button>> text=GraphQL').click();
150155
await page.locator('button>> text=HTTP/2').click();
151156
});
152157

test/subSuites/testHelper.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
* for E2E testing.
55
*/
66

7+
const isButtonDisabled = async (page, path) => {
8+
const button = await page.locator(path);
9+
const isDisabled = await button.getAttribute('disabled');
10+
return isDisabled !== null;
11+
};
12+
713
const fillRestRequest = async (
814
page,
915
url,
@@ -14,7 +20,9 @@ const fillRestRequest = async (
1420
) => {
1521
try {
1622
// Make sure HTTP2 method is selected
17-
await page.locator('button>> text=HTTP/2').click();
23+
const httpPath = 'button>> text=HTTP/2';
24+
if (!(await isButtonDisabled(page, httpPath)))
25+
await page.locator(httpPath).click();
1826

1927
// click and select METHOD if it isn't GET
2028
if (method !== 'GET') {
@@ -81,7 +89,9 @@ const fillGQLBasicInfo = async (
8189
) => {
8290
try {
8391
// click and check GRAPHQL
84-
await page.locator('button>> text=GraphQL').click();
92+
const gqlPath = 'button>> text=GraphQL';
93+
if (!(await isButtonDisabled(page, gqlPath)))
94+
await page.locator(gqlPath).click();
8595

8696
// click and select METHOD if it isn't QUERY
8797
if (method !== 'QUERY') {
@@ -186,6 +196,7 @@ const clearAndFillTestScriptArea = async (page, script) => {
186196
};
187197

188198
module.exports = {
199+
isButtonDisabled,
189200
fillRestRequest,
190201
fillGQLBasicInfo,
191202
fillGQLRequest,

0 commit comments

Comments
 (0)