mask input options and sampling options (#252)
* part of #80, support mask input options * close #188 enhance sampling options Use a more general sampling strategy interface to describe the configuration of sampling events collection. Implemented mousmove, mouse interaction, scroll and input sampling strategy.
This commit is contained in:
@@ -62,7 +62,7 @@
|
|||||||
"@xstate/fsm": "^1.4.0",
|
"@xstate/fsm": "^1.4.0",
|
||||||
"mitt": "^1.1.3",
|
"mitt": "^1.1.3",
|
||||||
"pako": "^1.0.11",
|
"pako": "^1.0.11",
|
||||||
"rrweb-snapshot": "^0.7.27",
|
"rrweb-snapshot": "^0.8.0",
|
||||||
"smoothscroll-polyfill": "^0.4.3"
|
"smoothscroll-polyfill": "^0.4.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { snapshot } from 'rrweb-snapshot';
|
import { snapshot, MaskInputOptions } from 'rrweb-snapshot';
|
||||||
import initObservers from './observer';
|
import initObservers from './observer';
|
||||||
import {
|
import {
|
||||||
mirror,
|
mirror,
|
||||||
@@ -35,15 +35,44 @@ function record<T = eventWithTime>(
|
|||||||
blockClass = 'rr-block',
|
blockClass = 'rr-block',
|
||||||
ignoreClass = 'rr-ignore',
|
ignoreClass = 'rr-ignore',
|
||||||
inlineStylesheet = true,
|
inlineStylesheet = true,
|
||||||
maskAllInputs = false,
|
maskAllInputs,
|
||||||
|
maskInputOptions: _maskInputOptions,
|
||||||
hooks,
|
hooks,
|
||||||
mousemoveWait = 50,
|
|
||||||
packFn,
|
packFn,
|
||||||
|
sampling = {},
|
||||||
|
mousemoveWait,
|
||||||
} = options;
|
} = options;
|
||||||
// runtime checks for user options
|
// runtime checks for user options
|
||||||
if (!emit) {
|
if (!emit) {
|
||||||
throw new Error('emit function is required');
|
throw new Error('emit function is required');
|
||||||
}
|
}
|
||||||
|
// move departed options to new options
|
||||||
|
if (mousemoveWait !== undefined && sampling.mousemove === undefined) {
|
||||||
|
sampling.mousemove = mousemoveWait;
|
||||||
|
}
|
||||||
|
|
||||||
|
const maskInputOptions: MaskInputOptions =
|
||||||
|
maskAllInputs === true
|
||||||
|
? {
|
||||||
|
color: true,
|
||||||
|
date: true,
|
||||||
|
'datetime-local': true,
|
||||||
|
email: true,
|
||||||
|
month: true,
|
||||||
|
number: true,
|
||||||
|
range: true,
|
||||||
|
search: true,
|
||||||
|
tel: true,
|
||||||
|
text: true,
|
||||||
|
time: true,
|
||||||
|
url: true,
|
||||||
|
week: true,
|
||||||
|
textarea: true,
|
||||||
|
select: true,
|
||||||
|
}
|
||||||
|
: _maskInputOptions !== undefined
|
||||||
|
? _maskInputOptions
|
||||||
|
: {};
|
||||||
|
|
||||||
polyfill();
|
polyfill();
|
||||||
|
|
||||||
@@ -83,7 +112,7 @@ function record<T = eventWithTime>(
|
|||||||
document,
|
document,
|
||||||
blockClass,
|
blockClass,
|
||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskAllInputs,
|
maskInputOptions,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -217,9 +246,9 @@ function record<T = eventWithTime>(
|
|||||||
),
|
),
|
||||||
blockClass,
|
blockClass,
|
||||||
ignoreClass,
|
ignoreClass,
|
||||||
maskAllInputs,
|
maskInputOptions,
|
||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
mousemoveWait,
|
sampling,
|
||||||
},
|
},
|
||||||
hooks,
|
hooks,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { INode, serializeNodeWithId, transformAttribute } from 'rrweb-snapshot';
|
import {
|
||||||
|
INode,
|
||||||
|
serializeNodeWithId,
|
||||||
|
transformAttribute,
|
||||||
|
MaskInputOptions,
|
||||||
|
} from 'rrweb-snapshot';
|
||||||
import {
|
import {
|
||||||
mutationRecord,
|
mutationRecord,
|
||||||
blockClass,
|
blockClass,
|
||||||
@@ -50,17 +55,17 @@ export default class MutationBuffer {
|
|||||||
private emissionCallback: mutationCallBack;
|
private emissionCallback: mutationCallBack;
|
||||||
private blockClass: blockClass;
|
private blockClass: blockClass;
|
||||||
private inlineStylesheet: boolean;
|
private inlineStylesheet: boolean;
|
||||||
private maskAllInputs: boolean;
|
private maskInputOptions: MaskInputOptions;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
cb: mutationCallBack,
|
cb: mutationCallBack,
|
||||||
blockClass: blockClass,
|
blockClass: blockClass,
|
||||||
inlineStylesheet: boolean,
|
inlineStylesheet: boolean,
|
||||||
maskAllInputs: boolean,
|
maskInputOptions: MaskInputOptions,
|
||||||
) {
|
) {
|
||||||
this.blockClass = blockClass;
|
this.blockClass = blockClass;
|
||||||
this.inlineStylesheet = inlineStylesheet;
|
this.inlineStylesheet = inlineStylesheet;
|
||||||
this.maskAllInputs = maskAllInputs;
|
this.maskInputOptions = maskInputOptions;
|
||||||
this.emissionCallback = cb;
|
this.emissionCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +94,7 @@ export default class MutationBuffer {
|
|||||||
this.blockClass,
|
this.blockClass,
|
||||||
true,
|
true,
|
||||||
this.inlineStylesheet,
|
this.inlineStylesheet,
|
||||||
this.maskAllInputs,
|
this.maskInputOptions,
|
||||||
)!,
|
)!,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -130,6 +135,47 @@ export default class MutationBuffer {
|
|||||||
this.emit();
|
this.emit();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public emit = () => {
|
||||||
|
const payload = {
|
||||||
|
texts: this.texts
|
||||||
|
.map((text) => ({
|
||||||
|
id: mirror.getId(text.node as INode),
|
||||||
|
value: text.value,
|
||||||
|
}))
|
||||||
|
// text mutation's id was not in the mirror map means the target node has been removed
|
||||||
|
.filter((text) => mirror.has(text.id)),
|
||||||
|
attributes: this.attributes
|
||||||
|
.map((attribute) => ({
|
||||||
|
id: mirror.getId(attribute.node as INode),
|
||||||
|
attributes: attribute.attributes,
|
||||||
|
}))
|
||||||
|
// attribute mutation's id was not in the mirror map means the target node has been removed
|
||||||
|
.filter((attribute) => mirror.has(attribute.id)),
|
||||||
|
removes: this.removes,
|
||||||
|
adds: this.adds,
|
||||||
|
};
|
||||||
|
// payload may be empty if the mutations happened in some blocked elements
|
||||||
|
if (
|
||||||
|
!payload.texts.length &&
|
||||||
|
!payload.attributes.length &&
|
||||||
|
!payload.removes.length &&
|
||||||
|
!payload.adds.length
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emissionCallback(payload);
|
||||||
|
|
||||||
|
// reset
|
||||||
|
this.texts = [];
|
||||||
|
this.attributes = [];
|
||||||
|
this.removes = [];
|
||||||
|
this.adds = [];
|
||||||
|
this.addedSet = new Set<Node>();
|
||||||
|
this.movedSet = new Set<Node>();
|
||||||
|
this.droppedSet = new Set<Node>();
|
||||||
|
this.movedMap = {};
|
||||||
|
};
|
||||||
|
|
||||||
private processMutation = (m: mutationRecord) => {
|
private processMutation = (m: mutationRecord) => {
|
||||||
switch (m.type) {
|
switch (m.type) {
|
||||||
case 'characterData': {
|
case 'characterData': {
|
||||||
@@ -231,47 +277,6 @@ export default class MutationBuffer {
|
|||||||
}
|
}
|
||||||
n.childNodes.forEach((childN) => this.genAdds(childN));
|
n.childNodes.forEach((childN) => this.genAdds(childN));
|
||||||
};
|
};
|
||||||
|
|
||||||
public emit = () => {
|
|
||||||
const payload = {
|
|
||||||
texts: this.texts
|
|
||||||
.map((text) => ({
|
|
||||||
id: mirror.getId(text.node as INode),
|
|
||||||
value: text.value,
|
|
||||||
}))
|
|
||||||
// text mutation's id was not in the mirror map means the target node has been removed
|
|
||||||
.filter((text) => mirror.has(text.id)),
|
|
||||||
attributes: this.attributes
|
|
||||||
.map((attribute) => ({
|
|
||||||
id: mirror.getId(attribute.node as INode),
|
|
||||||
attributes: attribute.attributes,
|
|
||||||
}))
|
|
||||||
// attribute mutation's id was not in the mirror map means the target node has been removed
|
|
||||||
.filter((attribute) => mirror.has(attribute.id)),
|
|
||||||
removes: this.removes,
|
|
||||||
adds: this.adds,
|
|
||||||
};
|
|
||||||
// payload may be empty if the mutations happened in some blocked elements
|
|
||||||
if (
|
|
||||||
!payload.texts.length &&
|
|
||||||
!payload.attributes.length &&
|
|
||||||
!payload.removes.length &&
|
|
||||||
!payload.adds.length
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.emissionCallback(payload);
|
|
||||||
|
|
||||||
// reset
|
|
||||||
this.texts = [];
|
|
||||||
this.attributes = [];
|
|
||||||
this.removes = [];
|
|
||||||
this.adds = [];
|
|
||||||
this.addedSet = new Set<Node>();
|
|
||||||
this.movedSet = new Set<Node>();
|
|
||||||
this.droppedSet = new Set<Node>();
|
|
||||||
this.movedMap = {};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { INode } from 'rrweb-snapshot';
|
import { INode, MaskInputOptions } from 'rrweb-snapshot';
|
||||||
import {
|
import {
|
||||||
mirror,
|
mirror,
|
||||||
throttle,
|
throttle,
|
||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
Arguments,
|
Arguments,
|
||||||
mediaInteractionCallback,
|
mediaInteractionCallback,
|
||||||
MediaInteractions,
|
MediaInteractions,
|
||||||
|
SamplingStrategy,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import MutationBuffer from './mutation';
|
import MutationBuffer from './mutation';
|
||||||
|
|
||||||
@@ -36,14 +37,14 @@ function initMutationObserver(
|
|||||||
cb: mutationCallBack,
|
cb: mutationCallBack,
|
||||||
blockClass: blockClass,
|
blockClass: blockClass,
|
||||||
inlineStylesheet: boolean,
|
inlineStylesheet: boolean,
|
||||||
maskAllInputs: boolean,
|
maskInputOptions: MaskInputOptions,
|
||||||
): MutationObserver {
|
): MutationObserver {
|
||||||
// see mutation.ts for details
|
// see mutation.ts for details
|
||||||
const mutationBuffer = new MutationBuffer(
|
const mutationBuffer = new MutationBuffer(
|
||||||
cb,
|
cb,
|
||||||
blockClass,
|
blockClass,
|
||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskAllInputs,
|
maskInputOptions,
|
||||||
);
|
);
|
||||||
const observer = new MutationObserver(mutationBuffer.processMutations);
|
const observer = new MutationObserver(mutationBuffer.processMutations);
|
||||||
observer.observe(document, {
|
observer.observe(document, {
|
||||||
@@ -59,8 +60,15 @@ function initMutationObserver(
|
|||||||
|
|
||||||
function initMoveObserver(
|
function initMoveObserver(
|
||||||
cb: mousemoveCallBack,
|
cb: mousemoveCallBack,
|
||||||
mousemoveWait: number,
|
sampling: SamplingStrategy,
|
||||||
): listenerHandler {
|
): listenerHandler {
|
||||||
|
if (sampling.mousemove === false) {
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const threshold =
|
||||||
|
typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
|
||||||
|
|
||||||
let positions: mousePosition[] = [];
|
let positions: mousePosition[] = [];
|
||||||
let timeBaseline: number | null;
|
let timeBaseline: number | null;
|
||||||
const wrappedCb = throttle((isTouch: boolean) => {
|
const wrappedCb = throttle((isTouch: boolean) => {
|
||||||
@@ -92,7 +100,7 @@ function initMoveObserver(
|
|||||||
});
|
});
|
||||||
wrappedCb(isTouchEvent(evt));
|
wrappedCb(isTouchEvent(evt));
|
||||||
},
|
},
|
||||||
mousemoveWait,
|
threshold,
|
||||||
{
|
{
|
||||||
trailing: false,
|
trailing: false,
|
||||||
},
|
},
|
||||||
@@ -109,7 +117,17 @@ function initMoveObserver(
|
|||||||
function initMouseInteractionObserver(
|
function initMouseInteractionObserver(
|
||||||
cb: mouseInteractionCallBack,
|
cb: mouseInteractionCallBack,
|
||||||
blockClass: blockClass,
|
blockClass: blockClass,
|
||||||
|
sampling: SamplingStrategy,
|
||||||
): listenerHandler {
|
): listenerHandler {
|
||||||
|
if (sampling.mouseInteraction === false) {
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
const disableMap: Record<string, boolean | undefined> =
|
||||||
|
sampling.mouseInteraction === true ||
|
||||||
|
sampling.mouseInteraction === undefined
|
||||||
|
? {}
|
||||||
|
: sampling.mouseInteraction;
|
||||||
|
|
||||||
const handlers: listenerHandler[] = [];
|
const handlers: listenerHandler[] = [];
|
||||||
const getHandler = (eventKey: keyof typeof MouseInteractions) => {
|
const getHandler = (eventKey: keyof typeof MouseInteractions) => {
|
||||||
return (event: MouseEvent | TouchEvent) => {
|
return (event: MouseEvent | TouchEvent) => {
|
||||||
@@ -129,7 +147,12 @@ function initMouseInteractionObserver(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
Object.keys(MouseInteractions)
|
Object.keys(MouseInteractions)
|
||||||
.filter((key) => Number.isNaN(Number(key)) && !key.endsWith('_Departed'))
|
.filter(
|
||||||
|
(key) =>
|
||||||
|
Number.isNaN(Number(key)) &&
|
||||||
|
!key.endsWith('_Departed') &&
|
||||||
|
disableMap[key] !== false,
|
||||||
|
)
|
||||||
.forEach((eventKey: keyof typeof MouseInteractions) => {
|
.forEach((eventKey: keyof typeof MouseInteractions) => {
|
||||||
const eventName = eventKey.toLowerCase();
|
const eventName = eventKey.toLowerCase();
|
||||||
const handler = getHandler(eventKey);
|
const handler = getHandler(eventKey);
|
||||||
@@ -143,6 +166,7 @@ function initMouseInteractionObserver(
|
|||||||
function initScrollObserver(
|
function initScrollObserver(
|
||||||
cb: scrollCallback,
|
cb: scrollCallback,
|
||||||
blockClass: blockClass,
|
blockClass: blockClass,
|
||||||
|
sampling: SamplingStrategy,
|
||||||
): listenerHandler {
|
): listenerHandler {
|
||||||
const updatePosition = throttle<UIEvent>((evt) => {
|
const updatePosition = throttle<UIEvent>((evt) => {
|
||||||
if (!evt.target || isBlocked(evt.target as Node, blockClass)) {
|
if (!evt.target || isBlocked(evt.target as Node, blockClass)) {
|
||||||
@@ -163,7 +187,7 @@ function initScrollObserver(
|
|||||||
y: (evt.target as HTMLElement).scrollTop,
|
y: (evt.target as HTMLElement).scrollTop,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 100);
|
}, sampling.scroll || 100);
|
||||||
return on('scroll', updatePosition);
|
return on('scroll', updatePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,27 +206,13 @@ function initViewportResizeObserver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
|
export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
|
||||||
export const MASK_TYPES = [
|
|
||||||
'color',
|
|
||||||
'date',
|
|
||||||
'datetime-local',
|
|
||||||
'email',
|
|
||||||
'month',
|
|
||||||
'number',
|
|
||||||
'range',
|
|
||||||
'search',
|
|
||||||
'tel',
|
|
||||||
'text',
|
|
||||||
'time',
|
|
||||||
'url',
|
|
||||||
'week',
|
|
||||||
];
|
|
||||||
const lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();
|
const lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();
|
||||||
function initInputObserver(
|
function initInputObserver(
|
||||||
cb: inputCallback,
|
cb: inputCallback,
|
||||||
blockClass: blockClass,
|
blockClass: blockClass,
|
||||||
ignoreClass: string,
|
ignoreClass: string,
|
||||||
maskAllInputs: boolean,
|
maskInputOptions: MaskInputOptions,
|
||||||
|
sampling: SamplingStrategy,
|
||||||
): listenerHandler {
|
): listenerHandler {
|
||||||
function eventHandler(event: Event) {
|
function eventHandler(event: Event) {
|
||||||
const { target } = event;
|
const { target } = event;
|
||||||
@@ -223,11 +233,14 @@ function initInputObserver(
|
|||||||
}
|
}
|
||||||
let text = (target as HTMLInputElement).value;
|
let text = (target as HTMLInputElement).value;
|
||||||
let isChecked = false;
|
let isChecked = false;
|
||||||
const hasTextInput =
|
|
||||||
MASK_TYPES.includes(type) || (target as Element).tagName === 'TEXTAREA';
|
|
||||||
if (type === 'radio' || type === 'checkbox') {
|
if (type === 'radio' || type === 'checkbox') {
|
||||||
isChecked = (target as HTMLInputElement).checked;
|
isChecked = (target as HTMLInputElement).checked;
|
||||||
} else if (hasTextInput && maskAllInputs) {
|
} else if (
|
||||||
|
maskInputOptions[
|
||||||
|
(target as Element).tagName.toLowerCase() as keyof MaskInputOptions
|
||||||
|
] ||
|
||||||
|
maskInputOptions[type as keyof MaskInputOptions]
|
||||||
|
) {
|
||||||
text = '*'.repeat(text.length);
|
text = '*'.repeat(text.length);
|
||||||
}
|
}
|
||||||
cbWithDedup(target, { text, isChecked });
|
cbWithDedup(target, { text, isChecked });
|
||||||
@@ -262,10 +275,10 @@ function initInputObserver(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const handlers: Array<listenerHandler | hookResetter> = [
|
const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
|
||||||
'input',
|
const handlers: Array<
|
||||||
'change',
|
listenerHandler | hookResetter
|
||||||
].map((eventName) => on(eventName, eventHandler));
|
> = events.map((eventName) => on(eventName, eventHandler));
|
||||||
const propertyDescriptor = Object.getOwnPropertyDescriptor(
|
const propertyDescriptor = Object.getOwnPropertyDescriptor(
|
||||||
HTMLInputElement.prototype,
|
HTMLInputElement.prototype,
|
||||||
'value',
|
'value',
|
||||||
@@ -414,20 +427,26 @@ export default function initObservers(
|
|||||||
o.mutationCb,
|
o.mutationCb,
|
||||||
o.blockClass,
|
o.blockClass,
|
||||||
o.inlineStylesheet,
|
o.inlineStylesheet,
|
||||||
o.maskAllInputs,
|
o.maskInputOptions,
|
||||||
);
|
);
|
||||||
const mousemoveHandler = initMoveObserver(o.mousemoveCb, o.mousemoveWait);
|
const mousemoveHandler = initMoveObserver(o.mousemoveCb, o.sampling);
|
||||||
const mouseInteractionHandler = initMouseInteractionObserver(
|
const mouseInteractionHandler = initMouseInteractionObserver(
|
||||||
o.mouseInteractionCb,
|
o.mouseInteractionCb,
|
||||||
o.blockClass,
|
o.blockClass,
|
||||||
|
o.sampling,
|
||||||
|
);
|
||||||
|
const scrollHandler = initScrollObserver(
|
||||||
|
o.scrollCb,
|
||||||
|
o.blockClass,
|
||||||
|
o.sampling,
|
||||||
);
|
);
|
||||||
const scrollHandler = initScrollObserver(o.scrollCb, o.blockClass);
|
|
||||||
const viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb);
|
const viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb);
|
||||||
const inputHandler = initInputObserver(
|
const inputHandler = initInputObserver(
|
||||||
o.inputCb,
|
o.inputCb,
|
||||||
o.blockClass,
|
o.blockClass,
|
||||||
o.ignoreClass,
|
o.ignoreClass,
|
||||||
o.maskAllInputs,
|
o.maskInputOptions,
|
||||||
|
o.sampling,
|
||||||
);
|
);
|
||||||
const mediaInteractionHandler = initMediaInteractionObserver(
|
const mediaInteractionHandler = initMediaInteractionObserver(
|
||||||
o.mediaInteractionCb,
|
o.mediaInteractionCb,
|
||||||
|
|||||||
38
src/types.ts
38
src/types.ts
@@ -1,4 +1,9 @@
|
|||||||
import { serializedNodeWithId, idNodeMap, INode } from 'rrweb-snapshot';
|
import {
|
||||||
|
serializedNodeWithId,
|
||||||
|
idNodeMap,
|
||||||
|
INode,
|
||||||
|
MaskInputOptions,
|
||||||
|
} from 'rrweb-snapshot';
|
||||||
import { PackFn, UnpackFn } from './packer/base';
|
import { PackFn, UnpackFn } from './packer/base';
|
||||||
|
|
||||||
export enum EventType {
|
export enum EventType {
|
||||||
@@ -126,6 +131,28 @@ export type eventWithTime = event & {
|
|||||||
|
|
||||||
export type blockClass = string | RegExp;
|
export type blockClass = string | RegExp;
|
||||||
|
|
||||||
|
export type SamplingStrategy = Partial<{
|
||||||
|
/**
|
||||||
|
* false means not to record mouse/touch move events
|
||||||
|
* number is the throttle threshold of recording mouse/touch move
|
||||||
|
*/
|
||||||
|
mousemove: boolean | number;
|
||||||
|
/**
|
||||||
|
* false means not to record mouse interaction events
|
||||||
|
* can also specify record some kinds of mouse interactions
|
||||||
|
*/
|
||||||
|
mouseInteraction: boolean | Record<string, boolean | undefined>;
|
||||||
|
/**
|
||||||
|
* number is the throttle threshold of recording scroll
|
||||||
|
*/
|
||||||
|
scroll: number;
|
||||||
|
/**
|
||||||
|
* 'all' will record all the input events
|
||||||
|
* 'last' will only record the last input value while input a sequence of chars
|
||||||
|
*/
|
||||||
|
input: 'all' | 'last';
|
||||||
|
}>;
|
||||||
|
|
||||||
export type recordOptions<T> = {
|
export type recordOptions<T> = {
|
||||||
emit?: (e: T, isCheckout?: boolean) => void;
|
emit?: (e: T, isCheckout?: boolean) => void;
|
||||||
checkoutEveryNth?: number;
|
checkoutEveryNth?: number;
|
||||||
@@ -133,10 +160,13 @@ export type recordOptions<T> = {
|
|||||||
blockClass?: blockClass;
|
blockClass?: blockClass;
|
||||||
ignoreClass?: string;
|
ignoreClass?: string;
|
||||||
maskAllInputs?: boolean;
|
maskAllInputs?: boolean;
|
||||||
|
maskInputOptions?: MaskInputOptions;
|
||||||
inlineStylesheet?: boolean;
|
inlineStylesheet?: boolean;
|
||||||
hooks?: hooksParam;
|
hooks?: hooksParam;
|
||||||
mousemoveWait?: number;
|
|
||||||
packFn?: PackFn;
|
packFn?: PackFn;
|
||||||
|
sampling?: SamplingStrategy;
|
||||||
|
// departed, please use sampling options
|
||||||
|
mousemoveWait?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type observerParam = {
|
export type observerParam = {
|
||||||
@@ -149,10 +179,10 @@ export type observerParam = {
|
|||||||
mediaInteractionCb: mediaInteractionCallback;
|
mediaInteractionCb: mediaInteractionCallback;
|
||||||
blockClass: blockClass;
|
blockClass: blockClass;
|
||||||
ignoreClass: string;
|
ignoreClass: string;
|
||||||
maskAllInputs: boolean;
|
maskInputOptions: MaskInputOptions;
|
||||||
inlineStylesheet: boolean;
|
inlineStylesheet: boolean;
|
||||||
styleSheetRuleCb: styleSheetRuleCallback;
|
styleSheetRuleCb: styleSheetRuleCallback;
|
||||||
mousemoveWait: number;
|
sampling: SamplingStrategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type hooksParam = {
|
export type hooksParam = {
|
||||||
|
|||||||
@@ -2288,6 +2288,694 @@ exports[`mask 1`] = `
|
|||||||
\\"id\\": 37
|
\\"id\\": 37
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"*\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`maskInputOptions 1`] = `
|
||||||
|
"[
|
||||||
|
{
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"data\\": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 1,
|
||||||
|
\\"data\\": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 4,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"href\\": \\"about:blank\\",
|
||||||
|
\\"width\\": 1920,
|
||||||
|
\\"height\\": 1080
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 1,
|
||||||
|
\\"name\\": \\"html\\",
|
||||||
|
\\"publicId\\": \\"\\",
|
||||||
|
\\"systemId\\": \\"\\",
|
||||||
|
\\"id\\": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"html\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"lang\\": \\"en\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"head\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"meta\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"charset\\": \\"UTF-8\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"meta\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"name\\": \\"viewport\\",
|
||||||
|
\\"content\\": \\"width=device-width, initial-scale=1.0\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"meta\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"http-equiv\\": \\"X-UA-Compatible\\",
|
||||||
|
\\"content\\": \\"ie=edge\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"title\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"form fields\\",
|
||||||
|
\\"id\\": 13
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n\\",
|
||||||
|
\\"id\\": 14
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n\\\\n\\",
|
||||||
|
\\"id\\": 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"body\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 17
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"form\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"label\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"for\\": \\"text\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"input\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"text\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 23
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"label\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"for\\": \\"radio\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"input\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"radio\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 27
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 28
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 29
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"label\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"for\\": \\"checkbox\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 31
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"input\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"type\\": \\"checkbox\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 33
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 30
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"label\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"for\\": \\"textarea\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 36
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"textarea\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"name\\": \\"\\",
|
||||||
|
\\"id\\": \\"\\",
|
||||||
|
\\"cols\\": \\"30\\",
|
||||||
|
\\"rows\\": \\"10\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 37
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 38
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 39
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"label\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"for\\": \\"select\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"select\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"name\\": \\"\\",
|
||||||
|
\\"id\\": \\"\\",
|
||||||
|
\\"value\\": \\"1\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 43
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"option\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"value\\": \\"1\\",
|
||||||
|
\\"selected\\": true
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"1\\",
|
||||||
|
\\"id\\": 45
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 44
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 46
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"option\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"value\\": \\"2\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"2\\",
|
||||||
|
\\"id\\": 48
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 49
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 42
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 50
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\",
|
||||||
|
\\"id\\": 51
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n\\\\n \\",
|
||||||
|
\\"id\\": 52
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"script\\",
|
||||||
|
\\"attributes\\": {},
|
||||||
|
\\"childNodes\\": [
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
|
||||||
|
\\"id\\": 54
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 53
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\",
|
||||||
|
\\"id\\": 55
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 16
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"id\\": 1
|
||||||
|
},
|
||||||
|
\\"initialOffset\\": {
|
||||||
|
\\"left\\": 0,
|
||||||
|
\\"top\\": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 5,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"t\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"te\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"tes\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"test\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 1,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 6,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 5,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"on\\",
|
||||||
|
\\"isChecked\\": true,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 1,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 6,
|
||||||
|
\\"id\\": 27
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 5,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 0,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"on\\",
|
||||||
|
\\"isChecked\\": true,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 6,
|
||||||
|
\\"id\\": 32
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 5,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"t\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"te\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"tex\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"text\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"texta\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textar\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textare\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea \\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea t\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea te\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea tes\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"textarea test\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 37
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
\\"type\\": 3,
|
\\"type\\": 3,
|
||||||
\\"data\\": {
|
\\"data\\": {
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ describe('record integration tests', function (this: ISuite) {
|
|||||||
console.log(event);
|
console.log(event);
|
||||||
window.snapshots.push(event);
|
window.snapshots.push(event);
|
||||||
},
|
},
|
||||||
maskAllInputs: ${options.maskAllInputs}
|
maskAllInputs: ${options.maskAllInputs},
|
||||||
|
maskInputOptions: ${JSON.stringify(options.maskAllInputs)}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -166,6 +167,28 @@ describe('record integration tests', function (this: ISuite) {
|
|||||||
assertSnapshot(snapshots, __filename, 'mask');
|
assertSnapshot(snapshots, __filename, 'mask');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can use maskInputOptions to configure which type of inputs should be masked', async () => {
|
||||||
|
const page: puppeteer.Page = await this.browser.newPage();
|
||||||
|
await page.goto('about:blank');
|
||||||
|
await page.setContent(
|
||||||
|
getHtml.call(this, 'form.html', {
|
||||||
|
maskInputOptions: {
|
||||||
|
text: false,
|
||||||
|
textarea: false,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.type('input[type="text"]', 'test');
|
||||||
|
await page.click('input[type="radio"]');
|
||||||
|
await page.click('input[type="checkbox"]');
|
||||||
|
await page.type('textarea', 'textarea test');
|
||||||
|
await page.select('select', '1');
|
||||||
|
|
||||||
|
const snapshots = await page.evaluate('window.snapshots');
|
||||||
|
assertSnapshot(snapshots, __filename, 'maskInputOptions');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not record blocked elements and its child nodes', async () => {
|
it('should not record blocked elements and its child nodes', async () => {
|
||||||
const page: puppeteer.Page = await this.browser.newPage();
|
const page: puppeteer.Page = await this.browser.newPage();
|
||||||
await page.goto('about:blank');
|
await page.goto('about:blank');
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
],
|
],
|
||||||
"arrow-parens": false,
|
"arrow-parens": false,
|
||||||
"only-arrow-functions": false,
|
"only-arrow-functions": false,
|
||||||
"max-line-length": false
|
"max-line-length": false,
|
||||||
|
"no-empty": false
|
||||||
},
|
},
|
||||||
"rulesDirectory": []
|
"rulesDirectory": []
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user