Skip to content

Commit aaebb53

Browse files
committed
add tests
1 parent e215512 commit aaebb53

File tree

5 files changed

+198
-0
lines changed

5 files changed

+198
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [new Sentry.Integrations.ContextLines()],
8+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
document.getElementById('script-error-btn').addEventListener('click', () => {
2+
throw new Error('Error without context lines');
3+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button id="inline-error-btn" onclick="throw new Error('Error with context lines')">Click me</button>
8+
<button id="script-error-btn">Click me too</button>
9+
</body>
10+
<footer>
11+
Some text...
12+
</foot>
13+
</html>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { expect } from '@playwright/test';
2+
import type { Event } from '@sentry/types';
3+
4+
import { sentryTest } from '../../../utils/fixtures';
5+
import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers';
6+
7+
sentryTest(
8+
'should add source context lines around stack frames from errors in Html',
9+
async ({ getLocalTestPath, page }) => {
10+
const url = await getLocalTestPath({ testDir: __dirname });
11+
12+
const eventPromise = getFirstSentryEnvelopeRequest<Event>(page, url);
13+
14+
await page.click('#inline-error-btn');
15+
16+
const eventData = await eventPromise;
17+
18+
expect(eventData.exception?.values).toHaveLength(1);
19+
20+
const exception = eventData.exception?.values?.[0];
21+
22+
expect(exception).toMatchObject({
23+
stacktrace: {
24+
frames: [
25+
{
26+
colno: 97,
27+
lineno: 7,
28+
pre_context: [' <meta charset="utf-8">', ' </head>', ' <body>'],
29+
context_line:
30+
' <button id="inline-error-btn" onclick="throw new Error(\'Error with context lines\')">Click me</button>',
31+
post_context: [
32+
' <button id="script-error-btn">Click me too</button>',
33+
' <script defer="" src="init.bundle.js"></script><script defer="" src="subject.bundle.js"></script>',
34+
' <footer>',
35+
],
36+
},
37+
],
38+
},
39+
});
40+
},
41+
);
42+
43+
sentryTest('should not add source context lines to errors from scripts', async ({ getLocalTestPath, page }) => {
44+
const url = await getLocalTestPath({ testDir: __dirname });
45+
46+
const eventPromise = getFirstSentryEnvelopeRequest<Event>(page, url);
47+
48+
await page.click('#script-error-btn');
49+
50+
const eventData = await eventPromise;
51+
const exception = eventData.exception?.values?.[0];
52+
const frames = exception?.stacktrace?.frames;
53+
expect(frames).toHaveLength(1);
54+
frames?.forEach(f => {
55+
expect(f).not.toHaveProperty('pre_context');
56+
expect(f).not.toHaveProperty('context_line');
57+
expect(f).not.toHaveProperty('post_context');
58+
});
59+
});
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import type { StackFrame } from '@sentry/types';
2+
3+
import { applySourceContextToFrame } from '../../../src/integrations/contextlines';
4+
5+
const lines = ['line1', 'line2', 'line3', 'line4', 'line5', 'line6', 'line7', 'line8', 'line9'];
6+
describe('ContextLines', () => {
7+
describe('applySourceContextToFrame', () => {
8+
it.each([
9+
[
10+
5,
11+
{
12+
pre_context: ['line2', 'line3', 'line4'],
13+
context_line: 'line5',
14+
post_context: ['line6', 'line7', 'line8'],
15+
},
16+
],
17+
[
18+
1,
19+
{
20+
context_line: 'line1',
21+
post_context: ['line2', 'line3', 'line4'],
22+
},
23+
],
24+
[
25+
2,
26+
{
27+
pre_context: ['line1'],
28+
context_line: 'line2',
29+
post_context: ['line3', 'line4', 'line5'],
30+
},
31+
],
32+
[
33+
9,
34+
{
35+
pre_context: ['line6', 'line7', 'line8'],
36+
context_line: 'line9',
37+
},
38+
],
39+
[
40+
11,
41+
{
42+
pre_context: ['line8', 'line9'],
43+
},
44+
],
45+
])(
46+
'correctly applies pre, post contexts and context lines for an inline stack frame (lineno %s)',
47+
(lineno, contextLines) => {
48+
const frame: StackFrame = {
49+
lineno,
50+
filename: 'https://mydomain.com/index.html',
51+
};
52+
53+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 7)).toStrictEqual({
54+
filename: 'https://mydomain.com/index.html',
55+
lineno,
56+
...contextLines,
57+
});
58+
},
59+
);
60+
61+
it('only applies the context line if the range is 1', () => {
62+
const frame: StackFrame = {
63+
lineno: 5,
64+
filename: 'https://mydomain.com/index.html',
65+
};
66+
67+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 1)).toStrictEqual({
68+
filename: 'https://mydomain.com/index.html',
69+
lineno: 5,
70+
context_line: 'line5',
71+
});
72+
});
73+
74+
it("no-ops if the frame's line number is out of bounds for the found lines", () => {
75+
const frame: StackFrame = {
76+
lineno: 20,
77+
filename: 'https://mydomain.com/index.html',
78+
};
79+
80+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 7)).toStrictEqual(frame);
81+
});
82+
83+
it("no-ops if the frame's filename is not the html file's name", () => {
84+
const frame: StackFrame = {
85+
filename: '/someScript.js',
86+
};
87+
88+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 7)).toStrictEqual(frame);
89+
});
90+
91+
it("no-ops if the frame doesn't have a line number", () => {
92+
const frame: StackFrame = {
93+
filename: '/index.html',
94+
};
95+
96+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 0)).toStrictEqual(frame);
97+
});
98+
99+
it("no-ops if the frame doesn't have a filename", () => {
100+
const frame: StackFrame = {
101+
lineno: 9,
102+
};
103+
104+
expect(applySourceContextToFrame(frame, lines, 'https://mydomain.com/index.html', 0)).toStrictEqual(frame);
105+
});
106+
107+
it('no-ops if there are no html lines available', () => {
108+
const frame: StackFrame = {
109+
lineno: 9,
110+
filename: '/index.html',
111+
};
112+
expect(applySourceContextToFrame(frame, [], 'https://mydomain.com/index.html', 0)).toStrictEqual(frame);
113+
});
114+
});
115+
});

0 commit comments

Comments
 (0)