Skip to content

Commit

Permalink
ignore window target vars
Browse files Browse the repository at this point in the history
  • Loading branch information
metal-messiah committed Nov 20, 2024
1 parent b1e4113 commit e7e011f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/features/generic_events/aggregate/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,20 @@ export class Aggregate extends AggregateBase {
rageClick: aggregatedUserAction.rageClick,
target: aggregatedUserAction.selectorPath,
...(isIFrameWindow(window) && { iframe: true }),
...(target?.id && { targetId: target.id }),
...(target?.tagName && { targetTag: target.tagName }),
...(target?.type && { targetType: target.type }),
...(target?.className && { targetClass: target.className })
...(canTrustTargetAttribute('id') && { targetId: target.id }),
...(canTrustTargetAttribute('tagName') && { targetTag: target.tagName }),
...(canTrustTargetAttribute('type') && { targetType: target.type }),
...(canTrustTargetAttribute('className') && { targetClass: target.className })
})

/**
* Only trust attributes that exist on HTML element targets, which excludes the window and the document targets
* @param {string} attribute The attribute to check for on the target element
* @returns {boolean} Whether the target element has the attribute and can be trusted
*/
function canTrustTargetAttribute (attribute) {
return !!(aggregatedUserAction.selectorPath !== 'window' && aggregatedUserAction.selectorPath !== 'document' && target instanceof HTMLElement && target?.[attribute])
}
}
} catch (e) {
// do nothing for now
Expand Down
19 changes: 19 additions & 0 deletions tests/assets/user-actions-modified-window.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<!--
Copyright 2020 New Relic Corporation.
PDX-License-Identifier: Apache-2.0
-->
<html>
<head>
<title>User Action Test</title>
{init} {config} {loader}
</head>
<body style="height: 200vh; overflow: scroll;">
<button id="pay-btn" class="btn-cart-add flex-grow container" type="submit">Create click user action</button>
<input type="text" id="textbox"/>
<script>
// having a type attribute on the window should be ignored by the collected UserActions
window.type = 'test'
</script>
</body>
</html>
26 changes: 26 additions & 0 deletions tests/specs/ins/harvesting.e2e.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { onlyFirefox } = require('../../../tools/browser-matcher/common-matchers.mjs')
const { testInsRequest, testErrorsRequest } = require('../../../tools/testing-server/utils/expect-tests')

describe('ins harvesting', () => {
Expand Down Expand Up @@ -85,6 +86,31 @@ describe('ins harvesting', () => {
expect(clickUAs[1].actionMs).toEqual(expect.stringMatching(/^\[\d+(,\d+){4}\]$/))
})

// firefox generates a focus event when the page loads, which makes testing this easier
it.withBrowsersMatching(onlyFirefox)('should ignore window attributes on UserAction blur and focus', async () => {
const testUrl = await browser.testHandle.assetURL('user-actions.html', { init: { user_actions: { enabled: true } } })
await browser.url(testUrl).then(() => browser.waitForAgentLoad())

const [insHarvests] = await Promise.all([
insightsCapture.waitForResult({ timeout: 7500 }),
$('#pay-btn').click().then(async () => {
// rage click
await browser.execute(function () {
for (let i = 0; i < 5; i++) {
document.querySelector('#textbox').click()
}
})
// stop aggregating textbox clicks
await $('body').click()
})
])

const userActionsHarvest = insHarvests.flatMap(harvest => harvest.request.body.ins) // firefox sends a window focus event on load, so we may end up with 2 harvests
const focusBlurUAs = userActionsHarvest.filter(ua => ua.action === 'focus' || ua.action === 'blur')
expect(focusBlurUAs.length).toBeGreaterThan(0)
expect(focusBlurUAs[0].targetType).toBeUndefined()
})

it('should detect iframes on UserActions if agent is running inside iframe', async () => {
const testUrl = await browser.testHandle.assetURL('iframe/same-origin.html', { init: { user_actions: { enabled: true } } })
await browser.url(testUrl).then(() => browser.pause(2000))
Expand Down

0 comments on commit e7e011f

Please sign in to comment.