diff --git a/app/javascript/packages/spinner-button/spinner-button-element.spec.ts b/app/javascript/packages/spinner-button/spinner-button-element.spec.ts index c91fdff2d7f..ed2678340bc 100644 --- a/app/javascript/packages/spinner-button/spinner-button-element.spec.ts +++ b/app/javascript/packages/spinner-button/spinner-button-element.spec.ts @@ -1,11 +1,13 @@ import baseUserEvent from '@testing-library/user-event'; import { getByRole, fireEvent, screen } from '@testing-library/dom'; +import type { SinonStub } from 'sinon'; import { useSandbox } from '@18f/identity-test-helpers'; import './spinner-button-element'; import type { SpinnerButtonElement } from './spinner-button-element'; describe('SpinnerButtonElement', () => { - const { clock } = useSandbox({ useFakeTimers: true }); + const sandbox = useSandbox({ useFakeTimers: true }); + const { clock } = sandbox; const userEvent = baseUserEvent.setup({ advanceTimers: clock.tick }); const longWaitDurationMs = 1000; @@ -118,4 +120,18 @@ describe('SpinnerButtonElement', () => { expect(wrapper.classList.contains('spinner-button--spinner-active')).to.be.false(); }); + + it('removes action message timeout when disconnected from the page', async () => { + const wrapper = createWrapper({ actionMessage: 'Verifying...' }); + const button = screen.getByRole('link', { name: 'Click Me' }); + + sandbox.spy(window, 'setTimeout'); + sandbox.spy(window, 'clearTimeout'); + + await userEvent.click(button); + wrapper.parentNode!.removeChild(wrapper); + + const timeoutId = (window.setTimeout as unknown as SinonStub).getCall(0).returnValue; + expect(window.clearTimeout).to.have.been.calledWith(timeoutId); + }); }); diff --git a/app/javascript/packages/spinner-button/spinner-button-element.ts b/app/javascript/packages/spinner-button/spinner-button-element.ts index 62571c8bd96..903fbd9ce28 100644 --- a/app/javascript/packages/spinner-button/spinner-button-element.ts +++ b/app/javascript/packages/spinner-button/spinner-button-element.ts @@ -38,6 +38,10 @@ export class SpinnerButtonElement extends HTMLElement { this.addEventListener('spinner.stop', () => this.toggleSpinner(false)); } + disconnectedCallback() { + window.clearTimeout(this.#longWaitTimeout); + } + toggleSpinner(isVisible: boolean) { const { button, actionMessage } = this.elements; this.classList.toggle('spinner-button--spinner-active', isVisible);