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

chore: Add wdio test for trace with replay behavior #607

Merged
merged 15 commits into from
Jul 28, 2023
58 changes: 29 additions & 29 deletions tests/specs/stn/with-replay-error-mode.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const getTraceMode = () => browser.execute(function () {
})

describe.withBrowsersMatching(notIE)('Trace error mode', () => {
let initSTReceived, getFirstSTPayload, getReplayOnErrorUrl
let getReplayOnErrorUrl
beforeEach(async () => {
await browser.destroyAgentSession()
await browser.testHandle.scheduleReply('bamServer', {
Expand All @@ -24,9 +24,7 @@ describe.withBrowsersMatching(notIE)('Trace error mode', () => {
body: JSON.stringify({ stn: 0, err: 1, ins: 1, spa: 1, sr: 1, loaded: 1 })
})

initSTReceived = undefined
getFirstSTPayload = browser.testHandle.expectResources().then(resPayload => initSTReceived = resPayload)
getReplayOnErrorUrl = browser.testHandle.assetURL('stn/instrumented.html', config({ session_replay: { sampleRate: 0, errorSampleRate: 1 }, session_trace: { harvestTimeSeconds: 2 } }))
getReplayOnErrorUrl = browser.testHandle.assetURL('stn/instrumented.html', config({ session_replay: { sampleRate: 0, errorSampleRate: 1 }, session_trace: { harvestTimeSeconds: 3 } }))
})

function simulateErrorInBrowser () { // this is a way to throw error in WdIO / Selenium without killing the test itself
Expand All @@ -36,41 +34,40 @@ describe.withBrowsersMatching(notIE)('Trace error mode', () => {
}

it('switches to full mode when an error happens after page load', async () => {
await browser.url(await getReplayOnErrorUrl)
await browser.waitForAgentLoad()
await browser.waitUntil(() => browser.execute(async function () { // here for no-retry wdio stability
return await Object.values(newrelic.initializedAgents)[0].features.session_trace.onAggregateImported
}), { timeout: 5000 })
let startingMode = (await getTraceMode())[0]
expect(initSTReceived).toBeUndefined()
expect(startingMode).toEqual(MODE.ERROR)

await browser.execute(simulateErrorInBrowser)
await getFirstSTPayload
let modeAfterErr = (await getTraceMode())[0]
expect(modeAfterErr).toEqual(MODE.FULL)
await Promise.all([
browser.testHandle.expectResources(5001, true),
browser.url(await getReplayOnErrorUrl).then(() => browser.waitForFeatureAggregate('session_trace'))
])
await expect(getTraceMode()).resolves.toEqual([MODE.ERROR, false])

const [resources] = await Promise.all([
browser.testHandle.expectResources(),
browser.execute(simulateErrorInBrowser)
])
await expect(getTraceMode()).resolves.toEqual([MODE.FULL, false])
// The loadEventEnd is part of PT and PNT resource entry and is a node created at start of page life.
expect(initSTReceived.request.body.res.find(node => node.n === 'loadEventEnd')).toEqual(expect.objectContaining({ n: 'loadEventEnd', o: 'document', t: 'timing' }))
expect(resources.request.body.res).toEqual(expect.arrayContaining([expect.objectContaining({
n: 'loadEventEnd', o: 'document', t: 'timing'
})]))

await expect(browser.testHandle.expectResources(3000)).resolves.toBeTruthy() // double check there's nothing wrong with full mdoe interval harvest
await expect(browser.testHandle.expectResources(5002)).resolves.toBeTruthy() // double check there's nothing wrong with full mode interval harvest
})

it('starts in full mode when an error happens before page load', async () => {
await browser.url(await getReplayOnErrorUrl)
await browser.execute(simulateErrorInBrowser)
let getFirstSTPayload = browser.testHandle.expectResources(5010)
metal-messiah marked this conversation as resolved.
Show resolved Hide resolved
await browser.url(await browser.testHandle.assetURL('js-error-with-error-before-page-load.html', config({ session_replay: { sampleRate: 0, errorSampleRate: 1 }, session_trace: { harvestTimeSeconds: 3 } })))
await browser.waitForAgentLoad()
await expect(getFirstSTPayload).resolves.toBeTruthy()
let startingMode = (await getTraceMode())[0]
expect(startingMode).toEqual(MODE.FULL)
await expect(getTraceMode()).resolves.toEqual([MODE.FULL, false])

await expect(browser.testHandle.expectResources(3000)).resolves.toBeTruthy()
await expect(browser.testHandle.expectResources(5011)).resolves.toBeTruthy()
})

it.withBrowsersMatching(onlyChrome)('does not capture more than the last 30 seconds when error happens', async () => {
await getReplayOnErrorUrl.then(builtUrl => browser.url(builtUrl)).then(() => browser.waitForAgentLoad()).then(async () => {
await browser.pause(30000)
metal-messiah marked this conversation as resolved.
Show resolved Hide resolved
await Promise.all([
browser.testHandle.expectResources(3000), // the setup expectRes promise would've timed out already -- you will see some console errors but they don't impact validity
browser.testHandle.expectResources(5020), // the setup expectRes promise would've timed out already -- you will see some console errors but they don't impact validity
browser.execute(simulateErrorInBrowser)
]).then(async ([initSTAfterErr]) => {
expect(initSTAfterErr.request.body.res.find(node => node.n === 'loadEventEnd')).toBeUndefined() // that node should've been tossed out by now
metal-messiah marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -79,12 +76,15 @@ describe.withBrowsersMatching(notIE)('Trace error mode', () => {
})

it('does not perform final harvest while in this mode', async () => {
let resources = browser.testHandle.expectResources(5030, true)
await getReplayOnErrorUrl.then(builtUrl => browser.url(builtUrl)).then(() => browser.waitForAgentLoad()).then(async () => {
await getTraceMode().then(traceState => expect(traceState).toEqual([MODE.ERROR, false])) // sanity check tbh
expect(initSTReceived).toBeUndefined()
await expect(getTraceMode()).resolves.toEqual([MODE.ERROR, false]) // sanity check tbh
await expect(resources).resolves.toBeUndefined()

resources = browser.testHandle.expectResources(5031, true)
}).then(() => browser.refresh()).then(() => browser.waitForAgentLoad()).then(async () => {
await getTraceMode().then(traceState => expect(traceState).toEqual([MODE.ERROR, false]))
expect(initSTReceived).toBeUndefined() // no harvest from either previous unload or from new existing-session load
await expect(getTraceMode()).resolves.toEqual([MODE.ERROR, false])
await expect(resources).resolves.toBeUndefined() // no harvest from either previous unload or from new existing-session load
})
})

Expand Down
1 change: 1 addition & 0 deletions tools/testing-server/test-handle.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ module.exports = class TestHandle {
`Expect ${testName} for ${serverId} timed out after ${testServerExpect.timeout || this.#testServer.config.timeout}ms for test ${this.#testId}`
))
}
this.#pendingExpects.get(serverId).delete(deferred)
}, testServerExpect.timeout || this.#testServer.config.timeout)
}

Expand Down
Loading