From 830853c0e8c029ec6d3ce4a6af756b578db2be95 Mon Sep 17 00:00:00 2001 From: thc202 Date: Mon, 1 Jun 2026 09:02:10 +0100 Subject: [PATCH] Report textarea and select These elements are also of interest for crawler/scanner. Signed-off-by: thc202 --- CHANGELOG.md | 4 ++ source/ContentScript/index.ts | 6 +++ source/types/ReportedModel.ts | 14 ++++++ test/ContentScript/integrationTests.test.ts | 53 +++++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4587a..6998a3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to the full browser extension will be documented in this fil The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## Umreleased +### Added +- Report `textarea` and `select` elements. + ## 0.1.9 - 2026-05-15 ### Added diff --git a/source/ContentScript/index.ts b/source/ContentScript/index.ts index 7734640..c01a374 100644 --- a/source/ContentScript/index.ts +++ b/source/ContentScript/index.ts @@ -193,6 +193,8 @@ function reportPointerElements( const url = window.location.href; if ( tagName !== 'input' && + tagName !== 'textarea' && + tagName !== 'select' && tagName !== 'button' && tagName !== 'a' && element instanceof Element @@ -217,6 +219,8 @@ function reportPageLoaded( reportPageLinks(doc, fn); reportPageForms(doc, fn); reportElements(doc.getElementsByTagName('input'), fn); + reportElements(doc.getElementsByTagName('textarea'), fn); + reportElements(doc.getElementsByTagName('select'), fn); reportElements(doc.getElementsByTagName('button'), fn); reportPointerElements(doc, fn); reportStorage(LOCAL_STORAGE, localStorage, fn); @@ -235,6 +239,8 @@ const domMutated = function domMutation( for (const mutation of mutationList) { if (mutation.type === 'childList') { reportNodeElements(mutation.target, 'input', reportObject); + reportNodeElements(mutation.target, 'textarea', reportObject); + reportNodeElements(mutation.target, 'select', reportObject); reportNodeElements(mutation.target, 'button', reportObject); if (mutation.target.nodeType === Node.ELEMENT_NODE) { reportPointerElements(mutation.target as Element, reportObject); diff --git a/source/types/ReportedModel.ts b/source/types/ReportedModel.ts index 3b5baa2..ea25fb8 100644 --- a/source/types/ReportedModel.ts +++ b/source/types/ReportedModel.ts @@ -125,6 +125,20 @@ class ReportedElement extends ReportedObject { // This will not work if form tags are not used this.formId = Array.prototype.slice.call(document.forms).indexOf(form); } + } else if (element.tagName === 'TEXTAREA') { + const textarea: HTMLTextAreaElement = element as HTMLTextAreaElement; + this.text = textarea.value; + const {form} = textarea; + if (form) { + this.formId = Array.prototype.slice.call(document.forms).indexOf(form); + } + } else if (element.tagName === 'SELECT') { + const select: HTMLSelectElement = element as HTMLSelectElement; + this.text = select.value; + const {form} = select; + if (form) { + this.formId = Array.prototype.slice.call(document.forms).indexOf(form); + } } else if (element.hasAttribute('href')) { this.href = element.getAttribute('href'); } diff --git a/test/ContentScript/integrationTests.test.ts b/test/ContentScript/integrationTests.test.ts index d11dbc0..1b7c263 100644 --- a/test/ContentScript/integrationTests.test.ts +++ b/test/ContentScript/integrationTests.test.ts @@ -1070,6 +1070,59 @@ function integrationTests( ]); }); + test('Should report textarea', async () => { + // Given + await enableZapEvents(server, driver); + const wd = await driver.getWebDriver(); + // When + await wd.get(`http://localhost:${_HTTPPORT}/webpages/interactions.html`); + await eventsProcessed(); + // Then + expect(actualData).toContainEqual( + reportObject( + 'nodeAdded', + 'TEXTAREA', + 'textarea-1', + 'TEXTAREA', + `http://localhost:${_HTTPPORT}/webpages/interactions.html`, + undefined, + 'Existing text' + ) + ); + }); + + test('Should report select', async () => { + // Given + await enableZapEvents(server, driver); + const wd = await driver.getWebDriver(); + // When + await wd.get(`http://localhost:${_HTTPPORT}/webpages/interactions.html`); + await eventsProcessed(); + // Then + expect(actualData).toContainEqual( + reportObject( + 'nodeAdded', + 'SELECT', + 'cars', + 'SELECT', + `http://localhost:${_HTTPPORT}/webpages/interactions.html`, + undefined, + 'volvo' + ) + ); + expect(actualData).toContainEqual( + reportObject( + 'nodeAdded', + 'SELECT', + 'longlist', + 'SELECT', + `http://localhost:${_HTTPPORT}/webpages/interactions.html`, + undefined, + 'v01' + ) + ); + }); + test('Should use className for input with stable unique class', async () => { // Given / When await driver.toggleRecording();