feat(plugin): add window popup plugin to record popup events#1900
Open
smeng9 wants to merge 13 commits into
Open
feat(plugin): add window popup plugin to record popup events#1900smeng9 wants to merge 13 commits into
smeng9 wants to merge 13 commits into
Conversation
Design for a plugin pair that captures native window.alert/confirm/prompt dialogs (message, prompt default, user response) and surfaces them on replay via a callback, mirroring the console/network plugins. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Native window.alert/confirm/prompt dialogs are browser chrome outside the
DOM, so rrweb never captured them. This adds a plugin pair mirroring the
console/network plugins:
- @rrweb/rrweb-plugin-dialog-record patches alert/confirm/prompt via
@rrweb/utils' patch(), calling through to the real (blocking) dialog
first so it can capture the user's response, then emitting a
'rrweb/dialog@1' plugin event with { kind, message, defaultValue?,
returnValue? }. Options: level, recordReturnValue, maskDialog.
- @rrweb/rrweb-plugin-dialog-replay filters those events and surfaces
each dialog to an onDialog callback (callback-only, since re-showing a
blocking native dialog would freeze the replayer).
Covered by unit tests (mock-window observer pattern); both packages
type-check and build.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename @rrweb/rrweb-plugin-dialog-record/replay to
@rrweb/rrweb-plugin-popup-record/replay, including the shared plugin
identifier ('rrweb/dialog@1' -> 'rrweb/popup@1') and all exported
symbols (getRecordPopupPlugin, getReplayPopupPlugin, PopupData,
PopupKind, PopupRecordOptions, PopupReplayOptions, onPopup, maskPopup).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop `?? {}` from the factory to match the network plugin's style;
normalize undefined options inside the observer instead, and type the
factory return as RecordPlugin (as network does) so options may be
undefined.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`level` was a meaningless carry-over from the console plugin (where it denotes log severity). Here the option holds a PopupKind[] (alert / confirm / prompt), so `kinds` names it accurately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
recordReturnValue was redundant: dropping the response is just a special case of masking. Remove it, always capture returnValue, and rename maskPopup -> maskPopupData. Users redact or drop the return value via the mask hook; documented with an example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rewrite both popup plugin READMEs to the standard rrweb plugin format (pointer to the recipe + guide, followed by the shared sponsors/team block), matching rrweb-plugin-console-record and rrweb-plugin-network-record. Move the usage/options docs into docs/recipes/popup.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The patched popup's receiver is always the recorded window, so apply to `win` directly and use an arrow function instead of capturing the caller's `this`. Removes the `this: unknown` annotation and is slightly more robust (correct Window receiver even inside iframes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IWindow (= Window & typeof globalThis) already satisfies patch()'s
{ [key: string]: any } source parameter, as network-record does with
patch(win, 'fetch', ...). Pass win directly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iate
options is undefined at runtime when the plugin is created with no args
(getRecordPopupPlugin() -> factory passes options: options). Type the
observer param as optional and read via optional chaining instead of the
`options || {}` intermediate, so the signature is honest and the direct
access is safe.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Design is finalized and implemented; the point-in-time spec (with its pre-rename dialog naming) is no longer needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 189d2a6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Record
window.alert/window.confirm/window.promptevents as part of UI interaction