Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
db517f8
rename all packages for mixpanel distribution
jakewski Aug 8, 2025
085ed07
update references
jakewski Aug 8, 2025
f0b4bbd
Merge pull request #1 from mixpanel/jg-mixpanel-prep
jakewski Aug 13, 2025
86162a9
mixpanel release changes
jakewski Aug 14, 2025
0e38da5
fix test ref
jakewski Sep 26, 2025
c68ae04
re-implement fix for hidden input (#4)
jakewski Sep 29, 2025
f3e3789
bump mixpanel version
jakewski Sep 29, 2025
1035618
fix changesets
jakewski Sep 29, 2025
8f06cc0
SRFE-8790 include cleanups for mutation observers and stylesheets
dhaval-valotia Feb 3, 2026
2a586e5
Trigger CI
dhaval-valotia Feb 4, 2026
21a9de0
Apply formatting changes
dhaval-valotia Feb 4, 2026
9d6d2f6
add tests
dhaval-valotia Feb 4, 2026
4951d99
Merge branch 'drv-sr-memory-leaks' of https://github.com/mixpanel/rrw…
dhaval-valotia Feb 4, 2026
21ff38f
Address pr comments
dhaval-valotia Feb 10, 2026
eebcd63
remove iframe handling in stylesheet manager
dhaval-valotia Feb 17, 2026
f60139c
Merge pull request #8 from mixpanel/drv-sr-memory-leaks
dhaval-valotia Feb 19, 2026
66223ba
Apply formatting changes
dhaval-valotia Feb 19, 2026
3010641
bump mixpanel version
dhaval-valotia Feb 19, 2026
758e97f
Merge branch 'mixpanel-release' of https://github.com/mixpanel/rrweb …
dhaval-valotia Feb 19, 2026
dad07de
Add cross origin support
dhaval-valotia Feb 27, 2026
efa288a
Apply formatting changes
dhaval-valotia Feb 27, 2026
f97aa16
update tests
dhaval-valotia Mar 2, 2026
dfeeb60
Ignore media interactions if not a supported media element during rep…
dhaval-valotia Mar 4, 2026
01e8c29
Apply formatting changes
dhaval-valotia Mar 4, 2026
23d0e1f
SRFE-8790 cleanup child nodes recursively
dhaval-valotia Mar 10, 2026
1079fe7
Rename to allowedIframOrigin and fallback to *
dhaval-valotia Mar 12, 2026
42c8574
Apply formatting changes
dhaval-valotia Mar 12, 2026
fea6fa4
Remove check on parent side
dhaval-valotia Mar 16, 2026
2c0e6ee
Merge pull request #9 from mixpanel/drv-sr-cross-origin
dhaval-valotia Mar 16, 2026
37dbfa1
Merge pull request #12 from mixpanel/drv-sr-cleanup
dhaval-valotia Mar 16, 2026
83c697e
Merge pull request #10 from mixpanel/drv-sr-fix-replayer
dhaval-valotia Mar 16, 2026
0b3f24c
Bump mixpanel version
dhaval-valotia Mar 16, 2026
54985bf
MULTI-656 add null check
dhaval-valotia Jun 22, 2026
19a53b7
update yaml
dhaval-valotia Jun 29, 2026
189e528
MULTI-656 fix ci
dhaval-valotia Jun 29, 2026
77509a2
Merge pull request #17 from mixpanel/drv-ci-pin-actions
dhaval-valotia Jun 29, 2026
a538de8
Merge remote-tracking branch 'origin/mixpanel-release' into multi-656
dhaval-valotia Jun 29, 2026
52ffd37
re-trigger ci
dhaval-valotia Jul 7, 2026
df60c04
re-trigger ci
dhaval-valotia Jul 7, 2026
f369f2c
Merge pull request #16 from mixpanel/multi-656
dhaval-valotia Jul 7, 2026
d2eddb2
incr version
dhaval-valotia Jul 7, 2026
a10319d
fix: mask placeholder attributes when input masking is enabled
Jul 27, 2026
642d3f4
fix: update cross-origin iframe test snapshots for placeholder attrib…
Jul 27, 2026
9403faf
ci: pin GitHub Actions to full-length commit SHAs
Jul 27, 2026
de931bb
Merge branch 'mixpanel-release' into fix/mask-placeholder-attributes
carlosdanieltt Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,19 @@ function serializeElementNode(
attributes.checked = checked;
}
}
if (
(tagName === 'input' || tagName === 'textarea') &&
attributes.placeholder
) {
attributes.placeholder = maskInputValue({
element: n,
type: getInputType(n),
tagName,
value: attributes.placeholder as string,
maskInputOptions,
maskInputFn,
});
}
if (tagName === 'option') {
if ((n as HTMLOptionElement).selected && !maskInputOptions['select']) {
attributes.selected = true;
Expand Down
2 changes: 1 addition & 1 deletion packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ export default class MutationBuffer {
let attributeName = m.attributeName as string;
let value = (m.target as HTMLElement).getAttribute(attributeName);

if (attributeName === 'value') {
if (attributeName === 'value' || attributeName === 'placeholder') {
const type = getInputType(target);

value = maskInputValue({
Expand Down
30 changes: 20 additions & 10 deletions packages/rrweb/test/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,8 @@ exports[`record integration tests > can record form interactions 1`] = `
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
\\"type\\": \\"text\\"
\\"type\\": \\"text\\",
\\"placeholder\\": \\"Enter your email\\"
},
\\"childNodes\\": [],
\\"id\\": 22
Expand Down Expand Up @@ -2806,7 +2807,8 @@ exports[`record integration tests > can record form interactions 1`] = `
\\"id\\": \\"\\",
\\"cols\\": \\"30\\",
\\"rows\\": \\"10\\",
\\"data-unmask-example\\": \\"true\\"
\\"data-unmask-example\\": \\"true\\",
\\"placeholder\\": \\"Tell us about yourself\\"
},
\\"childNodes\\": [],
\\"id\\": 42
Expand Down Expand Up @@ -4649,7 +4651,8 @@ exports[`record integration tests > can use maskInputOptions to configure which
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
\\"type\\": \\"text\\"
\\"type\\": \\"text\\",
\\"placeholder\\": \\"Enter your email\\"
},
\\"childNodes\\": [],
\\"id\\": 22
Expand Down Expand Up @@ -4790,7 +4793,8 @@ exports[`record integration tests > can use maskInputOptions to configure which
\\"id\\": \\"\\",
\\"cols\\": \\"30\\",
\\"rows\\": \\"10\\",
\\"data-unmask-example\\": \\"true\\"
\\"data-unmask-example\\": \\"true\\",
\\"placeholder\\": \\"Tell us about yourself\\"
},
\\"childNodes\\": [],
\\"id\\": 42
Expand Down Expand Up @@ -6477,7 +6481,8 @@ exports[`record integration tests > should mask inputs via function call 1`] = `
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
\\"type\\": \\"text\\"
\\"type\\": \\"text\\",
\\"placeholder\\": \\"****************\\"
},
\\"childNodes\\": [],
\\"id\\": 22
Expand Down Expand Up @@ -6618,7 +6623,8 @@ exports[`record integration tests > should mask inputs via function call 1`] = `
\\"id\\": \\"\\",
\\"cols\\": \\"30\\",
\\"rows\\": \\"10\\",
\\"data-unmask-example\\": \\"true\\"
\\"data-unmask-example\\": \\"true\\",
\\"placeholder\\": \\"Tell us about yourself\\"
},
\\"childNodes\\": [],
\\"id\\": 42
Expand Down Expand Up @@ -10305,7 +10311,8 @@ exports[`record integration tests > should not record input values if maskAllInp
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
\\"type\\": \\"text\\"
\\"type\\": \\"text\\",
\\"placeholder\\": \\"****************\\"
},
\\"childNodes\\": [],
\\"id\\": 22
Expand Down Expand Up @@ -10446,7 +10453,8 @@ exports[`record integration tests > should not record input values if maskAllInp
\\"id\\": \\"\\",
\\"cols\\": \\"30\\",
\\"rows\\": \\"10\\",
\\"data-unmask-example\\": \\"true\\"
\\"data-unmask-example\\": \\"true\\",
\\"placeholder\\": \\"**********************\\"
},
\\"childNodes\\": [],
\\"id\\": 42
Expand Down Expand Up @@ -13418,7 +13426,8 @@ exports[`record integration tests > should record input userTriggered values if
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
\\"type\\": \\"text\\"
\\"type\\": \\"text\\",
\\"placeholder\\": \\"Enter your email\\"
},
\\"childNodes\\": [],
\\"id\\": 22
Expand Down Expand Up @@ -13559,7 +13568,8 @@ exports[`record integration tests > should record input userTriggered values if
\\"id\\": \\"\\",
\\"cols\\": \\"30\\",
\\"rows\\": \\"10\\",
\\"data-unmask-example\\": \\"true\\"
\\"data-unmask-example\\": \\"true\\",
\\"placeholder\\": \\"Tell us about yourself\\"
},
\\"childNodes\\": [],
\\"id\\": 42
Expand Down
4 changes: 2 additions & 2 deletions packages/rrweb/test/html/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<body>
<form>
<label for="text">
<input type="text" />
<input type="text" placeholder="Enter your email" />
</label>
<label>
<input type="radio" name="toggle" value="on" />
Expand All @@ -22,7 +22,7 @@
<input type="checkbox" />
</label>
<label for="textarea">
<textarea name="" id="" cols="30" rows="10" data-unmask-example="true"></textarea>
<textarea name="" id="" cols="30" rows="10" data-unmask-example="true" placeholder="Tell us about yourself"></textarea>
</label>
<label for="select">
<select name="" id="">
Expand Down
44 changes: 43 additions & 1 deletion packages/rrweb/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import {
ISuite,
} from './utils';
import type { recordOptions } from '../src/types';
import { eventWithTime, NodeType, EventType } from '@rrweb/types';
import {
eventWithTime,
NodeType,
EventType,
serializedNodeWithId,
} from '@rrweb/types';
import { visitSnapshot } from 'rrweb-snapshot';

describe('record integration tests', function (this: ISuite) {
Expand Down Expand Up @@ -617,6 +622,43 @@ describe('record integration tests', function (this: ISuite) {
await assertSnapshot(snapshots);
});

it('should mask placeholder values if maskAllInputs is enabled', async () => {
const page: puppeteer.Page = await browser.newPage();
await page.goto('about:blank');
await page.setContent(
getHtml.call(this, 'form.html', { maskAllInputs: true }),
);

const snapshots = (await page.evaluate(
'window.snapshots',
)) as eventWithTime[];

const fullSnapshot = snapshots.find(
(s) => s.type === EventType.FullSnapshot,
);
expect(fullSnapshot).toBeDefined();

let foundMaskedPlaceholder = false;
visitSnapshot(
(fullSnapshot as eventWithTime & { data: { node: serializedNodeWithId } })
.data.node,
(node) => {
if (
node.type === NodeType.Element &&
(node.tagName === 'input' || node.tagName === 'textarea') &&
node.attributes.placeholder
) {
const placeholder = node.attributes.placeholder as string;
expect(placeholder).not.toContain('Enter your email');
expect(placeholder).not.toContain('Tell us about yourself');
expect(placeholder).toMatch(/^\*+$/);
foundMaskedPlaceholder = true;
}
},
);
expect(foundMaskedPlaceholder).toBe(true);
});

it('should record input userTriggered values if userTriggeredOnInput is enabled', async () => {
const page: puppeteer.Page = await browser.newPage();
await page.goto('about:blank');
Expand Down