Comprehensive validation of ListenLayer SDK click tracking across all DOM structures, edge cases, and sidecar configurations.
This page tests all click tracking capabilities of the ListenLayer SDK. Each section tests a specific feature or edge case.
_ll.debug(true) in browser console to see click events in real-timect: 'button')ct: 'rule' without matching rules configuredSDK Source: services/collect/tracker/src/auto/click.ts
What's being tested: The SDK detects <a> elements and classifies them as internal or external based on hostname comparison.
Expected behavior:
<a> tags emit ct: 'link'ext: true when hostname differs from current pageext: false for same-domain links and anchor linksdest contains the full href URLisAnchor(), isExternalLink() in click.tsWhat's being tested: The SDK detects <button> elements and <input type="submit">.
Expected behavior:
<button> (any type) → ct: 'button', tag: 'button'<input type="submit"> → ct: 'button', tag: 'input'<input type="button"> → NOT tracked by default (SDK only checks type="submit")isButton() checks tagName === 'BUTTON' || (tagName === 'INPUT' && type === 'submit')<input type="button"> is NOT detected as a button by the SDK. Only type="submit" inputs are tracked. This may be intentional (semantic difference) or a gap to fix.
What's being tested: Links to downloadable files are detected by file extension or download attribute.
Expected behavior:
ct: 'download', dl: '{extension}'download attribute → ct: 'download' regardless of extensionct: 'link' (not download)Supported extensions (40+): pdf, doc, docx, xls, xlsx, ppt, pptx, rtf, odt, ods, odp, epub, mobi, csv, txt, json, xml, zip, rar, 7z, tar, gz, bz2, xz, tgz, cab, iso, mp3, wav, flac, ogg, aac, m4a, mp4, avi, mov, wmv, mkv, webm, m4v, exe, dmg, pkg, deb, rpm, msi, apk, ipa, jar
DOWNLOAD_EXTENSIONS array, isDownloadLink(), getFileExtension()What's being tested: Links with tel: and mailto: protocols are classified separately from regular links.
Expected behavior:
tel:... → ct: 'tel' (no dest/ext fields)mailto:... → ct: 'mailto' (no dest/ext fields)ct: 'link'isTelLink(), isMailtoLink() - check URL prefixWhat's being tested: Non-semantic elements with ARIA roles are tracked as their semantic equivalents.
Expected behavior:
role="button" → ct: 'button'role="link" → ct: 'link'role="menuitem" → ct: 'button'element.getAttribute('role') for button/link/menuitemrole="button", role="link", and role="menuitem" are tracked. Other interactive roles like tab, switch, checkbox are NOT tracked automatically.
What's being tested: Elements with onclick handlers are treated as buttons (clickable interactive elements).
Expected behavior:
onclick="..." → ct: 'button'element.onclick = fn → ct: 'button'addEventListener('click', fn) → NOT detectable (no event)target.element.onclick || target.element.hasAttribute('onclick')addEventListener() cannot be detected by the SDK. Only onclick attribute and .onclick property are detectable.
What's being tested: When you click a child element (span, icon, img), the SDK traverses up the DOM to find the nearest link or button.
Expected behavior:
<a> element<a> elementevent.composedPath() and findInPath() to traverse upWhat's being tested: Click tracking works inside Shadow DOM using event.composedPath() which crosses shadow boundaries.
Expected behavior:
shadow: true flagpathCrossesShadow() detects shadow boundary, composedPath() traverses itmode: 'closed' cannot be traversed by composedPath(). The click event's path stops at the host element, so the SDK cannot see inside the shadow root.
What's being tested: Elements added to the DOM after page load are tracked via event delegation.
Expected behavior:
document.addEventListener('click', handler, { capture: true })Click buttons above to add elements, then click the new elements to verify tracking works.
What's being tested: Rapid clicks on the same element are debounced to prevent duplicate events.
Expected behavior:
debounceMs: 300 default, compares lastClickTarget and lastClickTimeWhat's being tested: Custom tracking data can be attached to elements via data-ll-* attributes.
Expected behavior:
data-ll-* attributes appear in the ll object of the eventdata-ll-click-type overrides the auto-detected click typeextractLLDataFromPath() collects data-ll-* from composed pathlink, button, cta, download, tel, mailto, rule, other
Parent: data-ll-section="hero" data-ll-experiment="pricing-v2"
Parent: data-ll-variant="control"
What's being tested: The SDK extracts element text content and CSS classes for event data.
Expected behavior:
txt: Text content, trimmed, whitespace normalized, max 100 chars (truncated with ...)cls: Array of class names, max 5 classesundefined (not sent)getElementText() (max 100), getElementClasses() (max 5)What's being tested: Sidecar-configured CSS selector rules that match specific elements and emit ct: 'rule' with a rule ID.
Expected behavior:
ct: 'rule', rule: '{rule-id}'element.matches(selector) on each element in composedPath⚠️ Requires sidecar configuration: These tests need matching rules in the account's sidecar settings to emit ct: 'rule'.
matchClickRule() iterates path and rules, uses element.matches(selector)Rule: #nav-signup → rule: 'nav-signup-btn'
Rule: .cta-primary → rule: 'primary-cta'
Rule: [data-action="subscribe"] → rule: 'subscribe-btn'
Rule: [href^="https://external"] → rule: 'external-link'
Rule: [href$=".pdf"] → rule: 'pdf-download'
Rule: [href*="campaign"] → rule: 'campaign-link'
Rule: .btn.primary → rule: 'primary-btn'
Rule: button.cta[data-size="large"] → rule: 'large-cta'
Rule: nav#main-nav a → rule: 'main-nav-link'
Rule: .card-actions > button:first-child → rule: 'card-primary-action'
Product Card
Rule: button:not(.disabled) → rule: 'active-btn'
Rule: ul.menu li:nth-child(odd) a → rule: 'odd-menu-item'
ct: 'link' or ct: 'button' unless your sidecar has matching rules configured. To see ct: 'rule', add rules like:
{
"clicks": {
"rules": [
{ "id": "nav-signup-btn", "selector": "#nav-signup" },
{ "id": "primary-cta", "selector": ".cta-primary" },
{ "id": "subscribe-btn", "selector": "[data-action='subscribe']" }
]
}
}
What's being tested: How the SDK handles clicks with modifier keys and different mouse buttons.
Expected behavior:
click event (left button). Middle/right clicks may not fire click event.What's being tested: Unusual or problematic DOM structures and link configurations.
Expected behavior varies - some may be tracked, others may have limitations.
clicks.autoTrack configuration:
links: false → Link clicks not auto-tracked (unless has data-ll-* or matches rule)buttons: false → Button clicks not auto-trackeddownloads: false → Download links not auto-trackedTo test: modify sidecar settings and reload page. Elements with data-ll-* attributes or matching custom rules are ALWAYS tracked regardless of autoTrack settings.
How to use: This panel shows click events captured by a hook. Enable SDK debug mode for full visibility.
_ll.debug(true)Click Tracking Test Suite - ListenLayer SDK Testing
15 sections covering all click tracking scenarios
Home | Test Matrix | Back to Top