Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️[RUMF-1517] split core specHelper #2111

Merged
merged 12 commits into from
Mar 29, 2023
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