Skip to content

Conversation

@tyiuhc
Copy link
Collaborator

@tyiuhc tyiuhc commented Dec 18, 2025

Summary

Implement user_interaction page trigger, which fires when the user either:

  1. click on an element
  2. focus on an element
  3. hovers over an element (for optional minThresholdMs)

Checklist

  • Does your PR title have the correct title format?
  • Does your PR have a breaking change?: No

@macroscopeapp
Copy link

macroscopeapp bot commented Dec 18, 2025

Add user_interaction trigger to publish click, hover (with minThresholdMs), and focus events via MessageBus and activate pages in SubscriptionManager

Introduce user_interaction payloads and trigger handling, add listener lifecycle and URL reset logic, and evaluate activation from fired interaction keys in packages/experiment-tag/src/subscriptions.ts and packages/experiment-tag/src/message-bus.ts.

📍Where to Start

Start with SubscriptionManager.setupUserInteractionPublisher in packages/experiment-tag/src/subscriptions.ts, then review setupUserInteractionListenersForSelector and the user_interaction case in isPageObjectActive.


Macroscope summarized 2a3cff7.

@promptless
Copy link

promptless bot commented Dec 18, 2025

📝 Documentation updates detected!

Updated existing suggestion: Document new page trigger types for Web Experiment

@tyiuhc tyiuhc requested a review from a team December 19, 2025 00:23

if (!success) {
// Invalid selector or elements don't exist yet - wait for element_appeared
this.messageBus.subscribe('element_appeared', () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate subscribers and DOM listeners are being added. Consider making registration idempotent: keep a registry keyed by selector + interactionType (include minThresholdMs for hover) so listeners attach once, and store unsubscribe handles to prevent accumulating element_appeared subscriptions across URL changes.

🚀 Reply to ask Macroscope to explain or update this suggestion.

👍 Helpful? React to give us feedback.

minThresholdMs?: number,
): boolean => {
try {
const elements = this.globalScope.document.querySelectorAll(selector);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would fail if an element matching the selector is added to the DOM later, it won't have listeners attached. I'd suggest istead of attaching listeners to each element, attach one listener to document and check if the event target matches the selector:

Comment on lines +441 to +459
} else if (event.type === 'mouseleave') {
if (interactionStartTime !== null) {
const interactionDuration = Date.now() - interactionStartTime;
if (
!minThresholdMs ||
interactionDuration >= minThresholdMs
) {
const interactionKey = `${selector}:${interactionType}:${
minThresholdMs || 0
}`;
this.firedUserInteractions.add(interactionKey);
this.messageBus.publish('user_interaction', {
selector,
interactionType,
});
}
interactionStartTime = null;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would mean hover won't trigger until mouseleave event is fired.

}
});

return true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always returns true even if elements.length is 0

private setupUserInteractionListenersForSelector = (
selector: string,
interactionType: 'click' | 'hover' | 'focus',
minThresholdMs?: number,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minThresholdMs is meant to be used for all interactionTypes and not just for hover.

minThresholdMs for click event can be interpreted in multiple ways (delayed trigger after click, click + linger, long click), so let's put a hold on to it for now .

For focus, it should be handled similarly to how hover is determined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants