vease 1.51.0 → 1.52.0-rc.10

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.
@@ -105,17 +105,19 @@ async function toggleShrinkFilter(window) {
105
105
  await window.getByTestId("shrinkFilterButton").click();
106
106
  await waitForActionSettled(window);
107
107
  }
108
- async function setShrinkFactor(window, shrinkFactorValue) {
109
- const slider = window.getByTestId("shrinkFactorSlider");
108
+ async function setSliderRatio(window, sliderTestId, ratio) {
109
+ const slider = window.getByTestId(sliderTestId);
110
110
  const box = await slider.boundingBox();
111
- if (!box) throw new Error("Could not get bounding box of the shrink factor slider.");
112
- const clickX = box.width * shrinkFactorValue;
111
+ if (!box) throw new Error(`Could not get bounding box of the ${sliderTestId} slider.`);
113
112
  await slider.click({ position: {
114
- x: clickX,
113
+ x: box.width * ratio,
115
114
  y: box.height / 2
116
115
  } });
117
116
  await waitForActionSettled(window);
118
117
  }
118
+ async function setShrinkFactor(window, shrinkFactorValue) {
119
+ await setSliderRatio(window, "shrinkFactorSlider", shrinkFactorValue);
120
+ }
119
121
  async function resetShrinkFilter(window) {
120
122
  await window.getByTestId("resetShrinkButton").click();
121
123
  await waitForActionSettled(window);
@@ -133,6 +135,21 @@ async function selectShrinkDatasets(window, datasetName, index = 0) {
133
135
  await select.click();
134
136
  await waitForActionSettled(window);
135
137
  }
138
+ async function toggleExplodeFilter(window) {
139
+ await window.getByTestId("explodeFilterButton").click();
140
+ await waitForActionSettled(window);
141
+ }
142
+ async function setExplodeFactor(window, explodeFactorValue) {
143
+ await setSliderRatio(window, "explodeFactorSlider", explodeFactorValue);
144
+ }
145
+ async function resetExplodeFilter(window) {
146
+ await window.getByTestId("resetExplodeButton").click();
147
+ await waitForActionSettled(window);
148
+ }
149
+ async function removeExplodeFilter(window) {
150
+ await window.getByTestId("removeExplodeButton").click();
151
+ await waitForActionSettled(window);
152
+ }
136
153
  async function toggleThresholdFilter(window) {
137
154
  await window.getByTestId("thresholdFilterButton").click();
138
155
  await waitForActionSettled(window);
@@ -207,4 +224,4 @@ async function drawZoomBox(window, deltaX, deltaY) {
207
224
  await expect(window.getByTestId("zoomBoxActiveChip")).toBeHidden();
208
225
  }
209
226
  //#endregion
210
- export { activateZoomToBox, clearRuler, closeCameraManager, drawZoomBox, ensureHighlightMenuOpen, removeThresholdFilter, resetCamera, resetShrinkFilter, resetThresholdFilter, restoreCameraPosition, rotateCamera, saveCameraPosition, selectCameraOrientation, selectShrinkDatasets, selectThresholdBlockPolyhedron, selectThresholdCellAttribute, setRulerPointInput, setShrinkFactor, setThresholdMinimum, setZScaling, toggleCameraManager, toggleCameraOrientation, toggleCenterOnClick, toggleGridScale, toggleRuler, toggleRulerSnap, toggleShrinkFilter, toggleShrinkTargetAllVisible, toggleThresholdFilter };
227
+ export { activateZoomToBox, clearRuler, closeCameraManager, drawZoomBox, ensureHighlightMenuOpen, removeExplodeFilter, removeThresholdFilter, resetCamera, resetExplodeFilter, resetShrinkFilter, resetThresholdFilter, restoreCameraPosition, rotateCamera, saveCameraPosition, selectCameraOrientation, selectShrinkDatasets, selectThresholdBlockPolyhedron, selectThresholdCellAttribute, setExplodeFactor, setRulerPointInput, setShrinkFactor, setThresholdMinimum, setZScaling, toggleCameraManager, toggleCameraOrientation, toggleCenterOnClick, toggleExplodeFilter, toggleGridScale, toggleRuler, toggleRulerSnap, toggleShrinkFilter, toggleShrinkTargetAllVisible, toggleThresholdFilter };
@@ -18,11 +18,18 @@ const test = test$1.extend({
18
18
  screenshotMask: [async ({}, use) => {
19
19
  await use({ locators: [] });
20
20
  }, { scope: "test" }],
21
- window: [async ({ mode, browser }, use, workerInfo) => {
21
+ window: [async ({ mode, playwright, browserName, headless, channel, launchOptions }, use, workerInfo) => {
22
22
  const configPath = fs.mkdtempSync(path.join(os.tmpdir(), `vease-e2e-worker${workerInfo.parallelIndex}-`));
23
23
  process.env.XDG_CONFIG_HOME = configPath;
24
24
  process.env.APPDATA = configPath;
25
- const { window, cleanup } = await navigateToApp(mode, browser);
25
+ async function launchBrowser() {
26
+ return await playwright[browserName].launch({
27
+ ...launchOptions,
28
+ headless,
29
+ channel
30
+ });
31
+ }
32
+ const { window, cleanup } = await navigateToApp(mode, launchBrowser);
26
33
  await use(window);
27
34
  await cleanup();
28
35
  fs.rmSync(configPath, {
@@ -143,7 +143,7 @@ async function signInToCloudApp(page) {
143
143
  await expect(page.getByTestId("layoutImportButton")).toBeEnabled({ timeout: WAIT_TIMES.cloud });
144
144
  await page.waitForFunction(() => document.readyState === "complete");
145
145
  }
146
- async function navigateToApp(mode, browser) {
146
+ async function newBrowserPage(browser) {
147
147
  const context = await browser.newContext({
148
148
  viewport: {
149
149
  width: PAGE_WIDTH,
@@ -159,13 +159,29 @@ async function navigateToApp(mode, browser) {
159
159
  consola.info("PAGE CLOSED:", newPage.url());
160
160
  });
161
161
  });
162
- const page = await context.newPage();
162
+ return context.newPage();
163
+ }
164
+ async function navigateToApp(mode, launchBrowser) {
163
165
  consola.info(`Testing app in ${mode} mode`);
166
+ if (mode === "DESKTOP") {
167
+ const { electronApp, firstWindow } = await runDesktopBuild();
168
+ consola.info(`Waiting for ${WAIT_TIMES.desktop / MILLISECONDS} seconds for the app to load...`);
169
+ await firstWindow.waitForFunction(() => document.readyState === "complete");
170
+ return {
171
+ window: firstWindow,
172
+ cleanup: async () => {
173
+ await electronApp.close();
174
+ }
175
+ };
176
+ }
177
+ if (mode !== "BROWSER" && mode !== "CLOUD") throw new Error(`Unknown mode: ${mode}`);
178
+ const browser = await launchBrowser();
179
+ const page = await newBrowserPage(browser);
180
+ page.on("console", (msg) => {
181
+ consola.info(`Browser console: ${msg.text()}`);
182
+ });
164
183
  if (mode === "BROWSER") {
165
184
  const nuxtPort = await runBrowser("preview:browser");
166
- page.on("console", (msg) => {
167
- consola.info(`Browser console: ${msg.text()}`);
168
- });
169
185
  const appUrl = `http://localhost:${nuxtPort}`;
170
186
  await page.goto(appUrl);
171
187
  consola.info("Navigated to", page.url());
@@ -176,37 +192,24 @@ async function navigateToApp(mode, browser) {
176
192
  window: page,
177
193
  cleanup: async () => {
178
194
  await page.close();
195
+ await browser.close();
179
196
  await kill(nuxtPort);
180
197
  }
181
198
  };
182
- } else if (mode === "CLOUD") {
183
- page.on("console", (msg) => {
184
- consola.info(`Browser console: ${msg.text()}`);
185
- });
186
- let prefix = "";
187
- const branch = execSync("git branch --show-current", { encoding: "utf8" }).trim();
188
- consola.info("Current branch:", branch);
189
- if (branch === "next") prefix = "next.";
190
- await navigateToCloudApp(page, `https://${prefix}vease.geode-solutions.com`, 10);
191
- await signInToCloudApp(page);
192
- return {
193
- window: page,
194
- cleanup: async () => {
195
- await page.close();
196
- }
197
- };
198
- } else if (mode === "DESKTOP") {
199
- const { electronApp, firstWindow } = await runDesktopBuild();
200
- consola.info(`Waiting for ${WAIT_TIMES.desktop / MILLISECONDS} seconds for the app to load...`);
201
- await firstWindow.waitForFunction(() => document.readyState === "complete");
202
- return {
203
- window: firstWindow,
204
- cleanup: async () => {
205
- await electronApp.close();
206
- }
207
- };
208
199
  }
209
- throw new Error(`Unknown mode: ${mode}`);
200
+ let prefix = "";
201
+ const branch = execSync("git branch --show-current", { encoding: "utf8" }).trim();
202
+ consola.info("Current branch:", branch);
203
+ if (branch === "next") prefix = "next.";
204
+ await navigateToCloudApp(page, `https://${prefix}vease.geode-solutions.com`, 10);
205
+ await signInToCloudApp(page);
206
+ return {
207
+ window: page,
208
+ cleanup: async () => {
209
+ await page.close();
210
+ await browser.close();
211
+ }
212
+ };
210
213
  }
211
214
  async function navigateToViewerPage(window) {
212
215
  await window.getByTestId("viewerNavButton").click();
@@ -1,6 +1,6 @@
1
1
  import { waitForActionSettled } from "../wait_for_action_settled.js";
2
2
  import { moveMouseOutOfTheWay } from "../app_interaction.js";
3
- import { clickCollapseOrExpandAll, collapseGeodeObjectTypeInTree, collapseTreeGroup, expandGeodeObjectTypeInTree, getTreeRowByTextAndParent } from "./common.js";
3
+ import { clickCollapseOrExpandAll, collapseGeodeObjectTypeInTree, collapseTreeGroup, expandGeodeObjectTypeInTree, getTreeRowByTextAndParent, openObjectTreeContextMenu } from "./common.js";
4
4
  import { consola } from "consola";
5
5
  //#region tests/e2e/utils/object_trees/main_object_tree.ts
6
6
  const HIGHLIGHT_HOVER_ATTEMPTS = 3;
@@ -57,6 +57,15 @@ async function showObjectInTree(window, objectName) {
57
57
  await waitForActionSettled(window);
58
58
  }
59
59
  }
60
+ async function openGeodeObjectTypeContextMenu(window, geodeObjectType) {
61
+ await openObjectTreeContextMenu(window, geodeObjectType, getMainObjectTree(window));
62
+ }
63
+ async function openDataContextMenu(window, geodeObjectType, dataName) {
64
+ await expandGeodeObjectType(window, geodeObjectType);
65
+ const mainObjectTree = getMainObjectTree(window);
66
+ await (await getTreeRowByTextAndParent(window, geodeObjectType, dataName, mainObjectTree)).getByTestId("treeItemLabel").first().click({ button: "right" });
67
+ await waitForActionSettled(window);
68
+ }
60
69
  async function toggleObjectsTree(window) {
61
70
  await window.getByTestId("toggleObjectsButton").click();
62
71
  await waitForActionSettled(window);
@@ -74,4 +83,4 @@ async function openObjectsTree(window) {
74
83
  }
75
84
  }
76
85
  //#endregion
77
- export { closeObjectsTree, collapseGeodeObjectType, collapseMainObjectTree, collapseMainObjectTreeGroup, expandGeodeObjectType, expandMainObjectTree, focusObjectInTree, getMainObjectTree, highlightData, openObjectsTree, showObjectInTree, toggleObjectsTree };
86
+ export { closeObjectsTree, collapseGeodeObjectType, collapseMainObjectTree, collapseMainObjectTreeGroup, expandGeodeObjectType, expandMainObjectTree, focusObjectInTree, getMainObjectTree, highlightData, openDataContextMenu, openGeodeObjectTypeContextMenu, openObjectsTree, showObjectInTree, toggleObjectsTree };
@@ -82,13 +82,6 @@ async function openModelComponentsTree(window, geodeObjectType, dataName) {
82
82
  await moveMouseOutOfTheWay(window);
83
83
  await waitForActionSettled(window);
84
84
  }
85
- async function openModelCollectionsTree(window, geodeObjectType, dataName) {
86
- await expandGeodeObjectType(window, geodeObjectType);
87
- const mainObjectTree = getMainObjectTree(window);
88
- await (await getTreeRowByTextAndParent(window, geodeObjectType, dataName, mainObjectTree)).getByTestId("expandModelCollectionsButton").first().click();
89
- await moveMouseOutOfTheWay(window);
90
- await waitForActionSettled(window);
91
- }
92
85
  async function hideAllComponentLeafRows(window, categoryName) {
93
86
  const tree = getModelComponentsObjectTree(window);
94
87
  await expandGeodeObjectTypeInTree(window, categoryName, tree);
@@ -101,4 +94,4 @@ async function hideAllComponentLeafRows(window, categoryName) {
101
94
  await waitForActionSettled(window);
102
95
  }
103
96
  //#endregion
104
- export { collapseMeshComponentType, collapseModelComponentTypes, collapseModelComponentsObjectTree, collapseModelComponentsObjectTreeGroup, expandMeshComponentType, expandModelComponentsObjectTree, getModelComponentTypeOptions, getModelComponentsObjectTree, hideAllComponentLeafRows, hoverCorners, hoverLines, hoverModelBlock, hoverSurfaces, openModelCollectionsTree, openModelComponentContextMenu, openModelComponentsTree, setModelTreeRowColorRandom, toggleModelTreeRow };
97
+ export { collapseMeshComponentType, collapseModelComponentTypes, collapseModelComponentsObjectTree, collapseModelComponentsObjectTreeGroup, expandMeshComponentType, expandModelComponentsObjectTree, getModelComponentTypeOptions, getModelComponentsObjectTree, hideAllComponentLeafRows, hoverCorners, hoverLines, hoverModelBlock, hoverSurfaces, openModelComponentContextMenu, openModelComponentsTree, setModelTreeRowColorRandom, toggleModelTreeRow };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vease",
3
- "version": "1.51.0",
3
+ "version": "1.52.0-rc.10",
4
4
  "description": "Desktop and cloud software for data visualization",
5
5
  "keywords": [
6
6
  "Desktop",
@@ -71,12 +71,11 @@
71
71
  "test:e2e": "npm run pretest && npx playwright test --config ./tests/e2e/playwright.config.ts",
72
72
  "test:e2e:browser:chrome": "npm run test:e2e -- --project=browser-chrome",
73
73
  "test:e2e:browser:firefox": "npm run test:e2e -- --project=browser-firefox",
74
- "test:e2e:browser": "npm run test:e2e:browser:chrome",
74
+ "test:e2e:browser": "npm run test:e2e:browser:chrome --",
75
75
  "test:e2e:cloud": "npm run test:e2e -- --project=cloud",
76
76
  "test:e2e:desktop": "npm run test:e2e -- --project=desktop",
77
77
  "test:e2e:update_snapshots": "npm run test:e2e:browser:chrome -- --update-snapshots",
78
- "prepare:types": "cross-env MODE=BROWSER nuxi prepare",
79
- "typecheck": "npm run prepare:types && vue-tsc --noEmit -p tsconfig.json && tsc --noEmit -p .nuxt/tsconfig.server.json --noImplicitAny false && tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tests/e2e/tsconfig.json"
78
+ "prepare:types": "cross-env MODE=BROWSER nuxi prepare"
80
79
  },
81
80
  "dependencies": {
82
81
  "@ai-sdk/gateway": "4.0.75",
@@ -85,12 +84,12 @@
85
84
  "@ai-sdk/vue": "4.0.93",
86
85
  "@fontsource/michroma": "5.2.6",
87
86
  "@fontsource/roboto": "5.2.10",
88
- "@geode/cloud-api": "latest",
89
- "@geode/opengeodeweb-back": "latest",
90
- "@geode/opengeodeweb-front": "latest",
91
- "@geode/opengeodeweb-viewer": "latest",
92
- "@geode/vease-back": "latest",
93
- "@geode/vease-viewer": "latest",
87
+ "@geode/cloud-api": "next",
88
+ "@geode/opengeodeweb-back": "next",
89
+ "@geode/opengeodeweb-front": "next",
90
+ "@geode/opengeodeweb-viewer": "next",
91
+ "@geode/vease-back": "next",
92
+ "@geode/vease-viewer": "next",
94
93
  "@nuxtjs/mcp-toolkit": "0.18.1",
95
94
  "ai": "7.0.93",
96
95
  "bowser": "2.14.1",
@@ -116,18 +115,18 @@
116
115
  "concurrently": "9.2.1",
117
116
  "cross-env": "10.0.0",
118
117
  "electron": "36.4.0",
119
- "electron-builder": "26.0.12",
118
+ "electron-builder": "26.15.3",
120
119
  "electron-playwright-helpers": "1.7.1",
121
120
  "happy-dom": "20.0.11",
122
121
  "nuxt-electron": "0.7.0",
122
+ "oxlint": "latest",
123
+ "oxlint-tsgolint": "latest",
123
124
  "pinia": "4.0.2",
124
125
  "playwright": "1.54.1",
125
126
  "rolldown": "1.2.8",
126
127
  "std-env": "3.9.0",
127
- "typescript": "5.9.3",
128
128
  "vitest": "4.1.10",
129
129
  "vitest-environment-nuxt": "2.0.0",
130
- "vitest-indexeddb": "0.0.1",
131
- "vue-tsc": "3.3.11"
130
+ "vitest-indexeddb": "0.0.1"
132
131
  }
133
132
  }
@@ -15,7 +15,6 @@ async function resetCamera(window: Page): Promise<void> {
15
15
  }
16
16
 
17
17
  const ROTATE_DRAG_STEPS = 20;
18
-
19
18
  // Vtk.js' RenderWindowInteractor turns a pointermove arriving more than 200ms after the previous one into a StartMouseMove, which InteractorStyleTrackballCamera ignores.
20
19
  // A skipped move mid-drag is caught up by the next handled one (rotation uses the delta from the last handled position), but a skipped final move is lost for good.
21
20
  // On slow runners (Windows + swiftshader) the last step regularly lands late, leaving the camera one step short of the requested angle.
@@ -145,17 +144,20 @@ async function toggleShrinkFilter(window: Page): Promise<void> {
145
144
  await waitForActionSettled(window);
146
145
  }
147
146
 
148
- async function setShrinkFactor(window: Page, shrinkFactorValue: number): Promise<void> {
149
- const slider = window.getByTestId("shrinkFactorSlider");
147
+ async function setSliderRatio(window: Page, sliderTestId: string, ratio: number): Promise<void> {
148
+ const slider = window.getByTestId(sliderTestId);
150
149
  const box = await slider.boundingBox();
151
150
  if (!box) {
152
- throw new Error("Could not get bounding box of the shrink factor slider.");
151
+ throw new Error(`Could not get bounding box of the ${sliderTestId} slider.`);
153
152
  }
154
- const clickX = box.width * shrinkFactorValue;
155
- await slider.click({ position: { x: clickX, y: box.height / 2 } });
153
+ await slider.click({ position: { x: box.width * ratio, y: box.height / 2 } });
156
154
  await waitForActionSettled(window);
157
155
  }
158
156
 
157
+ async function setShrinkFactor(window: Page, shrinkFactorValue: number): Promise<void> {
158
+ await setSliderRatio(window, "shrinkFactorSlider", shrinkFactorValue);
159
+ }
160
+
159
161
  async function resetShrinkFilter(window: Page): Promise<void> {
160
162
  await window.getByTestId("resetShrinkButton").click();
161
163
  await waitForActionSettled(window);
@@ -179,6 +181,25 @@ async function selectShrinkDatasets(window: Page, datasetName: string, index = 0
179
181
  await waitForActionSettled(window);
180
182
  }
181
183
 
184
+ async function toggleExplodeFilter(window: Page): Promise<void> {
185
+ await window.getByTestId("explodeFilterButton").click();
186
+ await waitForActionSettled(window);
187
+ }
188
+
189
+ async function setExplodeFactor(window: Page, explodeFactorValue: number): Promise<void> {
190
+ await setSliderRatio(window, "explodeFactorSlider", explodeFactorValue);
191
+ }
192
+
193
+ async function resetExplodeFilter(window: Page): Promise<void> {
194
+ await window.getByTestId("resetExplodeButton").click();
195
+ await waitForActionSettled(window);
196
+ }
197
+
198
+ async function removeExplodeFilter(window: Page): Promise<void> {
199
+ await window.getByTestId("removeExplodeButton").click();
200
+ await waitForActionSettled(window);
201
+ }
202
+
182
203
  async function toggleThresholdFilter(window: Page): Promise<void> {
183
204
  await window.getByTestId("thresholdFilterButton").click();
184
205
  await waitForActionSettled(window);
@@ -308,6 +329,10 @@ export {
308
329
  resetShrinkFilter,
309
330
  toggleShrinkTargetAllVisible,
310
331
  selectShrinkDatasets,
332
+ toggleExplodeFilter,
333
+ setExplodeFactor,
334
+ resetExplodeFilter,
335
+ removeExplodeFilter,
311
336
  toggleThresholdFilter,
312
337
  selectThresholdCellAttribute,
313
338
  selectThresholdBlockPolyhedron,
@@ -4,7 +4,7 @@ import os from "node:os";
4
4
  import path from "node:path";
5
5
 
6
6
  // Third party imports
7
- import type { Locator, Page } from "@playwright/test";
7
+ import type { Browser, Locator, Page } from "@playwright/test";
8
8
  // oxlint-disable-next-line eslint/no-duplicate-imports
9
9
  import { test as base, expect } from "@playwright/test";
10
10
  import { consola } from "consola";
@@ -44,14 +44,27 @@ const test = base.extend<TestFixtures, WorkerFixtures>({
44
44
  ],
45
45
 
46
46
  window: [
47
- async ({ mode, browser }, use, workerInfo): Promise<void> => {
47
+ async (
48
+ { mode, playwright, browserName, headless, channel, launchOptions },
49
+ use,
50
+ workerInfo,
51
+ ): Promise<void> => {
48
52
  // Each worker runs its own app: give it its own config folder (where extensions are installed) so parallel installs don't overwrite each other
49
53
  const configPath = fs.mkdtempSync(
50
54
  path.join(os.tmpdir(), `vease-e2e-worker${workerInfo.parallelIndex}-`),
51
55
  );
52
56
  process.env.XDG_CONFIG_HOME = configPath;
53
57
  process.env.APPDATA = configPath;
54
- const { window, cleanup } = await navigateToApp(mode, browser);
58
+ // Launched on demand instead of using the browser fixture, which would start (and require installing) a browser in DESKTOP mode too
59
+ async function launchBrowser(): Promise<Browser> {
60
+ const browser = await playwright[browserName].launch({
61
+ ...launchOptions,
62
+ headless,
63
+ channel,
64
+ });
65
+ return browser;
66
+ }
67
+ const { window, cleanup } = await navigateToApp(mode, launchBrowser);
55
68
  await use(window);
56
69
  await cleanup();
57
70
  fs.rmSync(configPath, { recursive: true, force: true });
@@ -199,10 +199,7 @@ async function signInToCloudApp(page: Page): Promise<void> {
199
199
  await page.waitForFunction(() => document.readyState === "complete");
200
200
  }
201
201
 
202
- async function navigateToApp(
203
- mode: string,
204
- browser: Browser,
205
- ): Promise<{ window: Page; cleanup: () => Promise<void> }> {
202
+ async function newBrowserPage(browser: Browser): Promise<Page> {
206
203
  const context = await browser.newContext({
207
204
  viewport: { width: PAGE_WIDTH, height: PAGE_HEIGHT },
208
205
  locale: LOCALE,
@@ -215,13 +212,36 @@ async function navigateToApp(
215
212
  consola.info("PAGE CLOSED:", newPage.url());
216
213
  });
217
214
  });
218
- const page = await context.newPage();
215
+ return context.newPage();
216
+ }
217
+
218
+ async function navigateToApp(
219
+ mode: string,
220
+ launchBrowser: () => Promise<Browser>,
221
+ ): Promise<{ window: Page; cleanup: () => Promise<void> }> {
219
222
  consola.info(`Testing app in ${mode} mode`);
223
+ // The desktop app is driven through Electron: no browser is launched
224
+ if (mode === "DESKTOP") {
225
+ const { electronApp, firstWindow } = await runDesktopBuild();
226
+ consola.info(`Waiting for ${WAIT_TIMES.desktop / MILLISECONDS} seconds for the app to load...`);
227
+ await firstWindow.waitForFunction(() => document.readyState === "complete");
228
+ return {
229
+ window: firstWindow,
230
+ cleanup: async () => {
231
+ await electronApp.close();
232
+ },
233
+ };
234
+ }
235
+ if (mode !== "BROWSER" && mode !== "CLOUD") {
236
+ throw new Error(`Unknown mode: ${mode}`);
237
+ }
238
+ const browser = await launchBrowser();
239
+ const page = await newBrowserPage(browser);
240
+ page.on("console", (msg) => {
241
+ consola.info(`Browser console: ${msg.text()}`);
242
+ });
220
243
  if (mode === "BROWSER") {
221
244
  const nuxtPort = await runBrowser("preview:browser");
222
- page.on("console", (msg) => {
223
- consola.info(`Browser console: ${msg.text()}`);
224
- });
225
245
  const appUrl = `http://localhost:${nuxtPort}`;
226
246
  await page.goto(appUrl);
227
247
  consola.info("Navigated to", page.url());
@@ -233,45 +253,32 @@ async function navigateToApp(
233
253
  window: page,
234
254
  cleanup: async () => {
235
255
  await page.close();
256
+ await browser.close();
236
257
  await kill(nuxtPort);
237
258
  },
238
259
  };
239
- } else if (mode === "CLOUD") {
240
- page.on("console", (msg) => {
241
- consola.info(`Browser console: ${msg.text()}`);
242
- });
243
-
244
- let prefix = "";
245
- const branch = execSync("git branch --show-current", {
246
- encoding: "utf8",
247
- }).trim();
248
- consola.info("Current branch:", branch);
249
- if (branch === "next") {
250
- prefix = "next.";
251
- }
252
- const url = `https://${prefix}vease.geode-solutions.com`;
253
- const maxRetries = 10;
254
- await navigateToCloudApp(page, url, maxRetries);
255
- await signInToCloudApp(page);
260
+ }
256
261
 
257
- return {
258
- window: page,
259
- cleanup: async () => {
260
- await page.close();
261
- },
262
- };
263
- } else if (mode === "DESKTOP") {
264
- const { electronApp, firstWindow } = await runDesktopBuild();
265
- consola.info(`Waiting for ${WAIT_TIMES.desktop / MILLISECONDS} seconds for the app to load...`);
266
- await firstWindow.waitForFunction(() => document.readyState === "complete");
267
- return {
268
- window: firstWindow,
269
- cleanup: async () => {
270
- await electronApp.close();
271
- },
272
- };
262
+ let prefix = "";
263
+ const branch = execSync("git branch --show-current", {
264
+ encoding: "utf8",
265
+ }).trim();
266
+ consola.info("Current branch:", branch);
267
+ if (branch === "next") {
268
+ prefix = "next.";
273
269
  }
274
- throw new Error(`Unknown mode: ${mode}`);
270
+ const url = `https://${prefix}vease.geode-solutions.com`;
271
+ const maxRetries = 10;
272
+ await navigateToCloudApp(page, url, maxRetries);
273
+ await signInToCloudApp(page);
274
+
275
+ return {
276
+ window: page,
277
+ cleanup: async () => {
278
+ await page.close();
279
+ await browser.close();
280
+ },
281
+ };
275
282
  }
276
283
 
277
284
  async function navigateToViewerPage(window: Page): Promise<void> {
@@ -5,6 +5,7 @@ import {
5
5
  collapseTreeGroup,
6
6
  expandGeodeObjectTypeInTree,
7
7
  getTreeRowByTextAndParent,
8
+ openObjectTreeContextMenu,
8
9
  } from "./common";
9
10
  import { consola } from "consola";
10
11
  import { moveMouseOutOfTheWay } from "@vease_tests/utils/app_interaction";
@@ -102,6 +103,25 @@ async function showObjectInTree(window: Page, objectName: string): Promise<void>
102
103
  }
103
104
  }
104
105
 
106
+ async function openGeodeObjectTypeContextMenu(
107
+ window: Page,
108
+ geodeObjectType: string,
109
+ ): Promise<void> {
110
+ await openObjectTreeContextMenu(window, geodeObjectType, getMainObjectTree(window));
111
+ }
112
+
113
+ async function openDataContextMenu(
114
+ window: Page,
115
+ geodeObjectType: string,
116
+ dataName: string,
117
+ ): Promise<void> {
118
+ await expandGeodeObjectType(window, geodeObjectType);
119
+ const mainObjectTree = getMainObjectTree(window);
120
+ const row = await getTreeRowByTextAndParent(window, geodeObjectType, dataName, mainObjectTree);
121
+ await row.getByTestId("treeItemLabel").first().click({ button: "right" });
122
+ await waitForActionSettled(window);
123
+ }
124
+
105
125
  async function toggleObjectsTree(window: Page): Promise<void> {
106
126
  await window.getByTestId("toggleObjectsButton").click();
107
127
  await waitForActionSettled(window);
@@ -139,6 +159,8 @@ export {
139
159
  focusObjectInTree,
140
160
  getMainObjectTree,
141
161
  highlightData,
162
+ openDataContextMenu,
163
+ openGeodeObjectTypeContextMenu,
142
164
  openObjectsTree,
143
165
  showObjectInTree,
144
166
  toggleObjectsTree,
@@ -149,19 +149,6 @@ async function openModelComponentsTree(
149
149
  await waitForActionSettled(window);
150
150
  }
151
151
 
152
- async function openModelCollectionsTree(
153
- window: Page,
154
- geodeObjectType: string,
155
- dataName: string,
156
- ): Promise<void> {
157
- await expandGeodeObjectType(window, geodeObjectType);
158
- const mainObjectTree = getMainObjectTree(window);
159
- const row = await getTreeRowByTextAndParent(window, geodeObjectType, dataName, mainObjectTree);
160
- await row.getByTestId("expandModelCollectionsButton").first().click();
161
- await moveMouseOutOfTheWay(window);
162
- await waitForActionSettled(window);
163
- }
164
-
165
152
  async function hideAllComponentLeafRows(window: Page, categoryName: string): Promise<void> {
166
153
  const tree = getModelComponentsObjectTree(window);
167
154
  await expandGeodeObjectTypeInTree(window, categoryName, tree);
@@ -192,7 +179,6 @@ export {
192
179
  hoverModelBlock,
193
180
  hoverSurfaces,
194
181
  openModelComponentContextMenu,
195
- openModelCollectionsTree,
196
182
  openModelComponentsTree,
197
183
  setModelTreeRowColorRandom,
198
184
  toggleModelTreeRow,