Skip to content

Commit c8e2ea9

Browse files
author
Luca Forstner
committed
Improve tests
1 parent b7862ae commit c8e2ea9

File tree

5 files changed

+103
-41
lines changed

5 files changed

+103
-41
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
// Simple function event listener
2-
const eventListener1 = () => {
3-
testCallback1();
2+
const functionListener = () => {
3+
functionListenerCallback();
44
};
55

66
// Attach event listener twice
7-
window.addEventListener('click', eventListener1);
8-
window.addEventListener('click', eventListener1);
7+
window.addEventListener('click', functionListener);
8+
window.addEventListener('click', functionListener);
99

1010
// Event listener that has handleEvent() method: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#listener
1111
class EventHandlerClass {
1212
handleEvent() {
13-
testCallback2();
13+
objectListenerCallback();
1414
}
1515
}
1616

17-
const eventListener2 = new EventHandlerClass();
17+
const objectListener = new EventHandlerClass();
1818

1919
// Attach event listener twice
20-
window.addEventListener('click', eventListener2);
21-
window.addEventListener('click', eventListener2);
20+
window.addEventListener('click', objectListener);
21+
window.addEventListener('click', objectListener);

packages/integration-tests/suites/public-api/instrumentation/eventListener-instrumentation-behaviour/test.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,27 @@ import { expect } from '@playwright/test';
22

33
import { sentryTest } from '../../../../utils/fixtures';
44

5-
sentryTest('should attach the same event listener only once', async ({ getLocalTestPath, page }) => {
6-
const url = await getLocalTestPath({ testDir: __dirname });
7-
await page.goto(url);
5+
sentryTest(
6+
'Event listener instrumentation should attach the same event listener only once',
7+
async ({ getLocalTestPath, page }) => {
8+
const url = await getLocalTestPath({ testDir: __dirname });
9+
await page.goto(url);
810

9-
let testCallback1Calls = 0;
10-
await page.exposeFunction('testCallback1', () => {
11-
testCallback1Calls = testCallback1Calls + 1;
12-
});
11+
let functionListenerCalls = 0;
12+
await page.exposeFunction('functionListenerCallback', () => {
13+
functionListenerCalls = functionListenerCalls + 1;
14+
});
1315

14-
let testCallback2Calls = 0;
15-
await page.exposeFunction('testCallback2', () => {
16-
testCallback2Calls = testCallback2Calls + 1;
17-
});
16+
let objectListenerCalls = 0;
17+
await page.exposeFunction('objectListenerCallback', () => {
18+
objectListenerCalls = objectListenerCalls + 1;
19+
});
1820

19-
// Trigger event listeners twice
20-
await page.evaluate('document.body.click()');
21-
await page.evaluate('document.body.click()');
21+
// Trigger event listeners twice
22+
await page.evaluate('document.body.click()');
23+
await page.evaluate('document.body.click()');
2224

23-
expect(testCallback1Calls).toBe(2);
24-
expect(testCallback2Calls).toBe(2);
25-
});
25+
expect(functionListenerCalls).toBe(2);
26+
expect(objectListenerCalls).toBe(2);
27+
},
28+
);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Simple function event listener
2+
const functionListener = () => {
3+
reportFunctionListenerStackHeight(new Error().stack.split('\n').length);
4+
};
5+
6+
// Event listener that has handleEvent() method: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#listener
7+
class EventHandlerClass {
8+
handleEvent() {
9+
reportObjectListenerStackHeight(new Error().stack.split('\n').length);
10+
}
11+
}
12+
13+
const objectListener = new EventHandlerClass();
14+
15+
window.attachListeners = function () {
16+
window.addEventListener('click', functionListener);
17+
window.addEventListener('click', objectListener);
18+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../../utils/fixtures';
4+
5+
sentryTest(
6+
'Event listener instrumentation should not wrap event listeners multiple times',
7+
async ({ getLocalTestPath, page }) => {
8+
const url = await getLocalTestPath({ testDir: __dirname });
9+
await page.goto(url);
10+
11+
const functionListenerStackHeights: number[] = [];
12+
const objectListenerStackHeights: number[] = [];
13+
14+
await page.exposeFunction('reportFunctionListenerStackHeight', (height: number) => {
15+
functionListenerStackHeights.push(height);
16+
});
17+
18+
await page.exposeFunction('reportObjectListenerStackHeight', (height: number) => {
19+
objectListenerStackHeights.push(height);
20+
});
21+
22+
// Attach initial listeners
23+
await page.evaluate('window.attachListeners()');
24+
await page.evaluate('document.body.click()');
25+
26+
await page.evaluate('window.attachListeners()');
27+
await page.evaluate('window.attachListeners()');
28+
await page.evaluate('window.attachListeners()');
29+
await page.evaluate('document.body.click()');
30+
31+
expect(functionListenerStackHeights).toHaveLength(2);
32+
expect(objectListenerStackHeights).toHaveLength(2);
33+
34+
// check if all error stack traces are the same height
35+
expect(functionListenerStackHeights.every((val, _i, arr) => val === arr[0])).toBeTruthy();
36+
expect(objectListenerStackHeights.every((val, _i, arr) => val === arr[0])).toBeTruthy();
37+
},
38+
);

packages/integration-tests/suites/public-api/instrumentation/eventListener/test.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,24 @@ import { Event } from '@sentry/types';
44
import { sentryTest } from '../../../../utils/fixtures';
55
import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers';
66

7-
sentryTest('should capture an error thrown in an event handler', async ({ getLocalTestPath, page }) => {
8-
const url = await getLocalTestPath({ testDir: __dirname });
7+
sentryTest(
8+
'Event listener instrumentation should capture an error thrown in an event handler',
9+
async ({ getLocalTestPath, page }) => {
10+
const url = await getLocalTestPath({ testDir: __dirname });
911

10-
const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
12+
const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
1113

12-
expect(eventData.exception?.values).toHaveLength(1);
13-
expect(eventData.exception?.values?.[0]).toMatchObject({
14-
type: 'Error',
15-
value: 'event_listener_error',
16-
mechanism: {
17-
type: 'instrument',
18-
handled: true,
19-
},
20-
stacktrace: {
21-
frames: expect.any(Array),
22-
},
23-
});
24-
});
14+
expect(eventData.exception?.values).toHaveLength(1);
15+
expect(eventData.exception?.values?.[0]).toMatchObject({
16+
type: 'Error',
17+
value: 'event_listener_error',
18+
mechanism: {
19+
type: 'instrument',
20+
handled: true,
21+
},
22+
stacktrace: {
23+
frames: expect.any(Array),
24+
},
25+
});
26+
},
27+
);

0 commit comments

Comments
 (0)