From 7d11d7f33ecce50367777694172d01d22187314d Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 19 Dec 2024 11:16:43 +0100 Subject: [PATCH 1/3] Fixed type error accessing null object and added test case --- src/__tests__/heatmaps.test.ts | 21 +++++++++++++++++++++ src/utils/element-utils.ts | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/__tests__/heatmaps.test.ts b/src/__tests__/heatmaps.test.ts index cb8955261..7e3759964 100644 --- a/src/__tests__/heatmaps.test.ts +++ b/src/__tests__/heatmaps.test.ts @@ -89,6 +89,27 @@ describe('heatmaps', () => { expect(posthog.heatmaps!.getAndClearBuffer()).toBeDefined() }) + it('should handle empty mouse moves', async () => { + posthog.heatmaps?.['_onMouseMove']?.(new Event('mousemove')) + + jest.advanceTimersByTime(posthog.heatmaps!.flushIntervalMilliseconds + 1) + + expect(beforeSendMock).toBeCalledTimes(1) + expect(beforeSendMock.mock.lastCall[0]).toMatchObject({ + event: '$$heatmap', + properties: { + $heatmap_data: { + 'http://replaced/': [ + { + target_fixed: false, + type: 'mousemove', + }, + ], + }, + }, + }) + }) + it('should send rageclick events in the same area', async () => { posthog.heatmaps?.['_onClick']?.(createMockMouseEvent()) posthog.heatmaps?.['_onClick']?.(createMockMouseEvent()) diff --git a/src/utils/element-utils.ts b/src/utils/element-utils.ts index 5567cd696..664248328 100644 --- a/src/utils/element-utils.ts +++ b/src/utils/element-utils.ts @@ -1,8 +1,8 @@ import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants' -export function isElementInToolbar(el: Element): boolean { +export function isElementInToolbar(el: Element | null): boolean { // NOTE: .closest is not supported in IE11 hence the operator check - return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS) + return el?.id === TOOLBAR_ID || !!el?.closest?.('.' + TOOLBAR_CONTAINER_CLASS) } /* From 586f1fd94cad2967b2b4144877da8f84831ead7c Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 19 Dec 2024 12:00:52 +0100 Subject: [PATCH 2/3] Removed as, fixed types in isElementInToolbar --- src/heatmaps.ts | 2 +- src/utils/element-utils.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/heatmaps.ts b/src/heatmaps.ts index e1e69a270..8948fe0ab 100644 --- a/src/heatmaps.ts +++ b/src/heatmaps.ts @@ -177,7 +177,7 @@ export class Heatmaps { } private _onMouseMove(e: Event): void { - if (isElementInToolbar(e.target as Element)) { + if (isElementInToolbar(e.target)) { return } clearTimeout(this._mouseMoveTimeout) diff --git a/src/utils/element-utils.ts b/src/utils/element-utils.ts index 664248328..f784ff8aa 100644 --- a/src/utils/element-utils.ts +++ b/src/utils/element-utils.ts @@ -1,8 +1,11 @@ import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants' -export function isElementInToolbar(el: Element | null): boolean { - // NOTE: .closest is not supported in IE11 hence the operator check - return el?.id === TOOLBAR_ID || !!el?.closest?.('.' + TOOLBAR_CONTAINER_CLASS) +export function isElementInToolbar(el: EventTarget | null): boolean { + if (el instanceof Element) { + // NOTE: .closest is not supported in IE11 hence the operator check + return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS) + } + return false } /* From c1861f453d050bfe10f8c67e328f092c170433d5 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 19 Dec 2024 13:48:21 +0100 Subject: [PATCH 3/3] Fixed unit tests not using full objects --- src/__tests__/heatmaps.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/__tests__/heatmaps.test.ts b/src/__tests__/heatmaps.test.ts index 7e3759964..b8c08a4b8 100644 --- a/src/__tests__/heatmaps.test.ts +++ b/src/__tests__/heatmaps.test.ts @@ -144,16 +144,24 @@ describe('heatmaps', () => { }) it('should ignore clicks if they come from the toolbar', async () => { + const testElementToolbar = document.createElement('div') + testElementToolbar.id = '__POSTHOG_TOOLBAR__' + posthog.heatmaps?.['_onClick']?.( createMockMouseEvent({ - target: { id: '__POSTHOG_TOOLBAR__' } as Element, + target: testElementToolbar, }) ) expect(posthog.heatmaps?.['buffer']).toEqual(undefined) + const testElementClosest = document.createElement('div') + testElementClosest.closest = () => { + return {} + } + posthog.heatmaps?.['_onClick']?.( createMockMouseEvent({ - target: { closest: () => ({}) } as unknown as Element, + target: testElementClosest, }) ) expect(posthog.heatmaps?.['buffer']).toEqual(undefined)