diff --git a/packages/browser-utils/src/instrumentation/history.ts b/packages/browser-utils/src/instrumentation/history.ts index 0c5d1e6333e6..3daf54ed6d55 100644 --- a/packages/browser-utils/src/instrumentation/history.ts +++ b/packages/browser-utils/src/instrumentation/history.ts @@ -1,9 +1,19 @@ -import { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/core'; +import { addHandler, fill, maybeInstrument, triggerHandlers } from '@sentry/core'; import type { HandlerDataHistory } from '../types'; import { WINDOW } from '../types'; let lastHref: string | undefined; +/** + * Tells whether current environment supports History API + * {@link supportsHistory}. + * + * @returns Answer to the given question. + */ +export function supportsHistory(): boolean { + return 'history' in WINDOW && !!WINDOW.history; +} + /** * Add an instrumentation handler for when a fetch request happens. * The handler function is called once when the request starts and once when it ends, diff --git a/packages/browser-utils/test/instrumentation/history.test.ts b/packages/browser-utils/test/instrumentation/history.test.ts index b26e7826eeb2..7d4b98c021c9 100644 --- a/packages/browser-utils/test/instrumentation/history.test.ts +++ b/packages/browser-utils/test/instrumentation/history.test.ts @@ -1,7 +1,7 @@ import * as instrumentHandlersModule from '@sentry/core'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { WINDOW } from '../../src/types'; -import { instrumentHistory } from './../../src/instrumentation/history'; +import { instrumentHistory, supportsHistory } from './../../src/instrumentation/history'; describe('instrumentHistory', () => { const originalHistory = WINDOW.history; @@ -116,3 +116,33 @@ describe('instrumentHistory', () => { }); }); }); + +describe('supportsHistory', () => { + const originalHistory = WINDOW.history; + + afterEach(() => { + // @ts-expect-error - this is fine for testing + WINDOW.history = originalHistory; + }); + + it('returns true if history is available', () => { + // @ts-expect-error - not setting all history properties + WINDOW.history = { + pushState: () => {}, + replaceState: () => {}, + }; + expect(supportsHistory()).toBe(true); + }); + + it('returns false if history is not available', () => { + // @ts-expect-error - deletion is okay in this case + delete WINDOW.history; + expect(supportsHistory()).toBe(false); + }); + + it('returns false if history is undefined', () => { + // @ts-expect-error - undefined is okay in this case + WINDOW.history = undefined; + expect(supportsHistory()).toBe(false); + }); +}); diff --git a/packages/browser/src/integrations/reportingobserver.ts b/packages/browser/src/integrations/reportingobserver.ts index 84f49ce0c11e..91ad2a06e6b0 100644 --- a/packages/browser/src/integrations/reportingobserver.ts +++ b/packages/browser/src/integrations/reportingobserver.ts @@ -1,15 +1,18 @@ import type { Client, IntegrationFn } from '@sentry/core/browser'; -import { - captureMessage, - defineIntegration, - getClient, - GLOBAL_OBJ, - supportsReportingObserver, - withScope, -} from '@sentry/core/browser'; +import { captureMessage, defineIntegration, getClient, GLOBAL_OBJ, withScope } from '@sentry/core/browser'; const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; +/** + * Tells whether current environment supports ReportingObserver API + * {@link supportsReportingObserver}. + * + * @returns Answer to the given question. + */ +function supportsReportingObserver(): boolean { + return 'ReportingObserver' in WINDOW; +} + const INTEGRATION_NAME = 'ReportingObserver' as const; interface Report { diff --git a/packages/core/src/browser-exports.ts b/packages/core/src/browser-exports.ts index ec6c277cf2d0..076754a95db3 100644 --- a/packages/core/src/browser-exports.ts +++ b/packages/core/src/browser-exports.ts @@ -15,6 +15,6 @@ export { startIdleSpan } from './tracing/idleSpan'; export { spanStreamingIntegration } from './integrations/browserSpanStreaming'; -export { supportsDOMError, supportsHistory, supportsNativeFetch, supportsReportingObserver } from './utils/supports'; +export { supportsNativeFetch } from './utils/supports'; export type { XhrBreadcrumbData, XhrBreadcrumbHint } from './types/breadcrumb'; export type { BrowserClientReplayOptions } from './types/browseroptions'; diff --git a/packages/core/src/utils/supports.ts b/packages/core/src/utils/supports.ts index 83e2dd084f3b..910663cbf86a 100644 --- a/packages/core/src/utils/supports.ts +++ b/packages/core/src/utils/supports.ts @@ -21,24 +21,6 @@ export function supportsErrorEvent(): boolean { } } -/** - * Tells whether current environment supports DOMError objects - * {@link supportsDOMError}. - * - * @returns Answer to the given question. - */ -export function supportsDOMError(): boolean { - try { - // Chrome: VM89:1 Uncaught TypeError: Failed to construct 'DOMError': - // 1 argument required, but only 0 present. - // @ts-expect-error It really needs 1 argument, not 0. - new DOMError(''); - return true; - } catch { - return false; - } -} - /** * Tells whether current environment supports DOMException objects * {@link supportsDOMException}. @@ -54,16 +36,6 @@ export function supportsDOMException(): boolean { } } -/** - * Tells whether current environment supports History API - * {@link supportsHistory}. - * - * @returns Answer to the given question. - */ -export function supportsHistory(): boolean { - return 'history' in WINDOW && !!WINDOW.history; -} - /** * Tells whether current environment supports Fetch API * {@link supportsFetch}. @@ -141,16 +113,6 @@ export function supportsNativeFetch(): boolean { return result; } -/** - * Tells whether current environment supports ReportingObserver API - * {@link supportsReportingObserver}. - * - * @returns Answer to the given question. - */ -export function supportsReportingObserver(): boolean { - return 'ReportingObserver' in WINDOW; -} - /** * Tells whether current environment supports Referrer Policy API * {@link supportsReferrerPolicy}. diff --git a/packages/core/test/lib/utils/is.test.ts b/packages/core/test/lib/utils/is.test.ts index e68d37b8167a..e741139255d8 100644 --- a/packages/core/test/lib/utils/is.test.ts +++ b/packages/core/test/lib/utils/is.test.ts @@ -11,11 +11,12 @@ import { isThenable, isVueViewModel, } from '../../../src/utils/is'; -import { supportsDOMError, supportsDOMException, supportsErrorEvent } from '../../../src/utils/supports'; +import { supportsDOMException, supportsErrorEvent } from '../../../src/utils/supports'; import { resolvedSyncPromise } from '../../../src/utils/syncpromise'; import { testOnlyIfNodeVersionAtLeast } from '../../testutils'; -if (supportsDOMError()) { +// @ts-expect-error See: src/supports.ts for details +if (typeof DOMError !== 'undefined') { describe('isDOMError()', () => { test('should work as advertised', () => { expect(isDOMError(new Error())).toEqual(false); diff --git a/packages/core/test/lib/utils/supports.test.ts b/packages/core/test/lib/utils/supports.test.ts deleted file mode 100644 index 97ad75d6c7c3..000000000000 --- a/packages/core/test/lib/utils/supports.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { afterEach } from 'node:test'; -import { describe, expect, it } from 'vitest'; -import { supportsHistory } from '../../../src/utils/supports'; - -describe('supportsHistory', () => { - const originalHistory = globalThis.history; - - afterEach(() => { - globalThis.history = originalHistory; - }); - - it('returns true if history is available', () => { - // @ts-expect-error - not setting all history properties - globalThis.history = { - pushState: () => {}, - replaceState: () => {}, - }; - expect(supportsHistory()).toBe(true); - }); - - it('returns false if history is not available', () => { - // @ts-expect-error - deletion is okay in this case - delete globalThis.history; - expect(supportsHistory()).toBe(false); - }); - - it('returns false if history is undefined', () => { - // @ts-expect-error - undefined is okay in this case - globalThis.history = undefined; - expect(supportsHistory()).toBe(false); - }); -});