@marimo-team/islands 0.24.3-dev1 → 0.24.3-dev13
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/dist/{ConnectedDataExplorerComponent-qIKbwYin.js → ConnectedDataExplorerComponent-C9OF_75w.js} +1 -1
- package/dist/{any-language-editor-CpTnK43-.js → any-language-editor-DmQ7dyCx.js} +1 -1
- package/dist/{chat-ui-DttQ-5Ut.js → chat-ui-CH7Gg-KH.js} +1300 -1300
- package/dist/{common-C7aHdgSC.js → common-DM9Wj-cL.js} +6484 -6276
- package/dist/{error-banner-WDhUzJyg.js → error-banner-CsXbEEjo.js} +160 -160
- package/dist/{formats-CJMVUfb3.js → formats-CslNOKy0.js} +1 -1
- package/dist/{html-to-image-BTYnN4ev.js → html-to-image-B3oyXfx7.js} +10 -9
- package/dist/main.js +257 -243
- package/dist/{mermaid-BsHdQeQf.js → mermaid-Bi23Ibnw.js} +1 -1
- package/dist/{process-output-CsALk6tp.js → process-output-ew3B35of.js} +2 -2
- package/dist/{reveal-component-DsDcTC8C.js → reveal-component-DjEi3rsH.js} +2 -2
- package/dist/{toDate-D-Rx3ux5.js → toDate-CpXBeDq0.js} +3 -2
- package/dist/{vega-component-D-IXRnlx.js → vega-component-ovBXgp91.js} +3 -3
- package/package.json +1 -1
- package/src/__mocks__/requests.ts +7 -2
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +2 -6
- package/src/components/data-table/column-visibility-dropdown.tsx +9 -3
- package/src/components/datasources/components.tsx +4 -2
- package/src/components/editor/chrome/components/feedback-button.tsx +10 -9
- package/src/components/editor/chrome/panels/__tests__/packages-panel.test.tsx +143 -0
- package/src/components/editor/chrome/panels/packages-panel.tsx +145 -51
- package/src/components/editor/code/__tests__/readonly-diff.test.tsx +65 -0
- package/src/components/editor/code/readonly-diff.tsx +1 -1
- package/src/components/editor/file-tree/__tests__/tree-actions.test.tsx +54 -0
- package/src/components/editor/file-tree/tree-actions.tsx +11 -14
- package/src/components/editor/package-alert.tsx +25 -1
- package/src/components/home/components.tsx +17 -0
- package/src/components/pages/gallery-page.tsx +2 -4
- package/src/components/pages/home-page.tsx +2 -4
- package/src/components/terminal/terminal.tsx +4 -4
- package/src/core/cells/pending-delete-service.ts +12 -16
- package/src/core/codemirror/language/__tests__/sql.test.ts +70 -2
- package/src/core/codemirror/language/languages/sql/sql.ts +16 -1
- package/src/core/datasets/__tests__/data-source.test.ts +2 -0
- package/src/core/datasets/data-source-connections.ts +15 -10
- package/src/core/islands/__tests__/parse.test.ts +140 -7
- package/src/core/islands/parse.ts +20 -0
- package/src/core/packages/__tests__/useInstallPackage.test.tsx +47 -1
- package/src/core/packages/toast-components.tsx +26 -0
- package/src/core/packages/useInstallPackage.ts +7 -2
- package/src/core/runtime/__tests__/runtime.test.ts +11 -0
- package/src/core/runtime/runtime.ts +7 -2
- package/src/core/wasm/bridge.ts +1 -0
- package/src/plugins/layout/AccordionPlugin.tsx +7 -2
- package/src/plugins/layout/__test__/AccordionPlugin.test.tsx +66 -0
|
@@ -3,7 +3,7 @@ import { g as t } from "./button-CKBkqR9J.js";
|
|
|
3
3
|
import { t as n } from "./react-DMWcHin-.js";
|
|
4
4
|
import { t as r } from "./compiler-runtime-CAH9RLw2.js";
|
|
5
5
|
import { t as i } from "./jsx-runtime-CpoKNRgu.js";
|
|
6
|
-
import { n as a } from "./error-banner-
|
|
6
|
+
import { n as a } from "./error-banner-CsXbEEjo.js";
|
|
7
7
|
import { n as o } from "./useTheme-CVJ0UOf2.js";
|
|
8
8
|
import { t as s } from "./useAsyncData-CH6-CgJF.js";
|
|
9
9
|
import { t as c } from "./purify.es-CB-YO1Hn.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as e, nt as t,
|
|
1
|
+
import { O as e, nt as t, rt as n } from "./html-to-image-B3oyXfx7.js";
|
|
2
2
|
import { u as r } from "./dist-3_o3T78I.js";
|
|
3
3
|
import { b as i } from "./select-3qHpFKF9.js";
|
|
4
4
|
import { n as a } from "./semaphore-89jsoHtS.js";
|
|
@@ -73,7 +73,7 @@ function v(e) {
|
|
|
73
73
|
//#endregion
|
|
74
74
|
//#region src/components/editor/output/console/process-output.ts
|
|
75
75
|
function y(e) {
|
|
76
|
-
return e.mimetype.startsWith("application/vnd.marimo") || e.mimetype === "text/html" ?
|
|
76
|
+
return e.mimetype.startsWith("application/vnd.marimo") || e.mimetype === "text/html" ? n(i.asString(e.data)) : t(i.asString(e.data));
|
|
77
77
|
}
|
|
78
78
|
//#endregion
|
|
79
79
|
export { d as a, h as c, s as d, o as f, m as i, c as l, _ as n, p as o, v as r, f as s, y as t, l as u };
|
|
@@ -2,9 +2,9 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
|
|
|
2
2
|
import { c as t, g as n, h as r, m as i, t as a } from "./button-CKBkqR9J.js";
|
|
3
3
|
import { t as o } from "./react-DMWcHin-.js";
|
|
4
4
|
import { t as s } from "./compiler-runtime-CAH9RLw2.js";
|
|
5
|
-
import {
|
|
5
|
+
import { kt as c, st as l } from "./html-to-image-B3oyXfx7.js";
|
|
6
6
|
import { u } from "./dist-3_o3T78I.js";
|
|
7
|
-
import { _n as d, c as f, ct as p, g as m, h, l as g, lt as _, n as v, o as y, r as b, t as x, u as S, ut as C, vn as w, xn as T } from "./common-
|
|
7
|
+
import { _n as d, c as f, ct as p, g as m, h, l as g, lt as _, n as v, o as y, r as b, t as x, u as S, ut as C, vn as w, xn as T } from "./common-DM9Wj-cL.js";
|
|
8
8
|
import { R as E } from "./select-3qHpFKF9.js";
|
|
9
9
|
import { Y as D } from "./dropdown-menu-DhCfcscX.js";
|
|
10
10
|
import { t as O } from "./jsx-runtime-CpoKNRgu.js";
|
|
@@ -554,8 +554,9 @@ var P = class {
|
|
|
554
554
|
getWsSyncURL(e) {
|
|
555
555
|
return this.formatWsURL("/ws_sync", this.getSessionSearchParams(e));
|
|
556
556
|
}
|
|
557
|
-
getTerminalWsURL() {
|
|
558
|
-
|
|
557
|
+
getTerminalWsURL(e) {
|
|
558
|
+
let t = this.formatWsURL("/terminal/ws");
|
|
559
|
+
return e && (t.searchParams.set("rows", String(e.rows)), t.searchParams.set("cols", String(e.cols))), t;
|
|
559
560
|
}
|
|
560
561
|
getLSPURL(e) {
|
|
561
562
|
if (e === "copilot") {
|
|
@@ -2,16 +2,16 @@ import { a as e } from "./rolldown-runtime-Cb76FRpK.js";
|
|
|
2
2
|
import { g as t, h as n, m as r, o as i } from "./button-CKBkqR9J.js";
|
|
3
3
|
import { t as a } from "./react-DMWcHin-.js";
|
|
4
4
|
import { t as o } from "./compiler-runtime-CAH9RLw2.js";
|
|
5
|
-
import { c as s, v as c } from "./toDate-
|
|
5
|
+
import { c as s, v as c } from "./toDate-CpXBeDq0.js";
|
|
6
6
|
import { t as l } from "./jsx-runtime-CpoKNRgu.js";
|
|
7
|
-
import { n as u } from "./error-banner-
|
|
7
|
+
import { n as u } from "./error-banner-CsXbEEjo.js";
|
|
8
8
|
import { t as d } from "./tooltip-Dt77sBeT.js";
|
|
9
9
|
import { t as f } from "./debounce-C3jyATpc.js";
|
|
10
10
|
import { j as p, n as ee } from "./useTheme-CVJ0UOf2.js";
|
|
11
11
|
import { c as m } from "./arrays-CN1djC4k.js";
|
|
12
12
|
import { t as te } from "./objects-CzUgoMIF.js";
|
|
13
13
|
import { t as h } from "./useAsyncData-CH6-CgJF.js";
|
|
14
|
-
import { a as ne, i as re, n as ie, t as g } from "./formats-
|
|
14
|
+
import { a as ne, i as re, n as ie, t as g } from "./formats-CslNOKy0.js";
|
|
15
15
|
import { A as ae, n as oe } from "./vega-loader.browser-DEggZzni.js";
|
|
16
16
|
import { t as se } from "./react-vega-DSD5aT7_.js";
|
|
17
17
|
import { a as ce, n as _ } from "./loader-VZ__bv4g.js";
|
package/package.json
CHANGED
|
@@ -136,8 +136,13 @@ export const MockRequestClient = {
|
|
|
136
136
|
updateCellOutputs: vi.fn().mockResolvedValue({}),
|
|
137
137
|
addPackage: vi.fn().mockResolvedValue({}),
|
|
138
138
|
removePackage: vi.fn().mockResolvedValue({}),
|
|
139
|
-
getPackageList: vi.fn().mockResolvedValue({
|
|
140
|
-
|
|
139
|
+
getPackageList: vi.fn().mockResolvedValue({
|
|
140
|
+
packages: [],
|
|
141
|
+
}),
|
|
142
|
+
getDependencyTree: vi.fn().mockResolvedValue({
|
|
143
|
+
tree: null,
|
|
144
|
+
context: { kind: "package-manager", name: "pip" },
|
|
145
|
+
}),
|
|
141
146
|
listSecretKeys: vi.fn().mockResolvedValue({ keys: [] }),
|
|
142
147
|
writeSecret: vi.fn().mockResolvedValue({}),
|
|
143
148
|
invokeAiTool: vi.fn().mockResolvedValue({}),
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
EyeIcon,
|
|
11
11
|
EyeOffIcon,
|
|
12
12
|
} from "lucide-react";
|
|
13
|
-
import {
|
|
13
|
+
import { useState } from "react";
|
|
14
14
|
import { useLocale } from "react-aria";
|
|
15
15
|
import {
|
|
16
16
|
AddDataframeChart,
|
|
@@ -98,11 +98,7 @@ export function ColumnExplorerPanel<TData>({
|
|
|
98
98
|
hiddenColumns: hiddenColumnCount,
|
|
99
99
|
} = getColumnCountForDisplay(table, totalColumns);
|
|
100
100
|
const { visible: visibleColumnCount } = getUserColumnVisibilityCounts(table);
|
|
101
|
-
const
|
|
102
|
-
const showOnlyColumnState = useMemo(
|
|
103
|
-
() => getShowOnlyColumnState(table),
|
|
104
|
-
[table, columnVisibility],
|
|
105
|
-
);
|
|
101
|
+
const showOnlyColumnState = getShowOnlyColumnState(table);
|
|
106
102
|
|
|
107
103
|
const { rowsAndColumns, hiddenSuffix } = prettifyRowColumnCount({
|
|
108
104
|
numRows: totalRows,
|
|
@@ -215,6 +215,11 @@ export const ColumnVisibilityDropdown = <TData,>({
|
|
|
215
215
|
index === list.pinnedCount &&
|
|
216
216
|
list.pinnedCount > 0 &&
|
|
217
217
|
list.pinnedCount < list.visibleOptions.length;
|
|
218
|
+
const label = (
|
|
219
|
+
<span className="truncate" title={option.label}>
|
|
220
|
+
{option.label}
|
|
221
|
+
</span>
|
|
222
|
+
);
|
|
218
223
|
return (
|
|
219
224
|
<React.Fragment key={option.value}>
|
|
220
225
|
{isSectionBoundary && <CommandSeparator />}
|
|
@@ -225,15 +230,16 @@ export const ColumnVisibilityDropdown = <TData,>({
|
|
|
225
230
|
className="flex items-center gap-1.5 cursor-pointer"
|
|
226
231
|
>
|
|
227
232
|
{dataType === undefined ? (
|
|
228
|
-
|
|
233
|
+
label
|
|
229
234
|
) : (
|
|
230
235
|
<ColumnName
|
|
231
|
-
|
|
236
|
+
className="min-w-0"
|
|
237
|
+
columnName={label}
|
|
232
238
|
dataType={dataType}
|
|
233
239
|
/>
|
|
234
240
|
)}
|
|
235
241
|
{!option.disabled && (
|
|
236
|
-
<span className="ml-auto flex items-center gap-0.5">
|
|
242
|
+
<span className="ml-auto flex shrink-0 items-center gap-0.5">
|
|
237
243
|
<ShowOnlyColumnButton
|
|
238
244
|
table={table}
|
|
239
245
|
columnIds={[option.value]}
|
|
@@ -101,18 +101,20 @@ export const ColumnPreviewContainer: React.FC<{
|
|
|
101
101
|
export const ColumnName = ({
|
|
102
102
|
columnName,
|
|
103
103
|
dataType,
|
|
104
|
+
className,
|
|
104
105
|
}: {
|
|
105
106
|
columnName: React.ReactNode;
|
|
106
107
|
dataType: DataType;
|
|
108
|
+
className?: string;
|
|
107
109
|
}) => {
|
|
108
110
|
const resolvedDataType = resolveDataType(dataType);
|
|
109
111
|
const Icon = DATA_TYPE_ICON[resolvedDataType];
|
|
110
112
|
const color = getDataTypeColor(resolvedDataType);
|
|
111
113
|
|
|
112
114
|
return (
|
|
113
|
-
<div className="flex flex-row items-center gap-1.5">
|
|
115
|
+
<div className={cn("flex flex-row items-center gap-1.5", className)}>
|
|
114
116
|
<Icon
|
|
115
|
-
className={`w-4 h-4 p-0.5 rounded-sm stroke-card-foreground ${color}`}
|
|
117
|
+
className={`w-4 h-4 shrink-0 p-0.5 rounded-sm stroke-card-foreground ${color}`}
|
|
116
118
|
/>
|
|
117
119
|
{columnName}
|
|
118
120
|
</div>
|
|
@@ -6,7 +6,7 @@ const Slot = SlotPrimitive.Slot;
|
|
|
6
6
|
|
|
7
7
|
import { useAtomValue } from "jotai";
|
|
8
8
|
import { ExternalLinkIcon, TriangleAlertIcon } from "lucide-react";
|
|
9
|
-
import React, { type PropsWithChildren,
|
|
9
|
+
import React, { type PropsWithChildren, useState } from "react";
|
|
10
10
|
import { CopyClipboardIcon } from "@/components/icons/copy-icon";
|
|
11
11
|
import { useImperativeModal } from "@/components/modal/ImperativeModal";
|
|
12
12
|
import { Button } from "@/components/ui/button";
|
|
@@ -94,8 +94,7 @@ export const FeedbackModal: React.FC<{
|
|
|
94
94
|
);
|
|
95
95
|
|
|
96
96
|
const notebook = useAtomValue(notebookAtom);
|
|
97
|
-
|
|
98
|
-
const errors = useMemo(() => getCellErrorEntries(store), [notebook]);
|
|
97
|
+
const errors = getCellErrorEntries(store);
|
|
99
98
|
|
|
100
99
|
const cells = notebook.cellIds.inOrderIds.map(
|
|
101
100
|
(cellId) => notebook.cellData[cellId],
|
|
@@ -145,10 +144,9 @@ export const FeedbackModal: React.FC<{
|
|
|
145
144
|
return contents;
|
|
146
145
|
}, [includeCode, notebookSourceAvailable, readCode]);
|
|
147
146
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
147
|
+
let githubIssueUrl = Constants.bugReportUrl;
|
|
148
|
+
let omitted: string[] = [];
|
|
149
|
+
if (environment) {
|
|
152
150
|
const fields: Record<string, string> = {
|
|
153
151
|
env: formatEnvironmentSection(environment),
|
|
154
152
|
};
|
|
@@ -158,8 +156,11 @@ export const FeedbackModal: React.FC<{
|
|
|
158
156
|
if (includeCode && codeRequest.data) {
|
|
159
157
|
fields["reproduction-code"] = formatCodeSection(codeRequest.data);
|
|
160
158
|
}
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
({ url: githubIssueUrl, omitted } = buildBugReportUrl(
|
|
160
|
+
Constants.bugReportUrl,
|
|
161
|
+
fields,
|
|
162
|
+
));
|
|
163
|
+
}
|
|
163
164
|
|
|
164
165
|
const omittedLabels = omitted
|
|
165
166
|
.map((field) =>
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { Provider } from "jotai";
|
|
5
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { MockRequestClient } from "@/__mocks__/requests";
|
|
7
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
8
|
+
import { requestClientAtom } from "@/core/network/requests";
|
|
9
|
+
import type {
|
|
10
|
+
DependencyTreeNode,
|
|
11
|
+
DependencyTreeResponse,
|
|
12
|
+
} from "@/core/network/types";
|
|
13
|
+
import { store } from "@/core/state/jotai";
|
|
14
|
+
import PackagesPanel from "../packages-panel";
|
|
15
|
+
|
|
16
|
+
const { openSettings } = vi.hoisted(() => ({
|
|
17
|
+
openSettings: vi.fn(),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
vi.mock("@/components/app-config/state", () => ({
|
|
21
|
+
useOpenSettingsToTab: () => ({ handleClick: openSettings }),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
const emptyTree: DependencyTreeNode = {
|
|
25
|
+
name: "<root>",
|
|
26
|
+
version: null,
|
|
27
|
+
tags: [],
|
|
28
|
+
dependencies: [],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const populatedTree: DependencyTreeNode = {
|
|
32
|
+
...emptyTree,
|
|
33
|
+
dependencies: [
|
|
34
|
+
{
|
|
35
|
+
name: "polars",
|
|
36
|
+
version: "1.44.1",
|
|
37
|
+
tags: [],
|
|
38
|
+
dependencies: [
|
|
39
|
+
{
|
|
40
|
+
name: "numpy",
|
|
41
|
+
version: "2.5.2",
|
|
42
|
+
tags: [{ kind: "dedupe", value: "true" }],
|
|
43
|
+
dependencies: [],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function renderPanel(
|
|
51
|
+
context: DependencyTreeResponse["context"],
|
|
52
|
+
tree: DependencyTreeNode = emptyTree,
|
|
53
|
+
) {
|
|
54
|
+
const getPackageList = vi.fn().mockResolvedValue({ packages: [] });
|
|
55
|
+
store.set(
|
|
56
|
+
requestClientAtom,
|
|
57
|
+
MockRequestClient.create({
|
|
58
|
+
getPackageList,
|
|
59
|
+
getDependencyTree: vi.fn().mockResolvedValue({ tree, context }),
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
getPackageList,
|
|
65
|
+
...render(
|
|
66
|
+
<Provider store={store}>
|
|
67
|
+
<TooltipProvider>
|
|
68
|
+
<PackagesPanel />
|
|
69
|
+
</TooltipProvider>
|
|
70
|
+
</Provider>,
|
|
71
|
+
),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
describe("PackagesPanel", () => {
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
vi.clearAllMocks();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it.each(["pixi", "uv"] as const)(
|
|
81
|
+
"shows the effective %s sandbox backend as a fixed context",
|
|
82
|
+
async (backend) => {
|
|
83
|
+
const { getPackageList } = renderPanel({ kind: "sandbox", backend });
|
|
84
|
+
|
|
85
|
+
expect(
|
|
86
|
+
await screen.findByPlaceholderText(
|
|
87
|
+
`Add packages to ${backend} sandbox...`,
|
|
88
|
+
),
|
|
89
|
+
).toBeInTheDocument();
|
|
90
|
+
expect(screen.getByText(`${backend} sandbox`)).toBeInTheDocument();
|
|
91
|
+
expect(
|
|
92
|
+
screen.queryByRole("button", { name: "Change package manager" }),
|
|
93
|
+
).not.toBeInTheDocument();
|
|
94
|
+
expect(
|
|
95
|
+
screen.queryByRole("button", { name: "List" }),
|
|
96
|
+
).not.toBeInTheDocument();
|
|
97
|
+
expect(
|
|
98
|
+
screen.queryByRole("button", { name: "Tree" }),
|
|
99
|
+
).not.toBeInTheDocument();
|
|
100
|
+
expect(getPackageList).not.toHaveBeenCalled();
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
it("explains the filtered empty state for a Pixi sandbox", async () => {
|
|
105
|
+
renderPanel({ kind: "sandbox", backend: "pixi" });
|
|
106
|
+
|
|
107
|
+
expect(await screen.findByText("No PyPI dependencies")).toBeInTheDocument();
|
|
108
|
+
expect(
|
|
109
|
+
screen.getByText("Conda dependencies are not shown in this panel."),
|
|
110
|
+
).toBeInTheDocument();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("labels a dependency whose subtree was already displayed", async () => {
|
|
114
|
+
renderPanel({ kind: "sandbox", backend: "pixi" }, populatedTree);
|
|
115
|
+
|
|
116
|
+
fireEvent.click(await screen.findByRole("treeitem", { name: /polars/ }));
|
|
117
|
+
|
|
118
|
+
expect(screen.getByText("already in tree")).toBeInTheDocument();
|
|
119
|
+
expect(screen.queryByText("cycle")).not.toBeInTheDocument();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("keeps the configured package manager changeable outside a sandbox", async () => {
|
|
123
|
+
const { getPackageList } = renderPanel({
|
|
124
|
+
kind: "package-manager",
|
|
125
|
+
name: "pip",
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
expect(
|
|
129
|
+
await screen.findByPlaceholderText("Install packages with pip..."),
|
|
130
|
+
).toBeInTheDocument();
|
|
131
|
+
const changeManager = screen.getByRole("button", {
|
|
132
|
+
name: "Change package manager",
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
fireEvent.click(changeManager);
|
|
136
|
+
|
|
137
|
+
expect(openSettings).toHaveBeenCalledWith("packageManagementAndData");
|
|
138
|
+
expect(screen.getByText("environment")).toBeInTheDocument();
|
|
139
|
+
expect(screen.getByRole("button", { name: "List" })).toBeInTheDocument();
|
|
140
|
+
expect(screen.getByRole("button", { name: "Tree" })).toBeInTheDocument();
|
|
141
|
+
expect(getPackageList).toHaveBeenCalledOnce();
|
|
142
|
+
});
|
|
143
|
+
});
|