diff --git a/eslint.config.mjs b/eslint.config.js similarity index 100% rename from eslint.config.mjs rename to eslint.config.js diff --git a/logging.js b/logging.js index 688ac44..867bff4 100644 --- a/logging.js +++ b/logging.js @@ -16,7 +16,8 @@ export class ServerLogger { this._batchSize = batchSize; this._batchTime = batchTime; this._logs = []; - window.addEventListener('unload', this._onUnload.bind(this)); + this._onPageHide = this._onPageHide.bind(this); + window.addEventListener('pagehide', this._onPageHide); } logBatch(logs) { @@ -36,6 +37,11 @@ export class ServerLogger { } } + _disconnectForTesting() { + window.removeEventListener('pagehide', this._onPageHide); + clearTimeout(this._batchTimeout); + } + async _log(logs) { let options = { method: 'POST', @@ -58,19 +64,17 @@ export class ServerLogger { } } - async _onUnload() { + async _onPageHide() { clearTimeout(this._batchTimeout); - if (!this._loggerPromise && !navigator || !navigator.sendBeacon) { + if (!this._loggerPromise || !navigator?.sendBeacon || this._logs.length === 0) { return; } - if (this._logs.length > 0) { - try { - const logger = await this._loggerPromise; - const data = JSON.stringify(this._logs); - navigator.sendBeacon(logger.Endpoint, data); - } catch (err) { - console.error(err, this._logs); - } + try { + const logger = await this._loggerPromise; + const data = JSON.stringify(this._logs); + navigator.sendBeacon(logger.Endpoint, data); + } catch (err) { + console.error(err, this._logs); } } diff --git a/package.json b/package.json index df25ca3..66c19ed 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "access": "public" }, "main": "index.js", + "type": "module", "scripts": { "lint": "npm run lint:eslint", "lint:eslint": "eslint .", @@ -16,7 +17,6 @@ "author": "D2L Corporation", "license": "Apache-2.0", "devDependencies": { - "@babel/core": "^7", "@brightspace-ui/testing": "^1", "eslint": "^9", "eslint-config-brightspace": "^2", diff --git a/test/logging.test.js b/test/logging.test.js index d28959b..e25c8ce 100644 --- a/test/logging.test.js +++ b/test/logging.test.js @@ -697,7 +697,10 @@ describe('logging', () => { consoleErrorStub = stub(console, 'error'); }); - afterEach(() => restore()); + afterEach(() => { + restore(); + logger._disconnectForTesting(); + }); describe('batching', () => { @@ -862,30 +865,45 @@ describe('logging', () => { }); - describe('unload', () => { + describe('pagehide', () => { let beaconStub; - beforeEach(() => { beaconStub = stub(navigator, 'sendBeacon'); }); afterEach(() => restore()); - it('should send remaining logs as beacon on unload', async() => { - + it('should send remaining logs as beacon when "pagehide" event is triggered', async() => { logger.logBatch([{ message: '1' }, { message: '2' }]); - window.dispatchEvent(new Event('unload')); + window.dispatchEvent(new Event('pagehide')); await aTimeout(0); - expect(beaconStub).to.have.been.calledOnce; + expect(beaconStub.calledOnce).to.be.true; const [endpoint, data] = beaconStub.getCall(0).args; expect(endpoint).to.equal('/test/endpoint/0'); expect(data).to.equal(JSON.stringify([{ message: '1' }, { message: '2' }])); }); + it('should not send anything as beacon if no logs have ever been sent', async() => { + window.dispatchEvent(new Event('pagehide')); + await aTimeout(0); + + expect(beaconStub.called).to.be.false; + }); + + it('should not send anything as beacon if there are no logs', async() => { + logger.logBatch([{ message: '1' }]); + await aTimeout(batchTime); + + window.dispatchEvent(new Event('pagehide')); + await aTimeout(0); + + expect(beaconStub.called).to.be.false; + }); + }); });