test(t => { assert_throws( { name: "TypeError" }, function () { new PerformanceObserver(); }, "PerformanceObserver constructor should throw TypeError if no argument is specified." ); assert_throws( { name: "TypeError" }, function () { new PerformanceObserver({}); }, "PerformanceObserver constructor should throw TypeError if the argument is not a function." ); }, "Test that PerformanceObserver constructor throws exception"); test(t => { var observer = new PerformanceObserver(() => {}); assert_throws( { name: "TypeError" }, function () { observer.observe(); }, "observe() should throw TypeError exception if no option specified." ); assert_throws( { name: "TypeError" }, function () { observer.observe({ unsupportedAttribute: "unsupported" }); }, "obsrve() should throw TypeError exception if the option has no 'entryTypes' attribute." ); assert_equals( undefined, observer.observe({ entryTypes: [] }), "observe() should silently ignore empty 'entryTypes' sequence." ); assert_throws( { name: "TypeError" }, function () { observer.observe({ entryTypes: null }); }, "obsrve() should throw TypeError exception if 'entryTypes' attribute is null." ); assert_equals( undefined, observer.observe({ entryTypes: ["invalid"] }), "observe() should silently ignore invalid 'entryTypes' values." ); }, "Test that PerformanceObserver.observe throws exception"); function promiseObserve(test, options) { return new Promise(resolve => { performance.clearMarks(); performance.clearMeasures(); var observer = new PerformanceObserver(list => resolve(list)); observer.observe(options); test.add_cleanup(() => observer.disconnect()); }); } promise_test(t => { var promise = promiseObserve(t, { entryTypes: ["mark", "measure"] }); performance.mark("test-start"); performance.mark("test-end"); performance.measure("test-measure", "test-start", "test-end"); return promise.then(list => { assert_equals( list.getEntries().length, 3, "There should be three observed entries." ); var markEntries = list.getEntries().filter(entry => { return entry.entryType == "mark"; }); assert_array_equals( markEntries, performance.getEntriesByType("mark"), "Observed 'mark' entries should equal to entries obtained by getEntriesByType." ); var measureEntries = list.getEntries().filter(entry => { return entry.entryType == "measure"; }); assert_array_equals( measureEntries, performance.getEntriesByType("measure"), "Observed 'measure' entries should equal to entries obtained by getEntriesByType." ); }); }, "Test for user-timing with PerformanceObserver"); promise_test(t => { var promise = new Promise((resolve, reject) => { performance.clearMarks(); performance.clearMeasures(); var observer = new PerformanceObserver(list => reject(list)); observer.observe({ entryTypes: ["mark", "measure"] }); observer.disconnect(); t.step_timeout(resolve, 100); }); performance.mark("test-start"); performance.mark("test-end"); performance.measure("test-measure", "test-start", "test-end"); return promise.then( () => { assert_equals(performance.getEntriesByType("mark").length, 2); assert_equals(performance.getEntriesByType("measure").length, 1); }, list => { assert_unreached("Observer callback should never be called."); } ); }, "Nothing should be notified after disconnecting observer"); promise_test(t => { var promise = promiseObserve(t, { entryTypes: ["mark"] }); performance.mark("test"); return promise.then(list => { assert_array_equals( list.getEntries({ entryType: "mark" }), performance.getEntriesByType("mark"), "getEntries with entryType filter should return correct results." ); assert_array_equals( list.getEntries({ name: "test" }), performance.getEntriesByName("test"), "getEntries with name filter should return correct results." ); assert_array_equals( list.getEntries({ name: "test", entryType: "mark" }), performance.getEntriesByName("test"), "getEntries with name and entryType filter should return correct results." ); assert_array_equals( list.getEntries({ name: "invalid" }), [], "getEntries with non-existent name filter should return an empty array." ); assert_array_equals( list.getEntries({ name: "test", entryType: "measure" }), [], "getEntries with name filter and non-existent entryType should return an empty array." ); assert_array_equals( list.getEntries({ name: "invalid", entryType: "mark" }), [], "getEntries with non-existent name and entryType filter should return an empty array." ); assert_array_equals( list.getEntries({ initiatorType: "xmlhttprequest" }), [], "getEntries with initiatorType filter should return an empty array." ); }); }, "Test for PerformanceObserverEntryList.getEntries"); promise_test(t => { var promise = promiseObserve(t, { entryTypes: ["mark", "measure"] }); performance.mark("test"); performance.measure("test-measure", "test", "test"); return promise.then(list => { assert_array_equals( list.getEntriesByType("mark"), performance.getEntriesByType("mark") ); assert_array_equals( list.getEntriesByType("measure"), performance.getEntriesByType("measure") ); }); }, "Test for PerformanceObserverEntryList.getEntriesByType"); promise_test(t => { var promise = promiseObserve(t, { entryTypes: ["mark", "measure"] }); performance.mark("test"); performance.measure("test-measure", "test", "test"); return promise.then(list => { assert_array_equals( list.getEntriesByName("test"), performance.getEntriesByName("test") ); assert_array_equals( list.getEntriesByName("test-measure"), performance.getEntriesByName("test-measure") ); }); }, "Test for PerformanceObserverEntryList.getEntriesByName"); promise_test(t => { var promise = new Promise(resolve => { performance.clearMarks(); performance.clearMeasures(); var observer = new PerformanceObserver(list => resolve(list)); observer.observe({ entryTypes: ["mark", "measure"] }); observer.observe({ entryTypes: ["mark", "measure"] }); t.add_cleanup(() => observer.disconnect()); }); performance.mark("test-start"); performance.mark("test-end"); performance.measure("test-measure", "test-start", "test-end"); return promise.then(list => { assert_equals( list.getEntries().length, 3, "Observed user timing entries should have only three entries." ); }); }, "Test that invoking observe method twice affects nothing"); promise_test(t => { var promise = new Promise(resolve => { performance.clearMarks(); performance.clearMeasures(); var observer = new PerformanceObserver(list => resolve(list)); observer.observe({ entryTypes: ["mark", "measure"] }); observer.observe({ entryTypes: ["mark"] }); t.add_cleanup(() => observer.disconnect()); }); performance.mark("test-start"); performance.mark("test-end"); performance.measure("test-measure", "test-start", "test-end"); return promise.then(list => { assert_equals( list.getEntries().length, 2, "Observed user timing entries should have only two entries." ); }); }, "Test that observing filter is replaced by a new filter"); promise_test(t => { var promise = new Promise(resolve => { performance.clearMarks(); performance.clearMeasures(); var observer = new PerformanceObserver(list => resolve(list)); observer.observe({ entryTypes: ["mark"] }); observer.observe({ entryTypes: ["measure"] }); t.add_cleanup(() => observer.disconnect()); }); performance.mark("test-start"); performance.mark("test-end"); performance.measure("test-measure", "test-start", "test-end"); return promise.then(list => { assert_equals( list.getEntries().length, 1, "Observed user timing entries should have only 1 entries." ); }); }, "Test that observing filter is replaced by a new filter");