diff --git a/services/web/frontend/js/shared/components/loading-spinner.js b/services/web/frontend/js/shared/components/loading-spinner.js
index f019c6715a..0828202cbf 100644
--- a/services/web/frontend/js/shared/components/loading-spinner.js
+++ b/services/web/frontend/js/shared/components/loading-spinner.js
@@ -1,14 +1,38 @@
import { useTranslation } from 'react-i18next'
import Icon from './icon'
+import { useEffect, useState } from 'react'
+import PropTypes from 'prop-types'
-function LoadingSpinner() {
+function LoadingSpinner({ delay = 500 }) {
const { t } = useTranslation()
+
+ const [show, setShow] = useState(false)
+
+ useEffect(() => {
+ const timer = window.setTimeout(() => {
+ setShow(true)
+ }, delay)
+
+ return () => {
+ window.clearTimeout(timer)
+ }
+ }, [delay])
+
+ if (!show) {
+ return null
+ }
+
return (
- {` ${t('loading')}…`}
+
+ {t('loading')}…
)
}
+LoadingSpinner.propTypes = {
+ delay: PropTypes.number,
+}
+
export default LoadingSpinner
diff --git a/services/web/test/frontend/features/chat/components/chat-pane.test.js b/services/web/test/frontend/features/chat/components/chat-pane.test.js
index b010cfd8bc..48a0b6de63 100644
--- a/services/web/test/frontend/features/chat/components/chat-pane.test.js
+++ b/services/web/test/frontend/features/chat/components/chat-pane.test.js
@@ -12,8 +12,21 @@ import {
cleanUpContext,
} from '../../../helpers/render-with-context'
import { stubMathJax, tearDownMathJaxStubs } from './stubs'
+import sinon from 'sinon'
describe('', function () {
+ beforeEach(function () {
+ this.clock = sinon.useFakeTimers({
+ toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'],
+ })
+ })
+
+ afterEach(function () {
+ this.clock.runAll()
+ this.clock.restore()
+ fetchMock.reset()
+ })
+
const user = {
id: 'fake_user',
first_name: 'fake_user_first_name',
@@ -78,10 +91,16 @@ describe('', function () {
})
it('a loading spinner is rendered while the messages are loading, then disappears', async function () {
- fetchMock.get(/messages/, [])
+ fetchMock.get(/messages/, [], { delay: 1000 })
renderWithChatContext(, { user })
+ this.clock.tick(600) // wait for spinner to be displayed
+
+ await screen.findByText('Loading…')
+
+ this.clock.tick(1000) // wait for response to be received
+
await waitForElementToBeRemoved(() => screen.getByText('Loading…'))
})