@parca/profile 0.19.107 → 0.19.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.19.108](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.107...@parca/profile@0.19.108) (2026-01-05)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.19.107](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.106...@parca/profile@0.19.107) (2025-12-22)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAOnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAO1C,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,kIAalB,gBAAgB,KAAG,GAAG,CAAC,OAwOzB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAOnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,GAAI,kIAalB,gBAAgB,KAAG,GAAG,CAAC,OAyOzB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -17,6 +17,7 @@ import { Item, Menu, Separator, Submenu } from 'react-contexify';
17
17
  import { Tooltip } from 'react-tooltip';
18
18
  import { useParcaContext, useURLState } from '@parca/components';
19
19
  import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
20
+ import { TEST_IDS } from '@parca/test-utils';
20
21
  import { getLastItem } from '@parca/utilities';
21
22
  import { useGraphTooltip } from '../../GraphTooltipArrow/useGraphTooltip';
22
23
  import { useGraphTooltipMetaInfo } from '../../GraphTooltipArrow/useGraphTooltipMetaInfo';
@@ -92,7 +93,7 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, compareAbsolu
92
93
  else {
93
94
  setDashboardItems([...dashboardItems, 'table']);
94
95
  }
95
- }, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), enableSandwichView === true && (_jsx(Item, { id: "show-in-sandwich", onClick: () => {
96
+ }, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), enableSandwichView === true && (_jsx(Item, { id: "show-in-sandwich", "data-testid": TEST_IDS.CONTEXT_MENU_SHOW_IN_SANDWICH, onClick: () => {
96
97
  if (functionName === '' || functionName == null) {
97
98
  return;
98
99
  }
@@ -106,7 +106,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
106
106
  : { isValid: true, isNonDelta: false, isDurationTooLong: false };
107
107
  const isInvalidFlameChartQuery = isFlameChart && !isFlameChartValid;
108
108
  if (isLoading && !isInvalidFlameChartQuery) {
109
- return (_jsx("div", { className: "h-auto overflow-clip", children: isRenderedAsFlamegraph ? (_jsx(SandwichFlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(FlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
109
+ return (_jsx("div", { className: "h-auto overflow-clip", "data-testid": TEST_IDS.FLAMEGRAPH_SKELETON, children: isRenderedAsFlamegraph ? (_jsx(SandwichFlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(FlameGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
110
110
  }
111
111
  // Do necessary checks to ensure that flame chart can be rendered for this query.
112
112
  if (isInvalidFlameChartQuery) {
@@ -1 +1 @@
1
- {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAErE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA2BnC"}
1
+ {"version":3,"file":"CalleesSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CalleesSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAErE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,GAChB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CA+BnC"}
@@ -1,5 +1,6 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { TEST_IDS, testId } from '@parca/test-utils';
2
3
  import ProfileFlameGraph from '../../ProfileFlameGraph';
3
4
  export function CalleesSection({ calleesRef, calleesFlamegraphData, profileSource, curPathArrow, setCurPathArrow, }) {
4
- return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileFlameGraph, { arrow: calleesFlamegraphData?.arrow, total: calleesFlamegraphData.total ?? BigInt(0), filtered: calleesFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: calleesFlamegraphData.loading, error: calleesFlamegraphData.error, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: calleesFlamegraphData.metadataMappingFiles, metadataLoading: calleesFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
5
+ return (_jsxs("div", { className: "flex relative items-start flex-row", ref: calleesRef, ...testId(TEST_IDS.SANDWICH_CALLEES_SECTION), children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left", children: ['<-', " Callees"] }), _jsx(ProfileFlameGraph, { arrow: calleesFlamegraphData?.arrow, total: calleesFlamegraphData.total ?? BigInt(0), filtered: calleesFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: calleesFlamegraphData.loading, error: calleesFlamegraphData.error, isHalfScreen: true, width: calleesRef.current != null ? calleesRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: calleesFlamegraphData.metadataMappingFiles, metadataLoading: calleesFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, profileSource: profileSource, tooltipId: "callees" })] }));
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAQrC,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAerE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAiEnC"}
1
+ {"version":3,"file":"CallersSection.d.ts","sourceRoot":"","sources":["../../../src/Sandwich/components/CallersSection.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AASrC,OAAO,EAAC,KAAK,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAerE,UAAU,mBAAmB;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,qBAAqB,EAAE,cAAc,CAAC;IACtC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,UAAU,EACV,aAAa,EACb,gBAAgB,GACjB,EAAE,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAqEnC"}
@@ -15,6 +15,7 @@ import { useMemo } from 'react';
15
15
  import { tableFromIPC } from 'apache-arrow';
16
16
  import { Tooltip } from 'react-tooltip';
17
17
  import { Button } from '@parca/components';
18
+ import { TEST_IDS, testId } from '@parca/test-utils';
18
19
  import ProfileFlameGraph from '../../ProfileFlameGraph';
19
20
  const FIELD_DEPTH = 'depth';
20
21
  function getMaxDepth(depthColumn) {
@@ -40,5 +41,5 @@ export function CallersSection({ callersRef, callersFlamegraphData, profileSourc
40
41
  const shouldShowButton = maxDepth > defaultMaxFrames;
41
42
  return (_jsxs(_Fragment, { children: [shouldShowButton && (_jsxs(Button, { variant: "neutral", onClick: () => setIsExpanded(!isExpanded), className: "absolute right-8 top-[-46px] z-10", type: "button", children: [_jsx("span", { "data-tooltip-content": !isExpanded
42
43
  ? `This profile has ${maxDepth} frames, showing only the top ${defaultMaxFrames} frames. Click to show more frames.`
43
- : `This profile has ${maxDepth} frames, showing all frames. Click to hide frames.`, "data-tooltip-id": "show-more-frames", children: isExpanded ? 'Hide frames' : 'Show more frames' }), _jsx(Tooltip, { id: "show-more-frames" })] })), _jsxs("div", { className: "flex relative flex-row overflow-hidden", ref: callersRef, children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0", children: ["Callers ", '->'] }), _jsx("div", { className: "flex-1 overflow-hidden relative", children: _jsx(ProfileFlameGraph, { arrow: callersFlamegraphData?.arrow, total: callersFlamegraphData.total ?? BigInt(0), filtered: callersFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: callersFlamegraphData.loading, error: callersFlamegraphData.error, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: callersFlamegraphData.metadataMappingFiles, metadataLoading: callersFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
44
+ : `This profile has ${maxDepth} frames, showing all frames. Click to hide frames.`, "data-tooltip-id": "show-more-frames", children: isExpanded ? 'Hide frames' : 'Show more frames' }), _jsx(Tooltip, { id: "show-more-frames" })] })), _jsxs("div", { className: "flex relative flex-row overflow-hidden", ref: callersRef, ...testId(TEST_IDS.SANDWICH_CALLERS_SECTION), children: [_jsxs("div", { className: "[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0", children: ["Callers ", '->'] }), _jsx("div", { className: "flex-1 overflow-hidden relative", children: _jsx(ProfileFlameGraph, { arrow: callersFlamegraphData?.arrow, total: callersFlamegraphData.total ?? BigInt(0), filtered: callersFlamegraphData.filtered ?? BigInt(0), profileType: profileSource?.ProfileType(), loading: callersFlamegraphData.loading, error: callersFlamegraphData.error, isHalfScreen: true, width: callersRef.current != null ? callersRef.current.getBoundingClientRect().width - 25 : 0, metadataMappingFiles: callersFlamegraphData.metadataMappingFiles, metadataLoading: callersFlamegraphData.metadataLoading, isInSandwichView: true, curPathArrow: curPathArrow, setNewCurPathArrow: setCurPathArrow, isRenderedAsFlamegraph: true, profileSource: profileSource, tooltipId: "callers", maxFrameCount: defaultMaxFrames, isExpanded: isExpanded }) })] })] }));
44
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAM9C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAIhE,UAAU,KAAK;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,mCAoEZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Sandwich/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAyB,MAAM,OAAO,CAAC;AAO9C,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAC,YAAY,EAAC,MAAM,oCAAoC,CAAC;AAIhE,UAAU,KAAK;IACb,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,QAAA,MAAM,QAAQ,mCAuEZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -14,6 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  import React, { useRef, useState } from 'react';
15
15
  import { AnimatePresence, motion } from 'framer-motion';
16
16
  import { useURLState } from '@parca/components';
17
+ import { TEST_IDS, testId } from '@parca/test-utils';
17
18
  import { useDashboard } from '../ProfileView/context/DashboardContext';
18
19
  import { useVisualizationState } from '../ProfileView/hooks/useVisualizationState';
19
20
  import { CalleesSection } from './components/CalleesSection';
@@ -27,6 +28,6 @@ const Sandwich = React.memo(function Sandwich({ sandwichData, profileSource, })
27
28
  const defaultMaxFrames = 10;
28
29
  const callersCalleesContainerRef = useRef(null);
29
30
  const { curPathArrow, setCurPathArrow } = useVisualizationState();
30
- return (_jsx("section", { className: "flex flex-row h-full w-full", children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsx("div", { className: "relative flex flex-row", children: sandwichFunctionName !== undefined ? (_jsxs("div", { className: "w-full flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, callersFlamegraphData: sandwichData.callers, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphData: sandwichData.callees, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
31
+ return (_jsx("section", { className: "flex flex-row h-full w-full", ...testId(TEST_IDS.SANDWICH_CONTAINER), children: _jsx(AnimatePresence, { children: _jsx(motion.div, { className: "h-full w-full", initial: { display: 'none', opacity: 0 }, animate: { display: 'block', opacity: 1 }, transition: { duration: 0.5 }, children: _jsx("div", { className: "relative flex flex-row", children: sandwichFunctionName !== undefined ? (_jsxs("div", { className: "w-full flex flex-col", ref: callersCalleesContainerRef, children: [_jsx(CallersSection, { callersRef: callersRef, callersFlamegraphData: sandwichData.callers, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow, isExpanded: isExpanded, setIsExpanded: setIsExpanded, defaultMaxFrames: defaultMaxFrames }), _jsx("div", { className: "h-4" }), _jsx(CalleesSection, { calleesRef: calleesRef, calleesFlamegraphData: sandwichData.callees, profileSource: profileSource, curPathArrow: curPathArrow, setCurPathArrow: setCurPathArrow })] })) : (_jsx("div", { className: "items-center justify-center flex h-full w-full", ...testId(TEST_IDS.SANDWICH_NO_FUNCTION_SELECTED), children: _jsx("p", { className: "text-sm", children: dashboardItems.includes('table') ? ('Please select a function to view its callers and callees.') : (_jsxs(_Fragment, { children: ["Use the right-click menu on the Flame", ' ', dashboardItems.includes('flamegraph') ? 'Graph' : 'Chart', " to choose a function to view its callers and callees."] })) }) })) }) }, "sandwich-loaded") }) }));
31
32
  });
32
33
  export default Sandwich;
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.19.107",
3
+ "version": "0.19.108",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@floating-ui/react": "^0.27.12",
7
7
  "@headlessui/react": "^1.7.19",
8
8
  "@iconify/react": "^4.0.0",
9
9
  "@parca/client": "0.17.16",
10
- "@parca/components": "0.16.394",
10
+ "@parca/components": "0.16.395",
11
11
  "@parca/dynamicsize": "0.16.72",
12
12
  "@parca/hooks": "0.0.116",
13
13
  "@parca/icons": "0.16.79",
14
14
  "@parca/parser": "0.16.86",
15
15
  "@parca/store": "0.16.199",
16
- "@parca/test-utils": "0.0.19",
16
+ "@parca/test-utils": "0.0.20",
17
17
  "@parca/utilities": "0.0.122",
18
18
  "@popperjs/core": "^2.11.8",
19
19
  "@protobuf-ts/runtime-rpc": "^2.5.0",
@@ -84,5 +84,5 @@
84
84
  "access": "public",
85
85
  "registry": "https://registry.npmjs.org/"
86
86
  },
87
- "gitHead": "dc8ae4a8f538ea9f3c16e8f9047970c2ce2b8c2f"
87
+ "gitHead": "062ac8ece420950b51220c40eaa2056e7e6e6493"
88
88
  }
@@ -20,6 +20,7 @@ import {Tooltip} from 'react-tooltip';
20
20
  import {useParcaContext, useURLState} from '@parca/components';
21
21
  import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
22
22
  import {ProfileType} from '@parca/parser';
23
+ import {TEST_IDS} from '@parca/test-utils';
23
24
  import {getLastItem} from '@parca/utilities';
24
25
 
25
26
  import {useGraphTooltip} from '../../GraphTooltipArrow/useGraphTooltip';
@@ -187,6 +188,7 @@ const ContextMenu = ({
187
188
  {enableSandwichView === true && (
188
189
  <Item
189
190
  id="show-in-sandwich"
191
+ data-testid={TEST_IDS.CONTEXT_MENU_SHOW_IN_SANDWICH}
190
192
  onClick={() => {
191
193
  if (functionName === '' || functionName == null) {
192
194
  return;
@@ -205,7 +205,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
205
205
 
206
206
  if (isLoading && !isInvalidFlameChartQuery) {
207
207
  return (
208
- <div className="h-auto overflow-clip">
208
+ <div className="h-auto overflow-clip" data-testid={TEST_IDS.FLAMEGRAPH_SKELETON}>
209
209
  {isRenderedAsFlamegraph ? (
210
210
  <SandwichFlameGraphSkeleton isHalfScreen={isHalfScreen} isDarkMode={isDarkMode} />
211
211
  ) : (
@@ -13,6 +13,8 @@
13
13
 
14
14
  import React from 'react';
15
15
 
16
+ import {TEST_IDS, testId} from '@parca/test-utils';
17
+
16
18
  import ProfileFlameGraph from '../../ProfileFlameGraph';
17
19
  import {type CurrentPathFrame} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
18
20
  import {type ProfileSource} from '../../ProfileSource';
@@ -35,7 +37,11 @@ export function CalleesSection({
35
37
  setCurPathArrow,
36
38
  }: CalleesSectionProps): JSX.Element {
37
39
  return (
38
- <div className="flex relative items-start flex-row" ref={calleesRef}>
40
+ <div
41
+ className="flex relative items-start flex-row"
42
+ ref={calleesRef}
43
+ {...testId(TEST_IDS.SANDWICH_CALLEES_SECTION)}
44
+ >
39
45
  <div className="[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left">
40
46
  {'<-'} Callees
41
47
  </div>
@@ -17,6 +17,7 @@ import {Vector, tableFromIPC} from 'apache-arrow';
17
17
  import {Tooltip} from 'react-tooltip';
18
18
 
19
19
  import {Button} from '@parca/components';
20
+ import {TEST_IDS, testId} from '@parca/test-utils';
20
21
 
21
22
  import ProfileFlameGraph from '../../ProfileFlameGraph';
22
23
  import {type CurrentPathFrame} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
@@ -90,7 +91,11 @@ export function CallersSection({
90
91
  <Tooltip id="show-more-frames" />
91
92
  </Button>
92
93
  )}
93
- <div className="flex relative flex-row overflow-hidden" ref={callersRef}>
94
+ <div
95
+ className="flex relative flex-row overflow-hidden"
96
+ ref={callersRef}
97
+ {...testId(TEST_IDS.SANDWICH_CALLERS_SECTION)}
98
+ >
94
99
  <div className="[writing-mode:vertical-lr] -rotate-180 px-1 uppercase text-[10px] text-left flex-shrink-0">
95
100
  Callers {'->'}
96
101
  </div>
@@ -16,6 +16,7 @@ import React, {useRef, useState} from 'react';
16
16
  import {AnimatePresence, motion} from 'framer-motion';
17
17
 
18
18
  import {useURLState} from '@parca/components';
19
+ import {TEST_IDS, testId} from '@parca/test-utils';
19
20
 
20
21
  import {ProfileSource} from '../ProfileSource';
21
22
  import {useDashboard} from '../ProfileView/context/DashboardContext';
@@ -46,7 +47,7 @@ const Sandwich = React.memo(function Sandwich({
46
47
  const {curPathArrow, setCurPathArrow} = useVisualizationState();
47
48
 
48
49
  return (
49
- <section className="flex flex-row h-full w-full">
50
+ <section className="flex flex-row h-full w-full" {...testId(TEST_IDS.SANDWICH_CONTAINER)}>
50
51
  <AnimatePresence>
51
52
  <motion.div
52
53
  className="h-full w-full"
@@ -78,7 +79,10 @@ const Sandwich = React.memo(function Sandwich({
78
79
  />
79
80
  </div>
80
81
  ) : (
81
- <div className="items-center justify-center flex h-full w-full">
82
+ <div
83
+ className="items-center justify-center flex h-full w-full"
84
+ {...testId(TEST_IDS.SANDWICH_NO_FUNCTION_SELECTED)}
85
+ >
82
86
  <p className="text-sm">
83
87
  {dashboardItems.includes('table') ? (
84
88
  'Please select a function to view its callers and callees.'