Run a callback and capture requests with the given `method` and `pathname`.
(
action: () => Promise<T>,
{
request: requestMatcher,
timeoutMs = 5000,
}: {
request: RequestMatcher
timeoutMs?: number
}
)
| 21 | export function createRequestTracker(browser: Playwright) { |
| 22 | /** Run a callback and capture requests with the given `method` and `pathname`. */ |
| 23 | async function captureResponse<T>( |
| 24 | action: () => Promise<T>, |
| 25 | { |
| 26 | request: requestMatcher, |
| 27 | timeoutMs = 5000, |
| 28 | }: { |
| 29 | request: RequestMatcher |
| 30 | timeoutMs?: number |
| 31 | } |
| 32 | ): Promise<[result: T, captured: PlaywrightResponse]> { |
| 33 | const isMatchingRequest = async (request: PlaywrightRequest) => { |
| 34 | if (typeof requestMatcher === 'function') { |
| 35 | // This can be async to allow matching on things like `request.allHeaders()` which is a promise. |
| 36 | return await requestMatcher(request) |
| 37 | } else { |
| 38 | const url = new URL(request.url()) |
| 39 | if (requestMatcher.pathname !== url.pathname) { |
| 40 | return false |
| 41 | } |
| 42 | if (requestMatcher.search !== undefined) { |
| 43 | if (url.search !== requestMatcher.search) { |
| 44 | return false |
| 45 | } |
| 46 | } |
| 47 | if (requestMatcher.method !== undefined) { |
| 48 | if (request.method() !== requestMatcher.method) { |
| 49 | return false |
| 50 | } |
| 51 | } |
| 52 | return true |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | const responseCtrl = promiseWithResolvers<PlaywrightResponse>() |
| 57 | let isSettled = false |
| 58 | |
| 59 | let capturedRequest: PlaywrightRequest | undefined |
| 60 | |
| 61 | const cleanups: (() => void)[] = [] |
| 62 | |
| 63 | // Make sure we clean up all event listeners and timers after we're done. |
| 64 | responseCtrl.promise.finally(() => { |
| 65 | isSettled = true |
| 66 | cleanups.forEach((cb) => cb()) |
| 67 | }) |
| 68 | |
| 69 | // Listen for requests that match the criteria. |
| 70 | const onRequest = async (request: PlaywrightRequest) => { |
| 71 | if (!(await isMatchingRequest(request))) { |
| 72 | return |
| 73 | } |
| 74 | |
| 75 | // If `capturedRequest` is already set, then we've got multiple requests that match the criteria. |
| 76 | // This is currently not supported, though if needed, we could extend the API |
| 77 | // to allow capturing multiple requests and returning them as an array. |
| 78 | if (capturedRequest) { |
| 79 | const criteriaDescription = |
| 80 | typeof requestMatcher === 'function' |
nothing calls this directly
no test coverage detected