Skip to content

Commit

Permalink
♻️[e2e] wait request to reach server before assertions (#229)
Browse files Browse the repository at this point in the history
* ♻️[e2e] wait to have receive logs/rum events before asserting on it

* 👌[e2e] simplify code
  • Loading branch information
bcaudan authored Jan 10, 2020
1 parent 368437d commit c001b04
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 38 deletions.
40 changes: 21 additions & 19 deletions test/e2e/scenario/agents.scenario.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { LogsGlobal } from '@datadog/browser-logs'
import { RumEvent, RumEventCategory, RumResourceEvent } from '@datadog/browser-rum'
import { RumEventCategory, RumResourceEvent, RumViewEvent } from '@datadog/browser-rum'
import {
browserExecute,
browserExecuteAsync,
flushBrowserLogs,
flushEvents,
renewSession,
retrieveLogs,
retrieveLogsMessages,
retrieveRumEvents,
retrieveRumEventsTypes,
retrieveViewEvents,
ServerRumViewEvent,
sortByMessage,
tearDown,
waitServerLogs,
waitServerRumEvents,
withBrowserLogs,
} from './helpers'

Expand All @@ -31,17 +29,17 @@ describe('logs', () => {
;((window as any).DD_LOGS as LogsGlobal).logger.log('hello')
})
await flushEvents()
const logs = await retrieveLogsMessages()
expect(logs).toContain('hello')
const logMessages = (await waitServerLogs()).map((log) => log.message)
expect(logMessages).toContain('hello')
})

it('should send errors', async () => {
await browserExecute(() => {
console.error('oh snap')
})
await flushEvents()
const logs = await retrieveLogsMessages()
expect(logs).toContain('console error: oh snap')
const logMessages = (await waitServerLogs()).map((log) => log.message)
expect(logMessages).toContain('console error: oh snap')
await withBrowserLogs((browserLogs) => {
expect(browserLogs.length).toEqual(1)
})
Expand All @@ -52,7 +50,7 @@ describe('logs', () => {
;((window as any).DD_LOGS as LogsGlobal).logger.log('hello')
})
await flushEvents()
const log = (await retrieveLogs())[0]
const log = (await waitServerLogs())[0]
expect(log.application_id).toBe('rum')
expect(log.view.id).toBeDefined()
})
Expand All @@ -64,8 +62,8 @@ describe('rum', () => {
console.error('oh snap')
})
await flushEvents()
const types = await retrieveRumEventsTypes()
expect(types).toContain(RumEventCategory.ERROR)
const eventCategories = (await waitServerRumEvents()).map((rumEvent) => rumEvent.evt.category)
expect(eventCategories).toContain(RumEventCategory.ERROR)
await withBrowserLogs((browserLogs) => {
expect(browserLogs.length).toEqual(1)
})
Expand All @@ -88,8 +86,8 @@ describe('rum', () => {
}, browser.options.baseUrl!)

await flushEvents()
const timing = (await retrieveRumEvents()).find(
(event: RumEvent) =>
const timing = (await waitServerRumEvents()).find(
(event) =>
event.evt.category === 'resource' && (event as RumResourceEvent).http.url === `${browser.options.baseUrl}/ok`
) as RumResourceEvent

Expand All @@ -102,7 +100,9 @@ describe('rum', () => {

it('should send performance timings along the view events', async () => {
await flushEvents()
const viewEvent = (await retrieveViewEvents())[0]
const events = await waitServerRumEvents()

const viewEvent = events.find((event) => event.evt.category === 'view') as RumViewEvent

expect(viewEvent as any).not.toBe(undefined)
const measures = viewEvent.view.measures
Expand All @@ -116,7 +116,9 @@ describe('rum', () => {
await renewSession()
await flushEvents()

const viewEvents = await retrieveViewEvents()
const viewEvents = (await waitServerRumEvents()).filter(
(event) => event.evt.category === 'view'
) as ServerRumViewEvent[]

expect(viewEvents.length).toBe(2)
expect(viewEvents[0].session_id).not.toBe(viewEvents[1].session_id)
Expand Down Expand Up @@ -161,7 +163,7 @@ describe('error collection', () => {
)
await flushBrowserLogs()
await flushEvents()
const logs = (await retrieveLogs()).sort(sortByMessage)
const logs = (await waitServerLogs()).sort(sortByMessage)

expect(logs.length).toEqual(2)

Expand Down Expand Up @@ -195,7 +197,7 @@ describe('error collection', () => {
)
await flushBrowserLogs()
await flushEvents()
const logs = (await retrieveLogs()).sort(sortByMessage)
const logs = (await waitServerLogs()).sort(sortByMessage)

expect(logs.length).toEqual(2)

Expand Down
40 changes: 21 additions & 19 deletions test/e2e/scenario/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,18 @@ export async function tearDown() {
})
}

export async function retrieveRumEvents() {
return fetch('/rum').then((rumEvents: string) => JSON.parse(rumEvents) as RumEvent[])
export async function waitServerLogs(): Promise<ServerLogsMessage[]> {
return fetchWhile('/logs', (logs: ServerLogsMessage[]) => logs.length === 0)
}

export async function retrieveRumEventsTypes() {
return retrieveRumEvents().then((rumEvents: RumEvent[]) =>
rumEvents.map((rumEvent: RumEvent) => rumEvent.evt.category)
)
}

export async function retrieveLogs() {
return fetch('/logs').then((logs: string) => JSON.parse(logs) as ServerLogsMessage[])
}

export async function retrieveLogsMessages() {
return retrieveLogs().then((logs: ServerLogsMessage[]) => logs.map((log: ServerLogsMessage) => log.message))
export async function waitServerRumEvents(): Promise<RumEvent[]> {
return fetchWhile('/rum', (events: RumEvent[]) => events.length === 0)
}

export async function retrieveMonitoringErrors() {
return fetch('/monitoring').then((monitoringErrors: string) => JSON.parse(monitoringErrors) as MonitoringMessage[])
}

export async function retrieveViewEvents() {
const events = await retrieveRumEvents()
return events.filter((event) => event.evt.category === 'view') as ServerRumViewEvent[]
}

export async function resetServerState() {
return fetch('/reset')
}
Expand All @@ -114,6 +99,23 @@ async function fetch(url: string): Promise<string> {
})
}

export async function fetchWhile(url: string, conditionFn: (body: any) => boolean, timeout = 10000) {
const threshold = Date.now() + timeout
let body: string = await fetch(url)
while (conditionFn(JSON.parse(body))) {
if (Date.now() > threshold) {
throw new Error(`fetchWhile promise rejected because of timeout (${timeout / 1000}s)
Body: ${body}
conditionFn: ${conditionFn.toString()}
`)
} else {
await new Promise((resolve) => setTimeout(resolve, 500))
}
body = await fetch(url)
}
return JSON.parse(body)
}

export function sortByMessage(a: { message: string }, b: { message: string }) {
if (a.message < b.message) {
return -1
Expand Down

0 comments on commit c001b04

Please sign in to comment.