* Waits until network requests have all been resolved * @param page - Playwright page object * @param delayMs - Amount of time in ms to wait after the last request resolves before cleaning up * @param timeoutMs - Amount of time to wait before continuing. In case of timeout, this function resolves
( page: Page, delayMs = 300, timeoutMs = 180000 )
| 151 | * @returns |
| 152 | */ |
| 153 | function networkIdle( |
| 154 | page: Page, |
| 155 | delayMs = 300, |
| 156 | timeoutMs = 180000 |
| 157 | ): Promise<number> { |
| 158 | return new Promise((resolve) => { |
| 159 | const cleanup = () => { |
| 160 | page.off('request', requestHandler) |
| 161 | page.off('requestfailed', requestFinishedHandler) |
| 162 | page.off('requestfinished', requestFinishedHandler) |
| 163 | clearTimeout(fullTimeout) |
| 164 | if (timeout) { |
| 165 | clearTimeout(timeout) |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | const requests = new Map<string, number>() |
| 170 | const start = Date.now() |
| 171 | let lastRequest: number |
| 172 | let timeout: NodeJS.Timeout | null = null |
| 173 | |
| 174 | const fullTimeout = setTimeout(() => { |
| 175 | cleanup() |
| 176 | console.error( |
| 177 | `Timeout while waiting for network idle. These requests are still pending: ${Array.from( |
| 178 | requests |
| 179 | ).join(', ')}} time is ${lastRequest - start}` |
| 180 | ) |
| 181 | resolve(Date.now() - lastRequest) |
| 182 | }, timeoutMs) |
| 183 | |
| 184 | const requestFilter = (request: Request) => { |
| 185 | return request.headers().accept !== 'text/event-stream' |
| 186 | } |
| 187 | |
| 188 | const requestHandler = (request: Request) => { |
| 189 | requests.set(request.url(), (requests.get(request.url()) ?? 0) + 1) |
| 190 | if (timeout) { |
| 191 | clearTimeout(timeout) |
| 192 | timeout = null |
| 193 | } |
| 194 | // Avoid tracking some requests, but we only know this after awaiting |
| 195 | // so we need to do this weird stunt to ensure that |
| 196 | if (!requestFilter(request)) { |
| 197 | requestFinishedInternal(request) |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | const requestFinishedHandler = (request: Request) => { |
| 202 | if (requestFilter(request)) { |
| 203 | requestFinishedInternal(request) |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | const requestFinishedInternal = (request: Request) => { |
| 208 | lastRequest = Date.now() |
| 209 | const currentCount = requests.get(request.url()) |
| 210 | if (currentCount === undefined) { |