diff --git a/jest.config.js b/jest.config.js index e3070358..54b57b85 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,9 +2,6 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', setupFilesAfterEnv: ['./jest.setup.ts'], - collectCoverageFrom: [ - 'src/*.{js,jsx}', - '!**/node_modules/**', - '!**/vendor/**', - ], + testPathIgnorePatterns: ['node_modules/', '.history'], + collectCoverageFrom: ['src/*.{ts}', '!**/node_modules/**', '!**/vendor/**'], }; diff --git a/package-lock.json b/package-lock.json index 7f96a2a8..4dfb4494 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1595,9 +1595,9 @@ } }, "@types/node": { - "version": "12.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz", - "integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==", + "version": "14.0.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", + "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==", "dev": true }, "@types/normalize-package-data": { @@ -3006,6 +3006,12 @@ } } }, + "delay": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", + "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==", + "dev": true + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -9501,6 +9507,12 @@ "acorn": "^7.0.0" }, "dependencies": { + "@types/node": { + "version": "12.12.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.47.tgz", + "integrity": "sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A==", + "dev": true + }, "acorn": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", diff --git a/package.json b/package.json index 057eb53f..6484929e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,9 @@ "devDependencies": { "@types/jest": "26.0.0", "@types/puppeteer": "3.0.0", + "@types/node": "^14.0.13", "auto-changelog": "2.0.0", + "delay": "^4.3.0", "eslint": "7.2.0", "eslint-config-prettier": "6.11.0", "eslint-plugin-jest": "23.13.2", diff --git a/src/__tests__/index.test.js b/src/__tests__/index.test.ts similarity index 61% rename from src/__tests__/index.test.js rename to src/__tests__/index.test.ts index c6a628db..e5a23818 100644 --- a/src/__tests__/index.test.js +++ b/src/__tests__/index.test.ts @@ -1,17 +1,11 @@ -const PendingXHR = require('../index').PendingXHR; -const http = require('http'); -const puppeteer = require('puppeteer'); +import {PendingXHR} from '../index'; +import http from 'http'; +import delay from 'delay'; +import { launch, Browser } from 'puppeteer'; + const port = 8907; const xhrBackendPort = 8908; -function timeout(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} -async function sleep(delay) { - await timeout(delay); - return; -} - const OK_NO_XHR = ` OK_NO_XHR @@ -52,21 +46,21 @@ OK_WITH_1_SLOW_XHR `; -let request1Resolver; +let request1Resolver: Function; const request1Promise = () => { - return new Promise(resolve => { + return new Promise<[number, any]>(resolve => { request1Resolver = resolve; }); }; -let request2Resolver; +let request2Resolver: Function; const request2Promise = () => { - return new Promise(resolve => { + return new Promise<[number, any]>(resolve => { request2Resolver = resolve; }); }; -const backendRequestHandler = async (request, response) => { +const backendRequestHandler = async (request: http.IncomingMessage, response: http.ServerResponse) => { if (request.url === '/request1') { const [statusCode, body] = await request1Promise(); response.statusCode = statusCode; @@ -78,9 +72,9 @@ const backendRequestHandler = async (request, response) => { } }; -let server; -let backendServer; -let browser; +let server: http.Server; +let backendServer: http.Server; +let browser: Browser; describe('PendingXHR', () => { beforeAll(async () => { @@ -88,7 +82,7 @@ describe('PendingXHR', () => { if (process.env.CI) { args.push('--no-sandbox'); } - browser = await puppeteer.launch({ + browser = await launch({ headless: true, args, }); @@ -96,7 +90,7 @@ describe('PendingXHR', () => { beforeEach(async () => { backendServer = http.createServer(backendRequestHandler); - await backendServer.listen(xhrBackendPort); + backendServer = await backendServer.listen(xhrBackendPort); }); afterAll(async () => { @@ -117,7 +111,7 @@ describe('PendingXHR', () => { server.close(cb); }); - async function startServerReturning(html) { + async function startServerReturning(html: string) { server = http.createServer((request, response) => { response.statusCode = 200; response.end(html); @@ -142,18 +136,72 @@ describe('PendingXHR', () => { expect(pendingXHR.pendingXhrCount()).toEqual(2); setTimeout(() => { request1Resolver([200, 'first xhr finished']); - }); - await sleep(1000); + }, 0); + await delay(1000); expect(pendingXHR.pendingXhrCount()).toEqual(1); setTimeout(() => { request2Resolver([200, 'second xhr finished']); - }); - await sleep(1000); + }, 0); + await delay(1000); expect(pendingXHR.pendingXhrCount()).toEqual(0); }); }); + describe('waitOnceForAllXhrFinished', () => { + + it('returns and removes all listeners immediatly if no xhr pending', async () => { + await startServerReturning(OK_NO_XHR); + const page = await browser.newPage(); + const count = page.listenerCount('request'); + const pendingXHR = new PendingXHR(page); + await page.goto(`http://localhost:${port}/go`); + await pendingXHR.waitOnceForAllXhrFinished(); + expect(page.listenerCount('request')).toBe(count) + }); + + describe.skip('one XHR', () => { + it('resolves removes all listeners once finished', async () => { + await startServerReturning(OK_WITH_1_XHR); + const page = await browser.newPage(); + const count = page.listenerCount('request'); + const pendingXHR = new PendingXHR(page); + await page.goto(`http://localhost:${port}/go`); + expect(pendingXHR.pendingXhrCount()).toEqual(1); + await pendingXHR.waitOnceForAllXhrFinished(); + expect(pendingXHR.pendingXhrCount()).toEqual(0); + expect(page.listenerCount('request')).toBe(count) + }) + + }) + + describe.skip('several XHR', () => { + it('resolves removes all listeners once finished', async () => { + await startServerReturning(OK_WITH_2_XHR); + const page = await browser.newPage(); + const count = page.listenerCount('request'); + const pendingXHR = new PendingXHR(page); + await page.goto(`http://localhost:${port}/go`); + expect(pendingXHR.pendingXhrCount()).toEqual(2); + await pendingXHR.waitOnceForAllXhrFinished(); + expect(pendingXHR.pendingXhrCount()).toEqual(0); + expect(page.listenerCount('request')).toBe(count) + }) + }) + + + }) + describe('waitForAllXhrFinished', () => { + + it('let a listenner connected', async () => { + await startServerReturning(OK_NO_XHR); + const page = await browser.newPage(); + const count = page.listenerCount('request'); + const pendingXHR = new PendingXHR(page); + await page.goto(`http://localhost:${port}/go`); + await pendingXHR.waitForAllXhrFinished(); + expect(page.listenerCount('request')).toBe(count+1) + }) it('returns immediatly if no xhr pending count', async () => { await startServerReturning(OK_NO_XHR); const page = await browser.newPage(); @@ -170,11 +218,25 @@ describe('PendingXHR', () => { expect(pendingXHR.pendingXhrCount()).toEqual(1); setTimeout(() => { request1Resolver([200, '']); - }); + }, 0); await pendingXHR.waitForAllXhrFinished(); expect(pendingXHR.pendingXhrCount()).toEqual(0); }); + it('can be trigerred multiple times', async () => { + await startServerReturning(OK_WITH_1_XHR); + const page = await browser.newPage(); + const pendingXHR = new PendingXHR(page); + await page.goto(`http://localhost:${port}/go`); + expect(pendingXHR.pendingXhrCount()).toEqual(1); + setTimeout(() => { + request1Resolver([200, '']); + }, 0); + await pendingXHR.waitForAllXhrFinished(); + expect(pendingXHR.pendingXhrCount()).toEqual(0); + await pendingXHR.waitForAllXhrFinished(); + }); + it('works with Promise.race', async () => { await startServerReturning(OK_WITH_1_XHR); const page = await browser.newPage(); @@ -208,7 +270,7 @@ describe('PendingXHR', () => { expect(pendingXHR.pendingXhrCount()).toEqual(2); setTimeout(() => { request1Resolver([200, 'first xhr finished']); - }); + }, 0); setTimeout(() => { request2Resolver([200, 'second xhr finished']); }, 200); @@ -224,7 +286,7 @@ describe('PendingXHR', () => { expect(pendingXHR.pendingXhrCount()).toEqual(1); setTimeout(() => { request1Resolver([500, 'boom']); - }); + }, 0); await pendingXHR.waitForAllXhrFinished(); expect(pendingXHR.pendingXhrCount()).toEqual(0); });