diff --git a/.changeset/quiet-foxes-approve.md b/.changeset/quiet-foxes-approve.md new file mode 100644 index 000000000..1e112b135 --- /dev/null +++ b/.changeset/quiet-foxes-approve.md @@ -0,0 +1,5 @@ +--- +'@segment/analytics-next': patch +--- + +Fix webdriver.io interception bug. Refactor to use native fetch where unfetch is unavailable. diff --git a/packages/browser/src/browser/index.ts b/packages/browser/src/browser/index.ts index 0aa62d80f..bfbf92f76 100644 --- a/packages/browser/src/browser/index.ts +++ b/packages/browser/src/browser/index.ts @@ -1,7 +1,7 @@ import { getProcessEnv } from '../lib/get-process-env' import { getCDN, setGlobalCDNUrl } from '../lib/parse-cdn' -import fetch from 'unfetch' +import { fetch } from '../lib/fetch' import { Analytics, AnalyticsSettings, InitOptions } from '../core/analytics' import { Context } from '../core/context' import { Plan } from '../core/events' diff --git a/packages/browser/src/core/stats/remote-metrics.ts b/packages/browser/src/core/stats/remote-metrics.ts index 312ab8516..5a2d92dcb 100644 --- a/packages/browser/src/core/stats/remote-metrics.ts +++ b/packages/browser/src/core/stats/remote-metrics.ts @@ -1,4 +1,4 @@ -import fetch from 'unfetch' +import { fetch } from '../../lib/fetch' import { version } from '../../generated/version' import { getVersionType } from '../../plugins/segmentio/normalize' diff --git a/packages/browser/src/lib/__tests__/fetch.test.ts b/packages/browser/src/lib/__tests__/fetch.test.ts new file mode 100644 index 000000000..552da78c2 --- /dev/null +++ b/packages/browser/src/lib/__tests__/fetch.test.ts @@ -0,0 +1,35 @@ +import { fetch } from '../fetch' +import { getGlobal } from '../get-global' +import unfetch from 'unfetch' + +jest.mock('unfetch') +const unfetchMock = jest.mocked(unfetch).mockResolvedValue({} as Response) + +jest.mock('../get-global') +const getGlobalMock = jest.mocked(getGlobal) + +describe(fetch, () => { + const testFetchArgs = ['http://foo.com', {}] as const + + it('should call native fetch if available', () => { + const nativeFetchMock = jest.fn() + getGlobalMock.mockReturnValue({ ...window, fetch: nativeFetchMock }) + void fetch(...testFetchArgs) + expect(nativeFetchMock).toBeCalledWith(...testFetchArgs) + expect(unfetchMock).not.toBeCalled() + }) + it('should fall back to unfetch in non-browserlike environment', () => { + getGlobalMock.mockReturnValue(null) + void fetch(...testFetchArgs) + expect(unfetchMock).toBeCalledWith(...testFetchArgs) + }) + it('should fall back to unfetch if native fetch is unsupported', () => { + getGlobalMock.mockReturnValue({ + ...window, + fetch: undefined, + } as any) + + void fetch(...testFetchArgs) + expect(unfetchMock).toBeCalledWith(...testFetchArgs) + }) +}) diff --git a/packages/browser/src/lib/fetch.ts b/packages/browser/src/lib/fetch.ts new file mode 100644 index 000000000..e0d2d88c6 --- /dev/null +++ b/packages/browser/src/lib/fetch.ts @@ -0,0 +1,10 @@ +import unfetch from 'unfetch' +import { getGlobal } from './get-global' + +/** + * Wrapper around native `fetch` containing `unfetch` fallback. + */ +export const fetch: typeof global.fetch = (...args) => { + const global = getGlobal() + return ((global && global.fetch) || unfetch)(...args) +} diff --git a/packages/browser/src/plugins/segmentio/batched-dispatcher.ts b/packages/browser/src/plugins/segmentio/batched-dispatcher.ts index 68d6e74a6..10f2c0032 100644 --- a/packages/browser/src/plugins/segmentio/batched-dispatcher.ts +++ b/packages/browser/src/plugins/segmentio/batched-dispatcher.ts @@ -1,12 +1,7 @@ -import unfetch from 'unfetch' import { SegmentEvent } from '../../core/events' +import { fetch } from '../../lib/fetch' import { onPageLeave } from '../../lib/on-page-leave' -let fetch = unfetch -if (typeof window !== 'undefined') { - fetch = window.fetch || unfetch -} - type BatchingConfig = { size?: number timeout?: number diff --git a/packages/browser/src/plugins/segmentio/fetch-dispatcher.ts b/packages/browser/src/plugins/segmentio/fetch-dispatcher.ts index 91e77be28..6d0a5e895 100644 --- a/packages/browser/src/plugins/segmentio/fetch-dispatcher.ts +++ b/packages/browser/src/plugins/segmentio/fetch-dispatcher.ts @@ -1,9 +1,4 @@ -import unfetch from 'unfetch' - -let fetch = unfetch -if (typeof window !== 'undefined') { - fetch = window.fetch || unfetch -} +import { fetch } from '../../lib/fetch' export type Dispatcher = (url: string, body: object) => Promise