From e4fa7fa05c2e11b03adc3f72648baef0a4980d0f Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Sun, 25 Oct 2020 01:23:47 +0200 Subject: [PATCH] refactor: Distinct server for each test allowing parallel runs (#42) * refactor: start tserver for each test * perf: run tests in parallel * docs: comments --- package.json | 2 +- src/tests/client.ts | 59 ++++++---- src/tests/fixtures/simple.ts | 107 ++++++++++++------ src/tests/server.ts | 206 ++++++++++++++++------------------- 4 files changed, 213 insertions(+), 161 deletions(-) diff --git a/package.json b/package.json index 889b06aa..f000d1f9 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "gendocs": "typedoc --options typedoc.js src/", "lint": "eslint 'src'", "type-check": "tsc --noEmit", - "test": "jest -i", + "test": "jest", "build": "tsc -b tsconfig.build.json", "release": "semantic-release" }, diff --git a/src/tests/client.ts b/src/tests/client.ts index 5eadedb8..adac6053 100644 --- a/src/tests/client.ts +++ b/src/tests/client.ts @@ -4,33 +4,22 @@ import WebSocket from 'ws'; import { EventEmitter } from 'events'; -import { url, startTServer, TServer } from './fixtures/simple'; +import { startTServer } from './fixtures/simple'; import { createClient, Client, EventListener } from '../client'; import { SubscribePayload } from '../message'; +// simulate browser environment for easier client testing +beforeEach(() => { + Object.assign(global, { + WebSocket: WebSocket, + }); +}); + // Just does nothing function noop(): void { /**/ } -let server: TServer, forgottenDispose: TServer['dispose'] | undefined; -beforeEach(async () => { - Object.assign(global, { WebSocket: WebSocket }); - const { dispose, ...rest } = await startTServer(); - forgottenDispose = dispose; - server = { - ...rest, - dispose: (beNice) => - dispose(beNice).then(() => (forgottenDispose = undefined)), - }; -}); -afterEach(async () => { - if (forgottenDispose) { - await forgottenDispose(); - forgottenDispose = undefined; - } -}); - interface TSubscribe { waitForNext: (test?: (value: T) => void, expire?: number) => Promise; waitForError: ( @@ -134,6 +123,8 @@ function tsubscribe( */ it('should use the provided WebSocket implementation', async () => { + const { url, ...server } = await startTServer(); + Object.assign(global, { WebSocket: null, }); @@ -148,6 +139,8 @@ it('should use the provided WebSocket implementation', async () => { }); it('should not accept invalid WebSocket implementations', async () => { + const { url } = await startTServer(); + Object.assign(global, { WebSocket: null, }); @@ -163,6 +156,8 @@ it('should not accept invalid WebSocket implementations', async () => { describe('query operation', () => { it('should execute the query, "next" the result and then complete', async () => { + const { url } = await startTServer(); + const client = createClient({ url }); const sub = tsubscribe(client, { @@ -179,6 +174,8 @@ describe('query operation', () => { describe('subscription operation', () => { it('should execute and "next" the emitted results until disposed', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url }); const sub = tsubscribe(client, { @@ -208,6 +205,8 @@ describe('subscription operation', () => { }); it('should emit results to correct distinct sinks', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url }); const sub1 = tsubscribe(client, { @@ -263,6 +262,8 @@ describe('subscription operation', () => { }); it('should use the provided `generateID` for subscription IDs', async () => { + const { url, ...server } = await startTServer(); + const generateIDFn = jest.fn(() => 'not unique'); const client = createClient({ url, generateID: generateIDFn }); @@ -276,6 +277,8 @@ describe('subscription operation', () => { }); it('should dispose of the subscription on complete', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url }); const sub = tsubscribe(client, { @@ -290,6 +293,8 @@ describe('subscription operation', () => { }); it('should dispose of the subscription on error', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url }); const sub = tsubscribe(client, { @@ -306,6 +311,8 @@ describe('subscription operation', () => { describe('"concurrency"', () => { it('should dispatch and receive messages even if one subscriber disposes while another one subscribes', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url, retryAttempts: 0 }); const sub1 = tsubscribe(client, { @@ -336,6 +343,8 @@ describe('"concurrency"', () => { describe('lazy', () => { it('should connect immediately when mode is disabled', async () => { + const { url, ...server } = await startTServer(); + createClient({ url, lazy: false, @@ -345,6 +354,8 @@ describe('lazy', () => { }); it('should close socket when disposing while mode is disabled', async () => { + const { url, ...server } = await startTServer(); + // wait for connected const client = await new Promise((resolve) => { const client = createClient({ @@ -363,6 +374,8 @@ describe('lazy', () => { }); it('should connect on first subscribe when mode is enabled', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url, lazy: true, // default @@ -388,6 +401,8 @@ describe('lazy', () => { }); it('should disconnect on last unsubscribe when mode is enabled', async () => { + const { url, ...server } = await startTServer(); + const client = createClient({ url, lazy: true, // default @@ -427,6 +442,8 @@ describe('lazy', () => { describe('reconnecting', () => { it('should not reconnect if retry attempts is zero', async () => { + const { url, ...server } = await startTServer(); + createClient({ url, lazy: false, @@ -444,6 +461,8 @@ describe('reconnecting', () => { }); it('should reconnect silently after socket closes', async () => { + const { url, ...server } = await startTServer(); + createClient({ url, lazy: false, @@ -473,6 +492,8 @@ describe('reconnecting', () => { describe('events', () => { it('should emit to relevant listeners with expected arguments', async () => { + const { url, ...server } = await startTServer(); + const connectingFn = jest.fn(noop as EventListener<'connecting'>); const connectedFn = jest.fn(noop as EventListener<'connected'>); const closedFn = jest.fn(noop as EventListener<'closed'>); diff --git a/src/tests/fixtures/simple.ts b/src/tests/fixtures/simple.ts index fe1c7d6a..68ecf18b 100644 --- a/src/tests/fixtures/simple.ts +++ b/src/tests/fixtures/simple.ts @@ -12,6 +12,33 @@ import net from 'net'; import http from 'http'; import { createServer, ServerOptions, Server } from '../../server'; +// distinct server for each test; if you forget to dispose, the fixture wont +const leftovers: Dispose[] = []; +afterEach(async () => { + while (leftovers.length > 0) { + // if not disposed by test, cleanup + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const dispose = leftovers.pop()!; + await dispose(); + } +}); + +export interface TServer { + url: string; + server: Server; + clients: Set; + pong: (key?: string) => void; + waitForClient: ( + test?: (client: WebSocket) => void, + expire?: number, + ) => Promise; + waitForOperation: (test?: () => void, expire?: number) => Promise; + waitForClientClose: (test?: () => void, expire?: number) => Promise; + dispose: Dispose; +} + +type Dispose = (beNice?: boolean) => Promise; + // use for dispatching a `pong` to the `ping` subscription const pendingPongs: Record = {}; const pongListeners: Record void) | undefined> = {}; @@ -87,28 +114,16 @@ export const schema = new GraphQLSchema({ }), }); -export interface TServer { - server: Server; - clients: Set; - pong: (key?: string) => void; - waitForClient: ( - test?: (client: WebSocket) => void, - expire?: number, - ) => Promise; - waitForOperation: (test?: () => void, expire?: number) => Promise; - waitForClientClose: (test?: () => void, expire?: number) => Promise; - dispose: (beNice?: boolean) => Promise; -} - -export const port = 8273, - path = '/graphql-simple', - url = `ws://localhost:${port}${path}`; +// test server finds an open port starting the search from this one +const startPort = 8765; export async function startTServer( options: Partial = {}, ): Promise { + const path = '/simple'; const emitter = new EventEmitter(); + // prepare http server const httpServer = http.createServer((_req, res) => { res.writeHead(404); res.end(); @@ -121,6 +136,7 @@ export async function startTServer( httpServer.once('close', () => sockets.delete(socket)); }); + // create server and hook up for tracking operations let pendingOperations = 0; const server = await createServer( { @@ -146,7 +162,28 @@ export async function startTServer( }, ); - await new Promise((resolve) => httpServer.listen(port, resolve)); + // search for open port from the starting port + let port = startPort; + for (;;) { + try { + await new Promise((resolve, reject) => { + httpServer.once('error', reject); + httpServer.once('listening', resolve); + httpServer.listen(port); + }); + break; // listening + } catch (err) { + if ('code' in err && err.code === 'EADDRINUSE') { + port++; + if (port - startPort > 256) { + throw new Error(`Cant find open port, stopping search on ${port}`); + } + continue; // try another one if this port is in use + } else { + throw err; // throw all other errors immediately + } + } + } // pending websocket clients let pendingCloses = 0; @@ -159,7 +196,28 @@ export async function startTServer( }); }); + // disposes of all started servers + const dispose: Dispose = (beNice) => { + return new Promise((resolve, reject) => { + if (!beNice) { + for (const socket of sockets) { + socket.destroy(); + sockets.delete(socket); + } + } + const disposing = server.dispose() as Promise; + disposing.catch(reject).then(() => { + httpServer.close(() => { + leftovers.splice(leftovers.indexOf(dispose), 1); + resolve(); + }); + }); + }); + }; + leftovers.push(dispose); + return { + url: `ws://localhost:${port}${path}`, server, get clients() { return server.webSocketServer.clients; @@ -224,19 +282,6 @@ export async function startTServer( } }); }, - dispose(beNice) { - return new Promise((resolve, reject) => { - if (!beNice) { - for (const socket of sockets) { - socket.destroy(); - sockets.delete(socket); - } - } - const disposing = server.dispose() as Promise; - disposing.catch(reject).then(() => { - httpServer.close(() => resolve()); - }); - }); - }, + dispose, }; } diff --git a/src/tests/server.ts b/src/tests/server.ts index 50237be6..633dd25d 100644 --- a/src/tests/server.ts +++ b/src/tests/server.ts @@ -14,29 +14,10 @@ import { stringifyMessage, SubscribePayload, } from '../message'; -import { startTServer, TServer, url, schema } from './fixtures/simple'; - -let forgottenDispose: TServer['dispose'] | undefined; -async function makeServer( - ...args: Parameters -): Promise { - const { dispose, ...rest } = await startTServer(...args); - forgottenDispose = dispose; - return { - ...rest, - dispose: (beNice) => - dispose(beNice).then(() => (forgottenDispose = undefined)), - }; -} -afterEach(async () => { - if (forgottenDispose) { - // if not disposed by test, cleanup - await forgottenDispose(); - forgottenDispose = undefined; - } -}); +import { schema, startTServer } from './fixtures/simple'; function createTClient( + url: string, protocols: string | string[] = GRAPHQL_TRANSPORT_WS_PROTOCOL, ) { let closeEvent: WebSocket.CloseEvent; @@ -112,30 +93,33 @@ function createTClient( */ it('should allow connections with valid protocols only', async () => { - await makeServer(); + const { url } = await startTServer(); - let client = await createTClient(''); + let client = await createTClient(url, ''); await client.waitForClose((event) => { expect(event.code).toBe(1002); expect(event.reason).toBe('Protocol Error'); expect(event.wasClean).toBeTruthy(); }); - client = await createTClient(['graphql', 'json']); + client = await createTClient(url, ['graphql', 'json']); await client.waitForClose((event) => { expect(event.code).toBe(1002); expect(event.reason).toBe('Protocol Error'); expect(event.wasClean).toBeTruthy(); }); - client = await createTClient(GRAPHQL_TRANSPORT_WS_PROTOCOL + 'gibberish'); + client = await createTClient( + url, + GRAPHQL_TRANSPORT_WS_PROTOCOL + 'gibberish', + ); await client.waitForClose((event) => { expect(event.code).toBe(1002); expect(event.reason).toBe('Protocol Error'); expect(event.wasClean).toBeTruthy(); }); - client = await createTClient(GRAPHQL_TRANSPORT_WS_PROTOCOL); + client = await createTClient(url, GRAPHQL_TRANSPORT_WS_PROTOCOL); await client.waitForClose( () => fail('shouldnt close for valid protocol'), 30, // should be kicked off within this time @@ -143,10 +127,10 @@ it('should allow connections with valid protocols only', async () => { }); it('should gracefully go away when disposing', async () => { - const server = await makeServer(); + const server = await startTServer(); - const client1 = await createTClient(); - const client2 = await createTClient(); + const client1 = await createTClient(server.url); + const client2 = await createTClient(server.url); await server.dispose(true); @@ -164,10 +148,11 @@ it('should gracefully go away when disposing', async () => { it('should report server errors to clients by closing the connection', async () => { const { + url, server: { webSocketServer }, - } = await makeServer(); + } = await startTServer(); - const client = await createTClient(); + const client = await createTClient(url); const emittedError = new Error("I'm a teapot"); webSocketServer.emit('error', emittedError); @@ -202,12 +187,12 @@ it('should use the provided roots as resolvers', async () => { }, }; - await makeServer({ + const { url } = await startTServer({ schema, roots, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -272,13 +257,13 @@ it('should pass in the context value from the config', async () => { const executeFn = jest.fn((args) => execute(args)); const subscribeFn = jest.fn((args) => subscribe(args)); - await makeServer({ + const { url } = await startTServer({ context, execute: executeFn, subscribe: subscribeFn, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -335,13 +320,13 @@ it('should pass in the context value from the config', async () => { describe('Connect', () => { it('should refuse connection and close socket if returning `false`', async () => { - await makeServer({ + const { url } = await startTServer({ onConnect: () => { return false; }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -359,13 +344,13 @@ describe('Connect', () => { it('should close socket with error thrown from the callback', async () => { const error = new Error("I'm a teapot"); - await makeServer({ + const { url } = await startTServer({ onConnect: () => { throw error; }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -380,8 +365,8 @@ describe('Connect', () => { }); it('should acknowledge connection if not implemented, returning `true` or nothing', async () => { - async function test() { - const client = await createTClient(); + async function test(url: string) { + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -393,26 +378,26 @@ describe('Connect', () => { } // no implementation - let server = await makeServer(); - await test(); + let server = await startTServer(); + await test(server.url); await server.dispose(); // returns true - server = await makeServer({ + server = await startTServer({ onConnect: () => { return true; }, }); - await test(); + await test(server.url); await server.dispose(); // returns nothing - await makeServer({ + server = await startTServer({ onConnect: () => { /**/ }, }); - await test(); + await test(server.url); }); it('should pass in the `connectionParams` through the context and have other flags correctly set', async (done) => { @@ -422,7 +407,7 @@ describe('Connect', () => { number: 10, }; - await makeServer({ + const { url } = await startTServer({ onConnect: (ctx) => { expect(ctx.connectionParams).toEqual(connectionParams); expect(ctx.connectionInitReceived).toBeTruthy(); // obviously received @@ -432,7 +417,7 @@ describe('Connect', () => { }, }); - (await createTClient()).ws.send( + (await createTClient(url)).ws.send( stringifyMessage({ type: MessageType.ConnectionInit, payload: connectionParams, @@ -441,9 +426,9 @@ describe('Connect', () => { }); it('should close the socket after the `connectionInitWaitTimeout` has passed without having received a `ConnectionInit` message', async () => { - await makeServer({ connectionInitWaitTimeout: 10 }); + const { url } = await startTServer({ connectionInitWaitTimeout: 10 }); - await (await createTClient()).waitForClose((event) => { + await (await createTClient(url)).waitForClose((event) => { expect(event.code).toBe(4408); expect(event.reason).toBe('Connection initialisation timeout'); expect(event.wasClean).toBeTruthy(); @@ -451,13 +436,13 @@ describe('Connect', () => { }); it('should not close the socket after the `connectionInitWaitTimeout` has passed but the callback is still resolving', async () => { - await makeServer({ + const { url } = await startTServer({ connectionInitWaitTimeout: 10, onConnect: () => new Promise((resolve) => setTimeout(() => resolve(true), 20)), }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -474,13 +459,13 @@ describe('Connect', () => { }); it('should close the socket if an additional `ConnectionInit` message is received while one is pending', async () => { - await makeServer({ + const { url } = await startTServer({ connectionInitWaitTimeout: 10, onConnect: () => new Promise((resolve) => setTimeout(() => resolve(true), 50)), }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -505,9 +490,9 @@ describe('Connect', () => { }); it('should close the socket if more than one `ConnectionInit` message is received at any given time', async () => { - await makeServer(); + const { url } = await startTServer(); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -535,9 +520,9 @@ describe('Connect', () => { describe('Subscribe', () => { it('should close the socket on request if connection is not acknowledged', async () => { - await makeServer(); + const { url } = await startTServer(); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -559,11 +544,11 @@ describe('Subscribe', () => { }); it('should close the socket on request if schema is left undefined', async () => { - await makeServer({ + const { url } = await startTServer({ schema: undefined, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -599,12 +584,12 @@ describe('Subscribe', () => { const error = new Error('Stop'); // onConnect - let server = await makeServer({ + let server = await startTServer({ onConnect: () => { throw error; }, }); - const client = await createTClient(); + const client = await createTClient(server.url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -618,11 +603,12 @@ describe('Subscribe', () => { await server.dispose(); async function test( + url: string, payload: SubscribePayload = { query: `query { getValue }`, }, ) { - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -648,65 +634,65 @@ describe('Subscribe', () => { } // onSubscribe - server = await makeServer({ + server = await startTServer({ onSubscribe: () => { throw error; }, }); - await test(); + await test(server.url); await server.dispose(); - server = await makeServer({ + server = await startTServer({ onOperation: () => { throw error; }, }); - await test(); + await test(server.url); await server.dispose(); // execute - server = await makeServer({ + server = await startTServer({ execute: () => { throw error; }, }); - await test(); + await test(server.url); await server.dispose(); // subscribe - server = await makeServer({ + server = await startTServer({ subscribe: () => { throw error; }, }); - await test({ query: 'subscription { greetings }' }); + await test(server.url, { query: 'subscription { greetings }' }); await server.dispose(); // onNext - server = await makeServer({ + server = await startTServer({ onNext: () => { throw error; }, }); - await test(); + await test(server.url); await server.dispose(); // onError - server = await makeServer({ + server = await startTServer({ onError: () => { throw error; }, }); - await test({ query: 'query { noExisto }' }); + await test(server.url, { query: 'query { noExisto }' }); await server.dispose(); // onComplete - server = await makeServer({ + server = await startTServer({ onComplete: () => { throw error; }, }); - await test(); + await test(server.url); await server.dispose(); }); @@ -716,7 +702,7 @@ describe('Subscribe', () => { operationName: 'Nope', document: parse(`query Nope { getValue }`), }; - await makeServer({ + const { url } = await startTServer({ schema: undefined, execute: (args) => { expect(args).toBe(nopeArgs); @@ -727,7 +713,7 @@ describe('Subscribe', () => { }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -768,13 +754,13 @@ describe('Subscribe', () => { }); it('should report the graphql errors returned from `onSubscribe`', async () => { - await makeServer({ + const { url } = await startTServer({ onSubscribe: (_ctx, _message) => { return [new GraphQLError('Report'), new GraphQLError('Me')]; }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -815,7 +801,7 @@ describe('Subscribe', () => { }); it('should use the execution result returned from `onNext`', async () => { - await makeServer({ + const { url } = await startTServer({ onNext: (_ctx, _message) => { return { data: { hey: 'there' }, @@ -823,7 +809,7 @@ describe('Subscribe', () => { }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -871,13 +857,13 @@ describe('Subscribe', () => { }); it('should use the graphql errors returned from `onError`', async () => { - await makeServer({ + const { url } = await startTServer({ onError: (_ctx, _message) => { return [new GraphQLError('Itsa me!'), new GraphQLError('Anda me!')]; }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -917,7 +903,7 @@ describe('Subscribe', () => { }); it('should use the operation result returned from `onOperation`', async () => { - await makeServer({ + const { url } = await startTServer({ onOperation: (_ctx, _message) => { return (async function* () { for (let i = 0; i < 3; i++) { @@ -927,7 +913,7 @@ describe('Subscribe', () => { }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ @@ -969,11 +955,11 @@ describe('Subscribe', () => { }); it('should execute the query of `string` type, "next" the result and then "complete"', async () => { - await makeServer({ + const { url } = await startTServer({ schema, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1014,7 +1000,7 @@ describe('Subscribe', () => { }); it('should execute the live query, "next" multiple results and then "complete"', async () => { - await makeServer({ + const { url } = await startTServer({ schema, execute: async function* () { for (const value of ['Hi', 'Hello', 'Sup']) { @@ -1027,7 +1013,7 @@ describe('Subscribe', () => { }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1084,11 +1070,11 @@ describe('Subscribe', () => { }); it('should execute the query of `DocumentNode` type, "next" the result and then "complete"', async () => { - await makeServer({ + const { url } = await startTServer({ schema, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1129,11 +1115,11 @@ describe('Subscribe', () => { }); it('should execute the query and "error" out because of validation errors', async () => { - await makeServer({ + const { url } = await startTServer({ schema, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1191,11 +1177,11 @@ describe('Subscribe', () => { }); it('should execute the subscription and "next" the published payload', async () => { - await makeServer({ + const { url } = await startTServer({ schema, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1233,11 +1219,11 @@ describe('Subscribe', () => { }); it('should stop dispatching messages after completing a subscription', async () => { - const server = await makeServer({ + const server = await startTServer({ schema, }); - const client = await createTClient(); + const client = await createTClient(server.url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1293,9 +1279,9 @@ describe('Subscribe', () => { }); it('should close the socket on duplicate `subscription` operation subscriptions request', async () => { - await makeServer(); + const { url } = await startTServer(); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1341,7 +1327,7 @@ describe('Subscribe', () => { }, }; - await makeServer({ + const { url } = await startTServer({ onSubscribe: (_ctx, msg) => { // search using `SubscriptionPayload.query` as QueryID // check the client example below for better understanding @@ -1353,7 +1339,7 @@ describe('Subscribe', () => { }, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1385,11 +1371,11 @@ describe('Subscribe', () => { describe('Keep-Alive', () => { it('should dispatch pings after the timeout has passed', async (done) => { - await makeServer({ + const { url } = await startTServer({ keepAlive: 50, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1400,11 +1386,11 @@ describe('Keep-Alive', () => { }); it('should not dispatch pings if disabled with nullish timeout', async (done) => { - await makeServer({ + const { url } = await startTServer({ keepAlive: 0, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit, @@ -1417,11 +1403,11 @@ describe('Keep-Alive', () => { }); it('should terminate the socket if no pong is sent in response to a ping', async () => { - await makeServer({ + const { url } = await startTServer({ keepAlive: 50, }); - const client = await createTClient(); + const client = await createTClient(url); client.ws.send( stringifyMessage({ type: MessageType.ConnectionInit,