Last active
May 9, 2023 23:21
-
-
Save graffhyrum/b57f47bcedfe8f1b166d4317e3c115c0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {Locator} from '@playwright/test'; | |
| /** | |
| * Wait for `elem` to have no mutations for a period of | |
| * `noMutationDuration` ms. If `timeout` ms elapse without a "no mutation" | |
| * period of sufficient length, throw an error. | |
| * @param elem | |
| * @param noMutationDuration | |
| * @param mutTimeout | |
| * @param waitForFirstMutation If true, wait until the first mutation before | |
| * starting to wait for the `noMutationDuration` period. | |
| */ | |
| export async function waitForMutationToStop( | |
| elem: Locator, | |
| noMutationDuration = 500, | |
| mutTimeout = 10 * 1000, | |
| waitForFirstMutation = false | |
| ): Promise<void> { | |
| return elem.evaluate( | |
| async ( | |
| elem, | |
| {noMutationDuration, timeout, waitForFirstMutation} | |
| ): Promise<void> => { | |
| return new Promise<void>((resolve, reject) => { | |
| const config = { | |
| attributes: true, | |
| childList: true, | |
| characterData: true, | |
| subtree: true, | |
| }; | |
| let lastMutationTime = waitForFirstMutation ? 0 : Date.now(); | |
| let resolveTimeout: ReturnType<typeof setTimeout>; | |
| const observer = new MutationObserver(callback); | |
| observer.observe(elem, config); | |
| resetTimeout(); | |
| const rejectTimeout = setTimeout(() => { | |
| observer.disconnect(); | |
| reject(new Error(`Mutation timeout exceeded: ${timeout} ms`)); | |
| }, timeout); | |
| function callback() { | |
| lastMutationTime = Date.now(); | |
| clearTimeout(resolveTimeout); | |
| resetTimeout(); | |
| } | |
| function resetTimeout() { | |
| resolveTimeout = setTimeout(checkTimeout, noMutationDuration); | |
| } | |
| function checkTimeout() { | |
| if (Date.now() - lastMutationTime > noMutationDuration) { | |
| observer.disconnect(); | |
| clearTimeout(resolveTimeout); | |
| resolve(); | |
| } else { | |
| resetTimeout(); | |
| } | |
| } | |
| }); | |
| }, | |
| {noMutationDuration, timeout: mutTimeout, waitForFirstMutation} | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment