Skip to content

Commit

Permalink
♻️[RUMF-1517] split core specHelper (#2111)
Browse files Browse the repository at this point in the history
* ♻️ move clearAllCookies to its usage

* ♻️ extract browserChecks

* ♻️ extract buildEnv

* ♻️ extract requests.specHelper

* ♻️ extract createNewEvent

* ♻️ extract location.specHelper

* ♻️ extract mockClock

* ♻️ rename specHelper to simpleTestDoubles

* ♻️ move capturedExceptions to tracekit

* 👌 remove specHelper prefix for files under test directory

* 👌 extract test/emulate directory

* 👌 split simpleTestDoubles
  • Loading branch information
bcaudan authored Mar 29, 2023
1 parent 471bbf1 commit 5578fe2
Show file tree
Hide file tree
Showing 18 changed files with 256 additions and 243 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as CapturedExceptions from '../../../test'
import { isSafari } from '../../../test'
import * as CapturedExceptions from './capturedExceptions.specHelper'
import { computeStackTrace } from './computeStackTrace'

describe('computeStackTrace', () => {
Expand Down
11 changes: 11 additions & 0 deletions packages/core/test/browserChecks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export function isSafari() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
}

export function isFirefox() {
return navigator.userAgent.toLowerCase().indexOf('firefox') > -1
}

export function isAdoptedStyleSheetsSupported() {
return Boolean((document as any).adoptedStyleSheets)
}
4 changes: 4 additions & 0 deletions packages/core/test/buildEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// to simulate different build env behavior
export interface BuildEnvWindow {
__BUILD_ENV__SDK_VERSION__: string
}
13 changes: 13 additions & 0 deletions packages/core/test/emulate/cookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function stubCookie() {
let cookie = ''
return {
getSpy: spyOnProperty(Document.prototype, 'cookie', 'get').and.callFake(() => cookie),
setSpy: spyOnProperty(Document.prototype, 'cookie', 'set').and.callFake((newCookie) => {
cookie = newCookie
}),
currentValue: () => cookie,
setCurrentValue: (newCookie: string) => {
cookie = newCookie
},
}
}
26 changes: 26 additions & 0 deletions packages/core/test/emulate/createNewEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { objectEntries } from '../../src'

export function createNewEvent<P extends Record<string, unknown>>(eventName: 'click', properties?: P): MouseEvent & P
export function createNewEvent<P extends Record<string, unknown>>(
eventName: 'pointerup',
properties?: P
): PointerEvent & P
export function createNewEvent(eventName: string, properties?: { [name: string]: unknown }): Event
export function createNewEvent(eventName: string, properties: { [name: string]: unknown } = {}) {
let event: Event
if (typeof Event === 'function') {
event = new Event(eventName)
} else {
event = document.createEvent('Event')
event.initEvent(eventName, true, true)
}
objectEntries(properties).forEach(([name, value]) => {
// Setting values directly or with a `value` descriptor seems unsupported in IE11
Object.defineProperty(event, name, {
get() {
return value
},
})
})
return event
}
14 changes: 14 additions & 0 deletions packages/core/test/emulate/eventBridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { BrowserWindowWithEventBridge } from '../../src/transport'

export function initEventBridgeStub(allowedWebViewHosts: string[] = [window.location.hostname]) {
const eventBridgeStub = {
send: (_msg: string) => undefined,
getAllowedWebViewHosts: () => JSON.stringify(allowedWebViewHosts),
}
;(window as BrowserWindowWithEventBridge).DatadogEventBridge = eventBridgeStub
return eventBridgeStub
}

export function deleteEventBridgeStub() {
delete (window as BrowserWindowWithEventBridge).DatadogEventBridge
}
32 changes: 32 additions & 0 deletions packages/core/test/emulate/location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { assign, buildUrl } from '../../src'

export function mockLocation(initialUrl: string) {
const fakeLocation = buildLocation(initialUrl)
spyOn(history, 'pushState').and.callFake((_: any, __: string, pathname: string) => {
assign(fakeLocation, buildLocation(pathname, fakeLocation.href))
})

function hashchangeCallBack() {
fakeLocation.hash = window.location.hash
fakeLocation.href = fakeLocation.href.replace(/#.*/, '') + window.location.hash
}

window.addEventListener('hashchange', hashchangeCallBack)
return {
location: fakeLocation,
cleanup: () => {
window.removeEventListener('hashchange', hashchangeCallBack)
window.location.hash = ''
},
}
}

export function buildLocation(url: string, base = location.href) {
const urlObject = buildUrl(url, base)
return {
hash: urlObject.hash,
href: urlObject.href,
pathname: urlObject.pathname,
search: urlObject.search,
} as Location
}
20 changes: 20 additions & 0 deletions packages/core/test/emulate/mockClock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { resetNavigationStart } from '../../src/tools/timeUtils'

export type Clock = ReturnType<typeof mockClock>

export function mockClock(date?: Date) {
jasmine.clock().install()
jasmine.clock().mockDate(date)
const start = Date.now()
spyOn(performance, 'now').and.callFake(() => Date.now() - start)
spyOnProperty(performance.timing, 'navigationStart', 'get').and.callFake(() => start)
resetNavigationStart()
return {
tick: (ms: number) => jasmine.clock().tick(ms),
setDate: (date: Date) => jasmine.clock().mockDate(date),
cleanup: () => {
jasmine.clock().uninstall()
resetNavigationStart()
},
}
}
12 changes: 12 additions & 0 deletions packages/core/test/emulate/navigatorOnLine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function setNavigatorOnLine(onLine: boolean) {
Object.defineProperty(navigator, 'onLine', {
get() {
return onLine
},
configurable: true,
})
}

export function restoreNavigatorOnLine() {
delete (navigator as any).onLine
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type {
Report,
ReportingObserverConstructor,
ReportingObserverOption,
} from '../src/domain/report/browser.types'
import { noop } from '../src/tools/utils'
} from '../../src/domain/report/browser.types'
import { noop } from '../../src/tools/utils'

export function stubReportingObserver() {
const originalReportingObserver = (window as BrowserWindow).ReportingObserver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BrowserWindowWithZoneJs } from '../src/tools/getZoneJsOriginalValue'
import type { BrowserWindowWithZoneJs } from '../../src/tools/getZoneJsOriginalValue'

export function stubZoneJs() {
const browserWindow = window as BrowserWindowWithZoneJs
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { deleteCookie, setCookie } from '../src/browser/cookie'
import type { BrowserWindow } from '../src/domain/synthetics/syntheticsWorkerValues'
import { deleteCookie, setCookie } from '../../src/browser/cookie'
import type { BrowserWindow } from '../../src/domain/synthetics/syntheticsWorkerValues'
import {
SYNTHETICS_INJECTS_RUM_COOKIE_NAME,
SYNTHETICS_RESULT_ID_COOKIE_NAME,
SYNTHETICS_TEST_ID_COOKIE_NAME,
} from '../src/domain/synthetics/syntheticsWorkerValues'
import { ONE_MINUTE } from '../src/tools/utils'
} from '../../src/domain/synthetics/syntheticsWorkerValues'
import { ONE_MINUTE } from '../../src/tools/utils'

// Duration to create a cookie lasting at least until the end of the test
const COOKIE_DURATION = ONE_MINUTE
Expand Down
12 changes: 12 additions & 0 deletions packages/core/test/emulate/visibilityState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function setPageVisibility(visibility: 'visible' | 'hidden') {
Object.defineProperty(document, 'visibilityState', {
get() {
return visibility
},
configurable: true,
})
}

export function restorePageVisibility() {
delete (document as any).visibilityState
}
13 changes: 13 additions & 0 deletions packages/core/test/emulate/windowOnError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { instrumentMethod, noop } from '../../src'

/**
* Opt out of jasmine uncaught error interception during test. This is useful for tests that are
* instrumenting `window.onerror`. See https://github.com/jasmine/jasmine/pull/1860 for more
* information.
*/
export function disableJasmineUncaughtErrorHandler() {
const { stop } = instrumentMethod(window, 'onerror', () => noop)
return {
reset: stop,
}
}
9 changes: 7 additions & 2 deletions packages/core/test/forEach.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { BuildEnvWindow } from './specHelper'
import { clearAllCookies } from './specHelper'
import type { BuildEnvWindow } from './buildEnv'

beforeEach(() => {
;(window as unknown as BuildEnvWindow).__BUILD_ENV__SDK_VERSION__ = 'test'
Expand All @@ -13,3 +12,9 @@ beforeEach(() => {
afterEach(() => {
clearAllCookies()
})

function clearAllCookies() {
document.cookie.split(';').forEach((c) => {
document.cookie = c.replace(/=.*/, `=;expires=${new Date().toUTCString()};path=/;samesite=strict`)
})
}
21 changes: 16 additions & 5 deletions packages/core/test/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
export * from './capturedExceptions'
export * from './browserChecks'
export * from './buildEnv'
export * from './collectAsyncCalls'
export * from './stubReportApis'
export * from './stubZoneJs'
export * from './syntheticsWorkerValues'
export * from './specHelper'
export * from './requests'
export * from './emulate/createNewEvent'
export * from './emulate/location'
export * from './emulate/mockClock'
export * from './emulate/stubReportApis'
export * from './emulate/stubZoneJs'
export * from './emulate/syntheticsWorkerValues'
export * from './emulate/visibilityState'
export * from './emulate/navigatorOnLine'
export * from './emulate/navigatorOnLine'
export * from './emulate/eventBridge'
export * from './emulate/eventBridge'
export * from './emulate/windowOnError'
export * from './emulate/cookie'
Loading

0 comments on commit 5578fe2

Please sign in to comment.