Click Tracking Test Suite

Comprehensive validation of ListenLayer SDK click tracking across all DOM structures, edge cases, and sidecar configurations.

How to Use This Page

This page tests all click tracking capabilities of the ListenLayer SDK. Each section tests a specific feature or edge case.

SDK Source: services/collect/tracker/src/auto/click.ts

Sections (15 Total)

1. Links 2. Buttons & Inputs 3. Downloads (40+ extensions) 4. Protocols (tel/mailto) 5. ARIA Roles 6. onclick Handlers 7. Nested Elements 8. Shadow DOM 9. Dynamic Elements 10. Debounce (300ms) 11. data-ll-* Attributes 12. Text/Class Extraction 13. Custom Click Rules 14. Modifier Keys 15. Edge Cases

2. Buttons & Input Elements

What's being tested: The SDK detects <button> elements and <input type="submit">.

Expected behavior:

SDK: isButton() checks tagName === 'BUTTON' || (tagName === 'INPUT' && type === 'submit')
ct: button, tag: button
ct: button, tag: button
ct: button, tag: button
ct: button, tag: button
ct: button, tag: input
NOT TRACKED (SDK limitation)
No event (disabled)
No event (disabled)
Known Limitation: <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.

3. Download Detection

What's being tested: Links to downloadable files are detected by file extension or download attribute.

Expected behavior:

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

SDK: DOWNLOAD_EXTENSIONS array, isDownloadLink(), getFileExtension()

Documents

📄 document.pdf
ct: download, dl: pdf
📝 document.docx
ct: download, dl: docx
📊 spreadsheet.xlsx
ct: download, dl: xlsx
📽️ slides.pptx
ct: download, dl: pptx
📋 data.csv
ct: download, dl: csv
📃 readme.txt
ct: download, dl: txt

Archives

📦 archive.zip
ct: download, dl: zip
📦 archive.rar
ct: download, dl: rar
📦 archive.7z
ct: download, dl: 7z
📦 archive.tar.gz
ct: download, dl: gz
💿 disc.iso
ct: download, dl: iso

Media Files

🎬 video.mp4
ct: download, dl: mp4
🎬 video.mov
ct: download, dl: mov
🎬 video.mkv
ct: download, dl: mkv
🎵 audio.mp3
ct: download, dl: mp3
🎵 audio.wav
ct: download, dl: wav
🎵 audio.flac
ct: download, dl: flac

Installers / Applications

💿 setup.exe
ct: download, dl: exe
💿 setup.msi
ct: download, dl: msi
🍎 app.dmg
ct: download, dl: dmg
🍎 app.pkg
ct: download, dl: pkg
🐧 app.deb
ct: download, dl: deb
🐧 app.rpm
ct: download, dl: rpm
🤖 app.apk
ct: download, dl: apk
📱 app.ipa
ct: download, dl: ipa

Download Attribute

⬇️ Generate Report
ct: download
⬇️ Export CSV
ct: download
file.xyz
ct: link (not download)
Download Item
ct: link (no extension)

4. Special Protocols (tel/mailto)

What's being tested: Links with tel: and mailto: protocols are classified separately from regular links.

Expected behavior:

SDK: isTelLink(), isMailtoLink() - check URL prefix
📞 +1-555-123-4567
ct: tel
📱 Call Us
ct: tel
✉️ contact@acmecorp.io
ct: mailto
📧 Contact Sales
ct: mailto
💬 Send SMS
ct: link (not special)
JS Link
ct: link

5. ARIA Roles

What's being tested: Non-semantic elements with ARIA roles are tracked as their semantic equivalents.

Expected behavior:

SDK: Checks element.getAttribute('role') for button/link/menuitem
Div as Button
ct: button
Span as Link
ct: link
ct: button
NO EVENT (role not supported)
Toggle
NO EVENT (role not supported)
Focusable Div
No event (no role)
Note: Only role="button", role="link", and role="menuitem" are tracked. Other interactive roles like tab, switch, checkbox are NOT tracked automatically.

6. onclick Handlers

What's being tested: Elements with onclick handlers are treated as buttons (clickable interactive elements).

Expected behavior:

SDK: Checks target.element.onclick || target.element.hasAttribute('onclick')
Inline Handler
ct: button
Empty onclick
ct: button
Programmatic
ct: button
Event Listener
NOT DETECTABLE
Limitation: Handlers added via addEventListener() cannot be detected by the SDK. Only onclick attribute and .onclick property are detectable.

7. Nested Elements

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:

SDK: Uses event.composedPath() and findInPath() to traverse up

Content Inside Links

Click the SPAN inside (not the text around it):
Before CLICK THIS SPAN After
ct: link, tag: a (finds parent link)
Click the SVG icon:
Link with SVG Icon
ct: link, tag: a (finds parent link)
Click the IMAGE inside:
Test Image Link with Image
ct: link, tag: a (finds parent link)

Content Inside Buttons

Click the inner SPAN:
ct: button, tag: button (finds parent button)
Click the SVG icon inside button:
ct: button, tag: button (finds parent button)

Deeply Nested (5 levels)

Level 1 (div)
Level 2 (div)
Level 3 (div)
Level 4 (div)
Click Me (Level 5 span)
ct: link, tag: a (traverses 5 levels up)

8. Shadow DOM

What's being tested: Click tracking works inside Shadow DOM using event.composedPath() which crosses shadow boundaries.

Expected behavior:

SDK: pathCrossesShadow() detects shadow boundary, composedPath() traverses it

Open Shadow DOM (mode: 'open')

ct: button, shadow: true
ct: link, shadow: true

Nested Shadow DOM

Card with nested shadow button inside
ct: button, shadow: true (nested)

Closed Shadow DOM (mode: 'closed')

CANNOT TRAVERSE (closed mode)
Limitation: Shadow DOM with mode: '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.

9. Dynamic Elements

What's being tested: Elements added to the DOM after page load are tracked via event delegation.

Expected behavior:

SDK: Event delegation on document with capture phase

Click buttons above to add elements, then click the new elements to verify tracking works.

10. Debounce Testing (300ms)

What's being tested: Rapid clicks on the same element are debounced to prevent duplicate events.

Expected behavior:

SDK: debounceMs: 300 default, compares lastClickTarget and lastClickTime
0
DOM clicks (actual): 0
With 300ms debounce, the SDK will emit fewer events than actual clicks.
How to verify: Enable SDK debug mode, click rapidly, and compare the actual click count above with the number of click events in the console/event log. SDK events should be fewer.

11. data-ll-* Attributes

What's being tested: Custom tracking data can be attached to elements via data-ll-* attributes.

Expected behavior:

SDK: extractLLDataFromPath() collects data-ll-* from composed path

Basic Tracking Attributes

ll: {click: 'signup-hero-cta'}
Pricing
ll: {click, source, position}
ll: {id: 'btn-123', campaign: '...'}

Click Type Override

Sign Up Link
ct: 'cta' (overridden from 'link')
ct: 'download' (overridden)
ct: 'button' (invalid ignored)
Valid override types: link, button, cta, download, tel, mailto, rule, other

Inheritance from Parent Elements

Parent: data-ll-section="hero" data-ll-experiment="pricing-v2"

Both buttons inherit section="hero" and experiment="pricing-v2"

Child Overrides Parent

Parent: data-ll-variant="control"

Each button has its own variant value, overriding parent's "control"

12. Text & Class Extraction

What's being tested: The SDK extracts element text content and CSS classes for event data.

Expected behavior:

SDK: getElementText() (max 100), getElementClasses() (max 5)

Text Content Extraction

txt: 'OK'
txt: 'Subscribe Now'
txt: 'This is an extremely long button text that exceeds one hundred characters and should be truncat...'
txt: 'Multiple Spaces Here'
txt: 'Line One Line Two'
txt: undefined

CSS Class Extraction

cls: ['primary-cta']
cls: ['btn', 'primary', 'large']
cls: ['btn','primary','lg','rounded','shadow']
cls: ['a','b','c','d','e'] (max 5)
cls: undefined

13. Custom Click Rules

What's being tested: Sidecar-configured CSS selector rules that match specific elements and emit ct: 'rule' with a rule ID.

Expected behavior:

⚠️ Requires sidecar configuration: These tests need matching rules in the account's sidecar settings to emit ct: 'rule'.

SDK: matchClickRule() iterates path and rules, uses element.matches(selector)

Simple Selectors

Rule: #nav-signuprule: 'nav-signup-btn'

Rule: .cta-primaryrule: 'primary-cta'

Rule: [data-action="subscribe"]rule: 'subscribe-btn'

Attribute Selectors

Rule: [href^="https://external"]rule: 'external-link'

External Link (prefix match)

Rule: [href$=".pdf"]rule: 'pdf-download'

📄 Report PDF (suffix match)

Rule: [href*="campaign"]rule: 'campaign-link'

Campaign Link (contains match)

Combined Selectors

Rule: .btn.primaryrule: 'primary-btn'

Rule: button.cta[data-size="large"]rule: 'large-cta'

Descendant/Child Selectors

Rule: nav#main-nav arule: 'main-nav-link'

Rule: .card-actions > button:first-childrule: 'card-primary-action'

Product Card

Pseudo Selectors

Rule: button:not(.disabled)rule: 'active-btn'

Rule: ul.menu li:nth-child(odd) arule: 'odd-menu-item'

Important: These elements will emit 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']" }
    ]
  }
}

14. Modifier Keys & Special Clicks

What's being tested: How the SDK handles clicks with modifier keys and different mouse buttons.

Expected behavior:

SDK: Uses standard click event (left button). Middle/right clicks may not fire click event.

Test with Modifier Keys

Normal Link
ct: link (standard)
New Tab Link
ct: link (opens new tab)
New Window Link
ct: link (opens new window)
External New Tab
ct: link, ext: true

Mouse Button Tests

ct: button
May not fire click event
Opens context menu, no click
How to test:

15. Edge Cases

What's being tested: Unusual or problematic DOM structures and link configurations.

Expected behavior varies - some may be tracked, others may have limitations.

Links Without href

Link without href
May not track (no href)
Empty href
ct: link (current page)
Space href
ct: link

Invalid/Unusual Structures

Both are clickable - complex
Both are clickable - complex
Outer Inner
Browser may flatten

Special URL Formats

Blob Link
ct: link
Data URL
ct: link
?foo=bar
ct: link, ext: false

CSS Pointer Events

Click passes through
Overlay receives click

autoTrack Configuration

Sidecar autoTrack settings: The SDK respects clicks.autoTrack configuration:

To test: modify sidecar settings and reload page. Elements with data-ll-* attributes or matching custom rules are ALWAYS tracked regardless of autoTrack settings.

Event Log

How to use: This panel shows click events captured by a hook. Enable SDK debug mode for full visibility.

  1. Open browser console
  2. Run: _ll.debug(true)
  3. Click elements on this page
  4. See events appear below (and in console)
Events captured: 0
Waiting for events... Click elements above after enabling debug mode.

Click Tracking Test Suite - ListenLayer SDK Testing

15 sections covering all click tracking scenarios

Home | Test Matrix | Back to Top