diff --git a/utils/waitForAttribute.js b/utils/waitForAttribute.js index fd80e3b30..669f09c62 100644 --- a/utils/waitForAttribute.js +++ b/utils/waitForAttribute.js @@ -10,10 +10,27 @@ * }} options */ export const waitForAttribute = ({ element, attribute, onSuccess, onTimeout, timeout = 300 }) => { + const currentAttrValue = element.getAttribute(attribute); + if (currentAttrValue !== null) { + onSuccess(currentAttrValue); + return; + } + + const observer = new MutationObserver((mutations) => { + const mutation = mutations[mutations.length - 1]; + handleMutation(mutation); + }); + + observer.observe(element, { + attributes: true, + attributeFilter: [attribute], + }); + const timeoutId = setTimeout(() => { observer.disconnect(); onTimeout(); }, timeout); + /** @param {MutationRecord} mutation */ const handleMutation = (mutation) => { const attrValue = element.getAttribute(attribute); @@ -23,17 +40,4 @@ export const waitForAttribute = ({ element, attribute, onSuccess, onTimeout, tim onSuccess(attrValue); } }; - const currentAttrValue = element.getAttribute(attribute); - if (currentAttrValue !== null) { - clearTimeout(timeoutId); - onSuccess(currentAttrValue); - } - const observer = new MutationObserver((mutations) => { - const mutation = mutations[mutations.length - 1]; - handleMutation(mutation); - }); - observer.observe(element, { - attributes: true, - attributeFilter: [attribute], - }); }; diff --git a/utils/waitForAttribute.test.js b/utils/waitForAttribute.test.js index 5c47d6b4f..ba97f6e4c 100644 --- a/utils/waitForAttribute.test.js +++ b/utils/waitForAttribute.test.js @@ -55,4 +55,24 @@ describe('waitForAttribute', () => { expect(onSuccess.getCall(0).args[0]).to.equal('test'); expect(onTimeout.called).to.be.false; }); + + it('should not call onSuccess on the second attribute change', async () => { + const element = document.createElement('div'); + element.setAttribute(TEST_ATTRIBUTE, 'test'); + const onSuccess = spy(); + const onTimeout = spy(); + waitForAttribute({ + element, + attribute: TEST_ATTRIBUTE, + onSuccess, + onTimeout, + timeout: 10, + }); + await delay(100); + element.setAttribute(TEST_ATTRIBUTE, 'tes2'); + await delay(100); + expect(onSuccess.calledOnce).to.be.true; + expect(onSuccess.getCall(0).args[0]).to.equal('test'); + expect(onTimeout.called).to.be.false; + }); });