diff --git a/src/document/interceptor.ts b/src/document/interceptor.ts index 6d6ecc2f..d5fe4efc 100644 --- a/src/document/interceptor.ts +++ b/src/document/interceptor.ts @@ -51,7 +51,7 @@ export function prepareInterceptor< ...args: Params ) { const { - applyNative = true, + applyNative = false, realArgs, then, } = interceptorImpl.call(this, ...args) diff --git a/src/document/selection.ts b/src/document/selection.ts index 8192dc2e..2ea6a94d 100644 --- a/src/document/selection.ts +++ b/src/document/selection.ts @@ -32,8 +32,7 @@ export function prepareSelectionInterceptor( function interceptorImpl( this: HTMLInputElement | HTMLTextAreaElement, start: number | Value | null, - end: number | null, - direction: 'forward' | 'backward' | 'none' = 'none', + ...others ) { const isUI = start && typeof start === 'object' && start[UISelection] @@ -42,10 +41,11 @@ export function prepareSelectionInterceptor( } return { - realArgs: [Number(start), end, direction] as [ + applyNative: !!isUI, + realArgs: [Number(start), ...others] as [ number, number, - typeof direction, + 'forward' | 'backward' | 'none' | undefined, ], } }, diff --git a/tests/document/index.ts b/tests/document/index.ts index 3f4679de..3326a773 100644 --- a/tests/document/index.ts +++ b/tests/document/index.ts @@ -202,3 +202,45 @@ test('track changes to value and selection per setRangeText', () => { expect(getUIValue(element)).toBe('aYcd') expect(getUISelection(element)).toHaveProperty('focusOffset', 1) }) + +test('circumvent setters/methods for UI changes', () => { + const {element} = render(``, {focus: false}) + + const prototypeDescr = Object.getOwnPropertyDescriptors( + Object.getPrototypeOf(element) as HTMLInputElement, + ) + const valueSpy = jest.fn(prototypeDescr.value.set) + const setSelectionRangeSpy = jest.fn(prototypeDescr.setSelectionRange.value) + + Object.defineProperties(element, { + value: { + get: () => { + throw new Error() + }, + ...prototypeDescr.value, + set: valueSpy, + }, + setSelectionRange: { + ...prototypeDescr.setSelectionRange, + value: setSelectionRangeSpy, + }, + }) + + prepare(element) + element.focus() + + setUIValue(element, 'abcd') + setUISelection(element, {focusOffset: 3}) + + expect(element).toHaveValue('abcd') + expect(element).toHaveProperty('selectionStart', 3) + expect(valueSpy).not.toBeCalled() + expect(setSelectionRangeSpy).not.toBeCalled() + + element.value = 'efgh' + element.setSelectionRange(1, 2) + expect(element).toHaveValue('efgh') + expect(element).toHaveProperty('selectionStart', 1) + expect(valueSpy).toBeCalledWith('efgh') + expect(setSelectionRangeSpy).toBeCalledWith(1, 2) +})