Skip to content

Commit 280aa42

Browse files
authored
Merge branch 'develop' into jb/profiling/expose-profiler
2 parents ecb8037 + 03d67c9 commit 280aa42

File tree

22 files changed

+150
-152
lines changed

22 files changed

+150
-152
lines changed

.github/dependabot.yml

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ updates:
1515
allow:
1616
- dependency-name: "@sentry/cli"
1717
- dependency-name: "@sentry/vite-plugin"
18+
- dependency-name: "@sentry/webpack-plugin"
19+
- dependency-name: "@sentry/rollup-plugin"
20+
- dependency-name: "@sentry/esbuild-plugin"
1821
- dependency-name: "@opentelemetry/*"
1922
- dependency-name: "@prisma/instrumentation"
2023
- dependency-name: "opentelemetry-instrumentation-fetch-node"

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
1212

13-
Work in this release was contributed by @leopoldkristjansson. Thank you for your contribution!
13+
Work in this release was contributed by @leopoldkristjansson and @filips123. Thank you for your contributions!
1414

1515
## 8.27.0
1616

dev-packages/browser-integration-tests/utils/replayEventTemplates.ts

+1
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ export const expectedCLSPerformanceSpan = {
141141
data: {
142142
value: expect.any(Number),
143143
nodeIds: expect.any(Array),
144+
attributions: expect.any(Array),
144145
rating: expect.any(String),
145146
size: expect.any(Number),
146147
},

dev-packages/e2e-tests/test-applications/debug-id-sourcemaps/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"devDependencies": {
1616
"rollup": "^4.0.2",
1717
"vitest": "^0.34.6",
18-
"@sentry/rollup-plugin": "2.14.2"
18+
"@sentry/rollup-plugin": "2.22.3"
1919
},
2020
"volta": {
2121
"extends": "../../package.json"

dev-packages/e2e-tests/test-applications/react-router-6-use-routes/tests/fixtures/ReplayRecordingData.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ export const ReplayRecordingData = [
219219
data: {
220220
value: expect.any(Number),
221221
size: expect.any(Number),
222-
nodeId: 16,
222+
nodeIds: [16],
223223
},
224224
},
225225
},

dev-packages/e2e-tests/test-applications/react-send-to-sentry/tests/fixtures/ReplayRecordingData.ts

+1
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ export const ReplayRecordingData = [
240240
size: expect.any(Number),
241241
rating: expect.any(String),
242242
nodeIds: expect.any(Array),
243+
attributions: expect.any(Array),
243244
},
244245
},
245246
},

packages/astro/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"@sentry/node": "8.27.0",
6262
"@sentry/types": "8.27.0",
6363
"@sentry/utils": "8.27.0",
64-
"@sentry/vite-plugin": "^2.20.1"
64+
"@sentry/vite-plugin": "^2.22.3"
6565
},
6666
"devDependencies": {
6767
"astro": "^3.5.0",

packages/core/test/lib/transports/offline.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ describe('makeOfflineTransport', () => {
410410
START_DELAY + 2_000,
411411
);
412412

413-
// eslint-disable-next-line jest/no-disabled-tests
413+
// eslint-disable-next-line @sentry-internal/sdk/no-skipped-tests
414414
it.skip(
415415
'Follows the Retry-After header',
416416
async () => {

packages/eslint-config-sdk/src/base.js

+2-18
Original file line numberDiff line numberDiff line change
@@ -184,24 +184,8 @@ module.exports = {
184184
'@sentry-internal/sdk/no-optional-chaining': 'off',
185185
'@sentry-internal/sdk/no-nullish-coalescing': 'off',
186186
'@typescript-eslint/no-floating-promises': 'off',
187-
},
188-
},
189-
{
190-
// Configuration only for test files (this won't apply to utils or other files in test directories)
191-
plugins: ['jest'],
192-
env: {
193-
jest: true,
194-
},
195-
files: ['test.ts', '*.test.ts', '*.test.tsx', '*.test.js', '*.test.jsx'],
196-
rules: {
197-
// Prevent permanent usage of `it.only`, `fit`, `test.only` etc
198-
// We want to avoid debugging leftovers making their way into the codebase
199-
'jest/no-focused-tests': 'error',
200-
201-
// Prevent permanent usage of `it.skip`, `xit`, `test.skip` etc
202-
// We want to avoid debugging leftovers making their way into the codebase
203-
// If there's a good reason to skip a test (e.g. bad flakiness), just add an ignore comment
204-
'jest/no-disabled-tests': 'error',
187+
'@sentry-internal/sdk/no-focused-tests': 'error',
188+
'@sentry-internal/sdk/no-skipped-tests': 'error',
205189
},
206190
},
207191
{

packages/eslint-plugin-sdk/src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ module.exports = {
1515
'no-eq-empty': require('./rules/no-eq-empty'),
1616
'no-class-field-initializers': require('./rules/no-class-field-initializers'),
1717
'no-regexp-constructor': require('./rules/no-regexp-constructor'),
18+
'no-focused-tests': require('./rules/no-focused-tests'),
19+
'no-skipped-tests': require('./rules/no-skipped-tests'),
1820
},
1921
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
/**
4+
* This rule was created to flag usages of the `.only` function in vitest and jest tests.
5+
* Usually, we don't want to commit focused tests as this causes other tests to be skipped.
6+
*/
7+
module.exports = {
8+
meta: {
9+
docs: {
10+
description: "Do not focus tests via `.only` to ensure we don't commit accidentally skip the other tests.",
11+
},
12+
schema: [],
13+
},
14+
create: function (context) {
15+
return {
16+
CallExpression(node) {
17+
if (
18+
node.callee.type === 'MemberExpression' &&
19+
node.callee.object.type === 'Identifier' &&
20+
['test', 'it', 'describe'].includes(node.callee.object.name) &&
21+
node.callee.property.type === 'Identifier' &&
22+
node.callee.property.name === 'only'
23+
) {
24+
context.report({
25+
node,
26+
message: "Do not focus tests via `.only` to ensure we don't commit accidentally skip the other tests.",
27+
});
28+
}
29+
},
30+
};
31+
},
32+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
/**
4+
* This rule was created to flag usages of the `.skip` function in vitest and jest tests.
5+
* Usually, we don't want to commit skipped tests as this causes other tests to be skipped.
6+
* Sometimes, skipping is valid (e.g. flaky tests), in which case, we can simply eslint-disable the rule.
7+
*/
8+
module.exports = {
9+
meta: {
10+
docs: {
11+
description: "Do not skip tests via `.skip` to ensure we don't commit accidentally skipped tests.",
12+
},
13+
schema: [],
14+
},
15+
create: function (context) {
16+
return {
17+
CallExpression(node) {
18+
if (
19+
node.callee.type === 'MemberExpression' &&
20+
node.callee.object.type === 'Identifier' &&
21+
['test', 'it', 'describe'].includes(node.callee.object.name) &&
22+
node.callee.property.type === 'Identifier' &&
23+
node.callee.property.name === 'skip'
24+
) {
25+
context.report({
26+
node,
27+
message: "Do not skip tests via `.skip` to ensure we don't commit accidentally skipped tests.",
28+
});
29+
}
30+
},
31+
};
32+
},
33+
};

packages/gatsby/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"@sentry/react": "8.27.0",
5050
"@sentry/types": "8.27.0",
5151
"@sentry/utils": "8.27.0",
52-
"@sentry/webpack-plugin": "2.16.0"
52+
"@sentry/webpack-plugin": "2.22.3"
5353
},
5454
"peerDependencies": {
5555
"gatsby": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",

packages/nextjs/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
"@sentry/types": "8.27.0",
7979
"@sentry/utils": "8.27.0",
8080
"@sentry/vercel-edge": "8.27.0",
81-
"@sentry/webpack-plugin": "2.20.1",
81+
"@sentry/webpack-plugin": "2.22.3",
8282
"chalk": "3.0.0",
8383
"resolve": "1.22.8",
8484
"rollup": "3.29.4",

packages/nuxt/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"@sentry/opentelemetry": "8.27.0",
5050
"@sentry/types": "8.27.0",
5151
"@sentry/utils": "8.27.0",
52-
"@sentry/vite-plugin": "2.20.1",
52+
"@sentry/vite-plugin": "2.22.3",
5353
"@sentry/vue": "8.27.0"
5454
},
5555
"devDependencies": {

packages/profiling-node/test/cpu_profiler.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ describe('Profiler bindings', () => {
316316
expect(profile?.measurements?.['memory_footprint']?.values.length).toBeLessThanOrEqual(300);
317317
});
318318

319-
// eslint-disable-next-line jest/no-disabled-tests
319+
// eslint-disable-next-line @sentry-internal/sdk/no-skipped-tests
320320
it.skip('includes deopt reason', async () => {
321321
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#52-the-object-being-iterated-is-not-a-simple-enumerable
322322
function iterateOverLargeHashTable() {

packages/replay-internal/src/types/performance.ts

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ export interface WebVitalData {
111111
* The recording id of the web vital nodes. -1 if not found
112112
*/
113113
nodeIds?: number[];
114+
/**
115+
* The layout shifts of a CLS metric
116+
*/
117+
attributions?: { value: number; sources?: number[] }[];
114118
}
115119

116120
/**

packages/replay-internal/src/util/createPerformanceEntries.ts

+37-10
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ export interface Metric {
4343
* The array may also be empty if the metric value was not based on any
4444
* entries (e.g. a CLS value of 0 given no layout shifts).
4545
*/
46-
entries: PerformanceEntry[] | PerformanceEventTiming[];
46+
entries: PerformanceEntry[] | LayoutShift[];
47+
}
48+
49+
interface LayoutShift extends PerformanceEntry {
50+
value: number;
51+
sources: LayoutShiftAttribution[];
52+
hadRecentInput: boolean;
4753
}
4854

4955
interface LayoutShiftAttribution {
@@ -52,6 +58,11 @@ interface LayoutShiftAttribution {
5258
currentRect: DOMRectReadOnly;
5359
}
5460

61+
interface Attribution {
62+
value: number;
63+
nodeIds?: number[];
64+
}
65+
5566
/**
5667
* Handler creater for web vitals
5768
*/
@@ -187,22 +198,32 @@ export function getLargestContentfulPaint(metric: Metric): ReplayPerformanceEntr
187198
return getWebVital(metric, 'largest-contentful-paint', node);
188199
}
189200

201+
function isLayoutShift(entry: PerformanceEntry | LayoutShift): entry is LayoutShift {
202+
return (entry as LayoutShift).sources !== undefined;
203+
}
204+
190205
/**
191206
* Add a CLS event to the replay based on a CLS metric.
192207
*/
193208
export function getCumulativeLayoutShift(metric: Metric): ReplayPerformanceEntry<WebVitalData> {
194-
const lastEntry = metric.entries[metric.entries.length - 1] as
195-
| (PerformanceEntry & { sources?: LayoutShiftAttribution[] })
196-
| undefined;
209+
const layoutShifts: Attribution[] = [];
197210
const nodes: Node[] = [];
198-
if (lastEntry && lastEntry.sources) {
199-
for (const source of lastEntry.sources) {
200-
if (source.node) {
201-
nodes.push(source.node);
211+
for (const entry of metric.entries) {
212+
if (isLayoutShift(entry)) {
213+
const nodeIds = [];
214+
for (const source of entry.sources) {
215+
if (source.node) {
216+
nodes.push(source.node);
217+
const nodeId = record.mirror.getId(source.node);
218+
if (nodeId) {
219+
nodeIds.push(nodeId);
220+
}
221+
}
202222
}
223+
layoutShifts.push({ value: entry.value, nodeIds });
203224
}
204225
}
205-
return getWebVital(metric, 'cumulative-layout-shift', nodes);
226+
return getWebVital(metric, 'cumulative-layout-shift', nodes, layoutShifts);
206227
}
207228

208229
/**
@@ -226,7 +247,12 @@ export function getInteractionToNextPaint(metric: Metric): ReplayPerformanceEntr
226247
/**
227248
* Add an web vital event to the replay based on the web vital metric.
228249
*/
229-
function getWebVital(metric: Metric, name: string, nodes: Node[] | undefined): ReplayPerformanceEntry<WebVitalData> {
250+
function getWebVital(
251+
metric: Metric,
252+
name: string,
253+
nodes: Node[] | undefined,
254+
attributions?: Attribution[],
255+
): ReplayPerformanceEntry<WebVitalData> {
230256
const value = metric.value;
231257
const rating = metric.rating;
232258

@@ -242,6 +268,7 @@ function getWebVital(metric: Metric, name: string, nodes: Node[] | undefined): R
242268
size: value,
243269
rating,
244270
nodeIds: nodes ? nodes.map(node => record.mirror.getId(node)) : undefined,
271+
attributions,
245272
},
246273
};
247274

packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describe('Unit | util | createPerformanceEntries', () => {
8383
name: 'largest-contentful-paint',
8484
start: 1672531205.108299,
8585
end: 1672531205.108299,
86-
data: { value: 5108.299, rating: 'good', size: 5108.299, nodeIds: undefined },
86+
data: { value: 5108.299, rating: 'good', size: 5108.299, nodeIds: undefined, attributions: undefined },
8787
});
8888
});
8989
});
@@ -103,7 +103,7 @@ describe('Unit | util | createPerformanceEntries', () => {
103103
name: 'cumulative-layout-shift',
104104
start: 1672531205.108299,
105105
end: 1672531205.108299,
106-
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: [] },
106+
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: [], attributions: [] },
107107
});
108108
});
109109
});
@@ -123,7 +123,7 @@ describe('Unit | util | createPerformanceEntries', () => {
123123
name: 'first-input-delay',
124124
start: 1672531205.108299,
125125
end: 1672531205.108299,
126-
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: undefined },
126+
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: undefined, attributions: undefined },
127127
});
128128
});
129129
});
@@ -143,7 +143,7 @@ describe('Unit | util | createPerformanceEntries', () => {
143143
name: 'interaction-to-next-paint',
144144
start: 1672531205.108299,
145145
end: 1672531205.108299,
146-
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: undefined },
146+
data: { value: 5108.299, size: 5108.299, rating: 'good', nodeIds: undefined, attributions: undefined },
147147
});
148148
});
149149
});

packages/solidstart/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"@sentry/solid": "8.27.0",
7474
"@sentry/types": "8.27.0",
7575
"@sentry/utils": "8.27.0",
76-
"@sentry/vite-plugin": "2.19.0"
76+
"@sentry/vite-plugin": "2.22.3"
7777
},
7878
"devDependencies": {
7979
"@solidjs/router": "^0.13.4",

packages/sveltekit/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"@sentry/svelte": "8.27.0",
4747
"@sentry/types": "8.27.0",
4848
"@sentry/utils": "8.27.0",
49-
"@sentry/vite-plugin": "2.22.0",
49+
"@sentry/vite-plugin": "2.22.3",
5050
"magic-string": "0.30.7",
5151
"magicast": "0.2.8",
5252
"sorcery": "0.11.0"

0 commit comments

Comments
 (0)