Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions packages/workspace/src/ts/workspace/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -815,13 +815,11 @@ export class PerspectiveWorkspace extends SplitPanel {
);

(async () => {
for (const table of (
await Promise.all(
this.client.map((client) =>
client.get_hosted_table_names(),
),
)
).map((x) => x.flatMap((x: any) => x))) {
const names = await Promise.all(
this.client.map((c) => c.get_hosted_table_names()),
).then((x) => x.flat());

for (const table of names) {
let args;
if (widget !== null) {
args = {
Expand Down
136 changes: 136 additions & 0 deletions packages/workspace/test/js/context_menu.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

import { test, expect } from "@perspective-dev/test";

test.beforeEach(async ({ page }) => {
await page.goto("/tools/test/src/html/workspace-test.html");
await page.evaluate(async () => {
while (!window["__TEST_PERSPECTIVE_READY__"]) {
await new Promise((x) => setTimeout(x, 10));
}
});
});

test.describe("Context menu", () => {
test("shows tables in the New Table submenu", async ({ page }) => {
await page.evaluate(async () => {
await window.__WORKER__.table("x\n1\n2\n", {
name: "test_table_1",
});

await window.__WORKER__.table("y\n3\n4\n", {
name: "test_table_2",
});
});

// Right-click on the workspace to open context menu
const workspace = page.locator("perspective-workspace");
await workspace.click({
button: "right",
position: { x: 100, y: 100 },
});

// Wait for the context menu to appear in the shadow DOM
const shadowHost = page.locator("perspective-workspace");
const menu = shadowHost.locator(".lm-Menu").first();
await expect(menu).toBeVisible();

// Click on "New Table" to open the submenu
const newTableItem = menu.locator(
".lm-Menu-item:has(.lm-Menu-itemLabel:text('New Table'))",
);
await newTableItem.hover();

// Wait for submenu to appear
const submenu = shadowHost.locator(".lm-Menu").nth(1);
await expect(submenu).toBeVisible();

// Get the submenu content with table entries
const submenuContent = submenu.locator(".lm-Menu-content");

// Wait for the table items to be populated (they are added asynchronously)
// We expect at least our two test tables plus the default "superstore" table
await expect(submenuContent.locator("> .lm-Menu-item")).toHaveCount(3, {
timeout: 5000,
});

const menuItems = submenuContent.locator("> .lm-Menu-item");
const itemCount = await menuItems.count();

// Get the labels of the first items (the tables)
const labels = [];
for (let i = 0; i < itemCount; i++) {
const label = await menuItems
.nth(i)
.locator(".lm-Menu-itemLabel")
.textContent();
labels.push(label);
}

// Verify our test tables appear in the menu
expect(labels).toContain("test_table_1");
expect(labels).toContain("test_table_2");
expect(labels).toContain("superstore");
});

test("context menu table entries have correct structure", async ({
page,
}) => {
// Create two tables and load the workspace
await page.evaluate(async () => {
await window.__WORKER__.table("a\n1\n", { name: "alpha" });
await window.__WORKER__.table("b\n2\n", { name: "beta" });
});

// Right-click on the workspace
const workspace = page.locator("perspective-workspace");
await workspace.click({
button: "right",
position: { x: 100, y: 100 },
});

// Open the "New Table" submenu
const shadowHost = page.locator("perspective-workspace");
const menu = shadowHost.locator(".lm-Menu").first();
await expect(menu).toBeVisible();

const newTableItem = menu.locator(
".lm-Menu-item:has(.lm-Menu-itemLabel:text('New Table'))",
);
await newTableItem.hover();

const submenu = shadowHost.locator(".lm-Menu").nth(1);
await expect(submenu).toBeVisible();

// Verify the DOM structure of table entries
const submenuContent = submenu.locator(".lm-Menu-content");

// Wait for table items to be populated
await expect(submenuContent.locator("> .lm-Menu-item")).toHaveCount(3, {
timeout: 5000,
});

const firstItem = submenuContent.locator("> .lm-Menu-item").first();

// Check that the menu item has the expected Lumino classes
await expect(firstItem).toHaveClass(/lm-Menu-item/);

// Check that it contains a label element
const labelElement = firstItem.locator(".lm-Menu-itemLabel");
await expect(labelElement).toBeVisible();

// Verify the label contains one of our table names
const labelText = await labelElement.textContent();
expect(["alpha", "beta", "superstore"]).toContain(labelText);
});
});
Loading