From 7d09180cbde581b3a3beeb97aab363431c7faf6d Mon Sep 17 00:00:00 2001 From: Andrew Baldwin Date: Thu, 8 Aug 2024 16:33:46 -0400 Subject: [PATCH 1/4] Fix edit test button --- .../components/SwarmForm/SwarmEditForm.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx b/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx index e9843255d6..dfc3283995 100644 --- a/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx +++ b/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx @@ -3,21 +3,23 @@ import { connect } from 'react-redux'; import Form from 'components/Form/Form'; import { useStartSwarmMutation } from 'redux/api/swarm'; -import { ISwarmState } from 'redux/slice/swarm.slice'; +import { ISwarmState, swarmActions } from 'redux/slice/swarm.slice'; import { IRootState } from 'redux/store'; -type ISwarmFormInput = Pick; +type ISwarmFormInput = Pick; interface ISwarmForm extends ISwarmFormInput { onSubmit: () => void; + setSwarm: (swarmPayload: Partial) => void; } -function SwarmEditForm({ onSubmit, numUsers, spawnRate }: ISwarmForm) { +function SwarmEditForm({ onSubmit, userCount, spawnRate, setSwarm }: ISwarmForm) { const [startSwarm] = useStartSwarmMutation(); const onEditSwarm = (inputData: ISwarmFormInput) => { onSubmit(); startSwarm(inputData); + setSwarm(inputData); }; return ( @@ -28,7 +30,7 @@ function SwarmEditForm({ onSubmit, numUsers, spawnRate }: ISwarmForm) { onSubmit={onEditSwarm}> @@ -48,9 +50,13 @@ function SwarmEditForm({ onSubmit, numUsers, spawnRate }: ISwarmForm) { ); } -const storeConnector = ({ swarm: { spawnRate, numUsers } }: IRootState) => ({ +const storeConnector = ({ swarm: { spawnRate, userCount } }: IRootState) => ({ spawnRate, - numUsers, + userCount, }); -export default connect(storeConnector)(SwarmEditForm); +const actionCreator = { + setSwarm: swarmActions.setSwarm, +}; + +export default connect(storeConnector, actionCreator)(SwarmEditForm); From 98dc76ab0a1b0c9b7867931e9dbb3a388bc0a929 Mon Sep 17 00:00:00 2001 From: Andrew Baldwin Date: Thu, 8 Aug 2024 16:49:41 -0400 Subject: [PATCH 2/4] No break in navbar --- .../src/components/Layout/Navbar/Navbar.tsx | 2 +- .../components/Layout/Navbar/SwarmMonitor.tsx | 29 +++++++++++++++---- .../components/StateButtons/StateButtons.tsx | 2 +- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/locust/webui/src/components/Layout/Navbar/Navbar.tsx b/locust/webui/src/components/Layout/Navbar/Navbar.tsx index 205f7f9e14..1aef417dbb 100644 --- a/locust/webui/src/components/Layout/Navbar/Navbar.tsx +++ b/locust/webui/src/components/Layout/Navbar/Navbar.tsx @@ -9,7 +9,7 @@ export default function Navbar() { return ( - + Host - {host} + + + {host} + + @@ -35,7 +46,9 @@ function SwarmMonitor({ Users - {userCount} + + {userCount} + )} @@ -44,19 +57,23 @@ function SwarmMonitor({ Workers - {workerCount} + + {workerCount} + )} RPS - {totalRps} + + {totalRps} + Failures - {`${failRatio}%`} + {`${failRatio}%`} ); diff --git a/locust/webui/src/components/StateButtons/StateButtons.tsx b/locust/webui/src/components/StateButtons/StateButtons.tsx index 6a2312659c..5bc20b934a 100644 --- a/locust/webui/src/components/StateButtons/StateButtons.tsx +++ b/locust/webui/src/components/StateButtons/StateButtons.tsx @@ -15,7 +15,7 @@ export default function StateButtons() { } return ( - + {swarmState === SWARM_STATE.STOPPED ? ( ) : ( From b7f685e966dcd6dbbf4394f45de9738579f37471 Mon Sep 17 00:00:00 2001 From: Andrew Baldwin Date: Thu, 8 Aug 2024 17:26:29 -0400 Subject: [PATCH 3/4] Add reference to locust cloud --- .../src/components/Layout/Footer/About.tsx | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/locust/webui/src/components/Layout/Footer/About.tsx b/locust/webui/src/components/Layout/Footer/About.tsx index 951c6f146c..2abdd2126b 100644 --- a/locust/webui/src/components/Layout/Footer/About.tsx +++ b/locust/webui/src/components/Layout/Footer/About.tsx @@ -22,23 +22,29 @@ export default function About() { Locust is free and open source software released under the{' '} - MIT License + MIT License It was originally developed by Carl Byström and{' '} - Jonatan Heyman. Since 2019, it - is primarily maintained by Lars Holmberg - . + Jonatan Heyman. Since 2019, it is + primarily maintained by Lars Holmberg. Many thanks to all our wonderful{' '} - - contributors - - ! + contributors! +
+ + Need help getting started? + + Locust Cloud gives you access to hosted, easily + scalable, and distributed load generation, as well as advanced reporting — all while + preserving the flexible “it’s just Python” approach to load test scripting that Locust + provides +
+
Version @@ -54,7 +60,10 @@ export default function About() { GitHub - Documentation + Documentation + + + Blog
From b0757b0132c8ca6095b63701bb246f0fc652f45b Mon Sep 17 00:00:00 2001 From: Andrew Baldwin Date: Fri, 9 Aug 2024 09:10:26 -0400 Subject: [PATCH 4/4] Update static asset --- locust/webui/index.html | 2 +- locust/webui/public/assets/favicon.ico | Bin 8348 -> 0 bytes locust/webui/public/assets/favicon.png | Bin 0 -> 704 bytes locust/webui/src/assets/Logo.tsx | 49 ++++++++++++++++++ locust/webui/src/assets/logo.png | Bin 19299 -> 0 bytes .../src/components/Layout/Navbar/Navbar.tsx | 21 +++----- locust/webui/src/hooks/useTheme.ts | 2 +- locust/webui/src/images.d.ts | 1 + locust/webui/src/pages/Auth.tsx | 18 ++----- locust/webui/src/pages/Dashboard.tsx | 2 +- .../webui/src/pages/tests/Dashboard.test.tsx | 3 +- 11 files changed, 63 insertions(+), 35 deletions(-) delete mode 100644 locust/webui/public/assets/favicon.ico create mode 100644 locust/webui/public/assets/favicon.png create mode 100644 locust/webui/src/assets/Logo.tsx delete mode 100644 locust/webui/src/assets/logo.png diff --git a/locust/webui/index.html b/locust/webui/index.html index c6fa08d331..2c2ae373d7 100644 --- a/locust/webui/index.html +++ b/locust/webui/index.html @@ -2,7 +2,7 @@ - + diff --git a/locust/webui/public/assets/favicon.ico b/locust/webui/public/assets/favicon.ico deleted file mode 100644 index b2d458d9f72440515308b01e5894984a1271f6ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8348 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 + + + + + + + + ); +} diff --git a/locust/webui/src/assets/logo.png b/locust/webui/src/assets/logo.png deleted file mode 100644 index 9f4651b5b185d7c0f563a53133cc75e8e9d7601a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19299 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 diff --git a/locust/webui/src/components/Layout/Navbar/Navbar.tsx b/locust/webui/src/components/Layout/Navbar/Navbar.tsx index 1aef417dbb..8ac75100d8 100644 --- a/locust/webui/src/components/Layout/Navbar/Navbar.tsx +++ b/locust/webui/src/components/Layout/Navbar/Navbar.tsx @@ -1,11 +1,14 @@ -import { AppBar, Box, Container, Link, Toolbar, Typography } from '@mui/material'; +import { AppBar, Box, Container, Link, Toolbar } from '@mui/material'; -import Logo from 'assets/logo.png'; +import Logo from 'assets/Logo'; import DarkLightToggle from 'components/Layout/Navbar/DarkLightToggle'; import SwarmMonitor from 'components/Layout/Navbar/SwarmMonitor'; import StateButtons from 'components/StateButtons/StateButtons'; +import { useSelector } from 'redux/hooks'; export default function Navbar() { + const isDarkMode = useSelector(({ theme }) => theme.isDarkMode); + return ( @@ -16,19 +19,7 @@ export default function Navbar() { sx={{ display: 'flex', alignItems: 'center', columnGap: 2 }} underline='none' > - - - Locust - + diff --git a/locust/webui/src/hooks/useTheme.ts b/locust/webui/src/hooks/useTheme.ts index 707e3698cf..bd20fcd47b 100644 --- a/locust/webui/src/hooks/useTheme.ts +++ b/locust/webui/src/hooks/useTheme.ts @@ -12,5 +12,5 @@ export default function useTheme() { [isDarkMode], ); - return theme; + return { theme, isDarkMode }; } diff --git a/locust/webui/src/images.d.ts b/locust/webui/src/images.d.ts index e2937d470e..e238d01ca3 100644 --- a/locust/webui/src/images.d.ts +++ b/locust/webui/src/images.d.ts @@ -1 +1,2 @@ declare module '*.png'; +declare module '*.svg'; diff --git a/locust/webui/src/pages/Auth.tsx b/locust/webui/src/pages/Auth.tsx index 4808e25bf1..0e021109cd 100644 --- a/locust/webui/src/pages/Auth.tsx +++ b/locust/webui/src/pages/Auth.tsx @@ -2,13 +2,13 @@ import { Alert, Box, Button, IconButton, TextField, Typography } from '@mui/mate import CssBaseline from '@mui/material/CssBaseline'; import { ThemeProvider } from '@mui/material/styles'; -import Logo from 'assets/logo.png'; +import Logo from 'assets/Logo'; import DarkLightToggle from 'components/Layout/Navbar/DarkLightToggle'; import useTheme from 'hooks/useTheme'; import { IAuthArgs } from 'types/auth.types'; export default function Auth({ authProviders, error, usernamePasswordCallback }: IAuthArgs) { - const theme = useTheme(); + const { theme, isDarkMode } = useTheme(); return ( @@ -34,19 +34,7 @@ export default function Auth({ authProviders, error, usernamePasswordCallback }: }} > - - - Locust - + {usernamePasswordCallback && (

diff --git a/locust/webui/src/pages/Dashboard.tsx b/locust/webui/src/pages/Dashboard.tsx index d57a3bded5..537015e094 100644 --- a/locust/webui/src/pages/Dashboard.tsx +++ b/locust/webui/src/pages/Dashboard.tsx @@ -24,7 +24,7 @@ function Dashboard({ swarmState, tabs, extendedTabs }: IDashboard) { useSwarmUi(); useLogViewer(); - const theme = useTheme(); + const { theme } = useTheme(); return ( diff --git a/locust/webui/src/pages/tests/Dashboard.test.tsx b/locust/webui/src/pages/tests/Dashboard.test.tsx index 01d2ff3aef..2daf70e263 100644 --- a/locust/webui/src/pages/tests/Dashboard.test.tsx +++ b/locust/webui/src/pages/tests/Dashboard.test.tsx @@ -9,13 +9,12 @@ describe('Dashboard', () => { test('renders the layout', () => { const { getByRole } = renderWithProvider(); - const logo = getByRole('img'); + const logo = getByRole('img', { name: 'Locust' }); const heading = getByRole('link', { name: 'Locust' }); expect(heading).toBeTruthy(); expect(heading.getAttribute('href')).toEqual('/'); expect(logo).toBeTruthy(); - expect(logo.getAttribute('src')).toEqual('/src/assets/logo.png'); }); test('renders the swarm form by default', () => {