Last active
May 24, 2024 16:26
-
-
Save heyMP/d38b9b5378032a27efcc455d88a5fc2a to your computer and use it in GitHub Desktop.
Playwright stream events from browser.
This file contains 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
/** | |
* An async queue that can stream existing values | |
* and stream new values as they are added using | |
* async generators and async iterators. | |
* | |
* @example | |
* | |
* const counter = new AsyncQueue<number>(); | |
* counter.add(1); | |
* counter.add(2); | |
* counter.add(3); | |
* setTimeout(() => counter.add(4), 1000); | |
* for await (const value of counter) { | |
* console.log(value); | |
* if (value === 4) break; | |
* } | |
*/ | |
export class AsyncQueue<T> extends EventTarget { | |
queue: T[] = []; | |
abortController = new AbortController(); | |
constructor(initialValue?: T[]) { | |
super(); | |
if (initialValue) { | |
this.queue = initialValue; | |
} | |
} | |
/** | |
* @param value | |
*/ | |
add(value: T) { | |
this.queue.push(value); | |
this.dispatchEvent(new CustomEvent('updated', {detail: value})); | |
} | |
dispose() { | |
this.abortController.abort(); | |
} | |
/** | |
* Async generator that yields the current value of the Signal and waits for the next update | |
* | |
* @example | |
* for await (const value of queue.stream()) { | |
* } | |
*/ | |
async *stream() { | |
for (const i of this.queue) { | |
yield i; | |
} | |
while (true) { | |
yield new Promise((resolve) => | |
this.addEventListener('updated', (e) => { | |
if (!(e instanceof CustomEvent)) return; | |
resolve(e.detail); | |
}, {once: true, signal: this.abortController.signal}), | |
); | |
} | |
} | |
/** | |
* Async iterator that yields the current value | |
* | |
* @example | |
* for await (const value of queue) { | |
* } | |
*/ | |
[Symbol.asyncIterator]() { | |
return this.stream(); | |
} | |
} |
This file contains 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 {BrowserContext, Page} from '@playwright/test'; | |
import { AsyncQueue } from './AsyncQueue' | |
export async function monitorOidcManagerEvents(page: Page) { | |
const oidcEventQueue = new AsyncQueue<CustomEvent>(); | |
const callback = (e: CustomEvent) => { | |
oidcEventQueue.add(e); | |
}; | |
await page.exposeFunction('oidcEventQueue', callback); | |
await page.addInitScript(async () => { | |
window.addEventListener('oidc-manager-registered', () => { | |
console.log('oidc-manager-registered'); | |
window.oidcManager.addEventListener('message', (e: any) => { | |
// @ts-ignore | |
window.oidcManagerEvents = window.oidcManagerEvents || []; | |
// @ts-ignore | |
window.oidcEventQueue(e); | |
}); | |
}); | |
}); | |
return oidcEventQueue; | |
} |
This file contains 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 {Page, expect, test} from '@playwright/test'; | |
import { | |
monitorOidcManagerEvents, | |
} from './helpers'; | |
test('verify login_required event is published', async ({page,context}) => { | |
const oidcEventQueue = await monitorOidcManagerEvents(page); | |
const oidcEventLoginEvent = await waitForOidcManagerEvent(page, (e) => | |
e?.detail?.error?.includes?.('login_required') | |
); | |
await page.goto('https://www.redhat.com/en'); | |
expect(await oidcEventLoginEvent.promise).toBeTruthy(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment