From 07e7c490bed92482ba5d233ab5e771aadda38197 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Fri, 22 Nov 2024 19:20:07 +0100 Subject: [PATCH] Avoid timeouts when testing SSE subscriptions in browser (#3506) --- .../__integration-tests__/browser.spec.ts | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/packages/graphql-yoga/__integration-tests__/browser.spec.ts b/packages/graphql-yoga/__integration-tests__/browser.spec.ts index 37e4252aaf..5a376c410f 100644 --- a/packages/graphql-yoga/__integration-tests__/browser.spec.ts +++ b/packages/graphql-yoga/__integration-tests__/browser.spec.ts @@ -46,6 +46,10 @@ const fakeAsyncIterable = { }, }; +// will be registered inside `emitter` resolver +let emitToEmitter: ((val: string) => Promise) | null; +let stopEmitter: (() => void) | null; + export function createTestSchema() { let liveQueryCounter = 0; @@ -161,6 +165,18 @@ export function createTestSchema() { yield { eventEmitted: Date.now() }; }, }, + emitter: { + type: new GraphQLNonNull(GraphQLString), + subscribe() { + return new Repeater(async (push, stop) => { + emitToEmitter = val => push({ emitter: val }); + stopEmitter = stop; + await stop; + emitToEmitter = null; + stopEmitter = null; + }); + }, + }, count: { type: GraphQLInt, args: { @@ -171,7 +187,7 @@ export function createTestSchema() { async *subscribe(_root, args) { for (let count = 1; count <= args.to; count++) { yield { count }; - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise(resolve => setTimeout(resolve, 200)); } }, }, @@ -357,34 +373,32 @@ describe('browser', () => { test('execute SSE (subscription) operation', async () => { await page.goto(`http://localhost:${port}${endpoint}`); - await typeOperationText(`subscription { count(to: 2) }`); + await typeOperationText(`subscription { emitter }`); await page.click('.graphiql-execute-button'); - await setTimeout$(50); + // showing stop selector means subscription has started + await page.waitForSelector(stopButtonSelector); - const resultContents = await waitForResult(); - const isShowingStopButton = await page.evaluate(stopButtonSelector => { - return !!window.document.querySelector(stopButtonSelector); - }, stopButtonSelector); - expect(resultContents).toEqual({ + await emitToEmitter!('one'); + + await expect(waitForResult()).resolves.toEqual({ data: { - count: 1, + emitter: 'one', }, }); - expect(isShowingStopButton).toEqual(true); - await setTimeout$(300); + await emitToEmitter!('two'); - const resultContents1 = await waitForResult(); - const isShowingPlayButton = await page.evaluate(playButtonSelector => { - return !!window.document.querySelector(playButtonSelector); - }, playButtonSelector); - expect(resultContents1).toEqual({ + await expect(waitForResult()).resolves.toEqual({ data: { - count: 2, + emitter: 'two', }, }); - expect(isShowingPlayButton).toEqual(true); + + stopEmitter!(); + + // wait for subscription to end + await page.waitForSelector(playButtonSelector); }); test('show the query provided in the search param', async () => {