Skip to content

Commit 55428b4

Browse files
committed
Ignore events on hidden elements
Signed-off-by: Simon Bennetts <[email protected]>
1 parent bb04471 commit 55428b4

File tree

5 files changed

+90
-1
lines changed

5 files changed

+90
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ All notable changes to the full browser extension will be documented in this fil
33

44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
55

6+
## Unreleased
7+
8+
### Fixed
9+
- Ignore events on non-visible elements, which will fail on replay.
10+
611
## 0.1.7 - 2025-11-28
712

813
### Added

CHANGELOG.rec.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ All notable changes to the recorder browser extension will be documented in this
33

44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
55

6+
## Unreleased
7+
8+
### Fixed
9+
- Ignore events on non-visible elements, which will fail on replay.
10+
611
## 0.1.7 - 2025-11-28
712

813
### Added

source/ContentScript/recorder.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,37 @@ class Recorder {
396396
});
397397
}
398398

399+
isVisible(el: HTMLElement): boolean {
400+
const style = window.getComputedStyle(el);
401+
402+
if (
403+
style.display === 'none' ||
404+
style.visibility === 'hidden' ||
405+
style.opacity === '0'
406+
) {
407+
return false;
408+
}
409+
410+
// Check layout dimensions
411+
if (el.offsetWidth <= 0 && el.offsetHeight <= 0) {
412+
return false;
413+
}
414+
415+
const rect = el.getBoundingClientRect();
416+
417+
// Check rendered size
418+
if (rect.width === 0 || rect.height === 0) {
419+
return false;
420+
}
421+
422+
// The element is rendered and visible in layout (may still be off-screen)
423+
return true;
424+
}
425+
399426
shouldRecord(element: HTMLElement): boolean {
400427
if (!this.active) return this.active;
401428
if (element.className === ZAP_FLOATING_DIV_ELEMENTS) return false;
402-
return true;
429+
return this.isVisible(element);
403430
}
404431

405432
getBrowserName(): string {

test/ContentScript/integrationTests.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,29 @@ function integrationTests(
673673
]);
674674
});
675675

676+
test('Should not record interactions on hidden element', async () => {
677+
// Given / When
678+
await driver.toggleRecording();
679+
const wd = await driver.getWebDriver();
680+
await wd.get(`http://localhost:${_HTTPPORT}/webpages/hiddenElement.html`);
681+
await eventsProcessed();
682+
await wd.findElement(By.id('visibleButton')).click();
683+
await eventsProcessed();
684+
// Then
685+
expect(actualData).toEqual([
686+
reportZestStatementComment(),
687+
reportZestStatementLaunch(
688+
'http://localhost:1801/webpages/hiddenElement.html'
689+
),
690+
reportZestStatementScrollTo(3, 'visibleButton'),
691+
reportZestStatementClick(4, 'visibleButton'),
692+
reportZestStatementScrollTo(5, 'visibleCheckBox'),
693+
reportZestStatementClick(6, 'visibleCheckBox'),
694+
reportZestStatementScrollTo(7, 'visibleCheckBox'),
695+
reportZestStatementSendKeys(8, 'visibleCheckBox', 'on', 'id'),
696+
]);
697+
});
698+
676699
test('Should record set localStorage', async () => {
677700
// Given
678701
await enableZapEvents(server, driver);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Hidden Element Event Demo</title>
6+
</head>
7+
<body>
8+
9+
<button id="visibleButton">Click Me</button>
10+
11+
<input id="visibleCheckBox" type="checkbox">
12+
13+
<input id="hiddenCheckBoxDisplay" type="checkbox" style="display:none">
14+
15+
<input id="hiddenCheckBoxVisibility" type="checkbox" style="visibility:hidden">
16+
17+
<input id="hiddenCheckBoxOpacity" type="checkbox" style="opacity:0">
18+
19+
<script>
20+
document.getElementById("visibleButton").addEventListener("click", () => {
21+
document.getElementById("visibleCheckBox").click();
22+
document.getElementById("hiddenCheckBoxDisplay").click();
23+
document.getElementById("hiddenCheckBoxVisibility").click();
24+
document.getElementById("hiddenCheckBoxOpacity").click();
25+
});
26+
</script>
27+
28+
</body>
29+
</html>

0 commit comments

Comments
 (0)