diff --git a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js index c1b2a47a0ba..57a0e1d8946 100644 --- a/packages/react-native/src/private/webapis/performance/PerformanceObserver.js +++ b/packages/react-native/src/private/webapis/performance/PerformanceObserver.js @@ -203,18 +203,30 @@ export class PerformanceObserver { return observerHandle; } - #validateObserveOptions(options: PerformanceObserverInit): void { - const {type, entryTypes, durationThreshold} = options; + #validateObserveOptions(options: ?PerformanceObserverInit): void { + if (options == null) { + throw new TypeError( + "Failed to execute 'observe' on 'PerformanceObserver': 1 argument required, but only 0 present.", + ); + } + + const {type, entryTypes, durationThreshold, buffered} = options; if (!type && !entryTypes) { throw new TypeError( - "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.", + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.", ); } if (entryTypes && type) { throw new TypeError( - "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.", + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.", + ); + } + + if (entryTypes && buffered != null) { + throw new TypeError( + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and buffered arguments.", ); } diff --git a/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-itest.js b/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-itest.js index 41ddaa4be8f..3924e5e2435 100644 --- a/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-itest.js +++ b/packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-itest.js @@ -96,6 +96,31 @@ describe('PerformanceObserver', () => { expect(entries2.getEntries()[1]).toBe(measure); }); + describe('observe()', () => { + it('rejects invalid entry type option combinations before registering with native', () => { + const callback = jest.fn(); + const observer = new PerformanceObserver(callback); + + // $FlowExpectedError[incompatible-call] + expect(() => observer.observe()).toThrow( + "Failed to execute 'observe' on 'PerformanceObserver': 1 argument required, but only 0 present.", + ); + expect(() => observer.observe({})).toThrow( + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.", + ); + expect(() => + observer.observe({entryTypes: ['mark'], type: 'measure'}), + ).toThrow( + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.", + ); + expect(() => + observer.observe({entryTypes: ['mark'], buffered: true}), + ).toThrow( + "Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and buffered arguments.", + ); + }); + }); + describe('takeRecords()', () => { it('provides all buffered events and clears the buffer', () => { const callback = jest.fn();