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
47 changes: 47 additions & 0 deletions tests/e2e/bbox-select-overlay.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { test, expect } from "@playwright/test";
import {
openNotebookFresh,
runFirstNCells,
executeCellAndWaitForOutput,
} from "./helpers/notebook";
import { validateBounds } from "./helpers/assertions";
import { drawBboxOnMapLibre } from "./helpers/maplibre";

test.describe("BBox selection - Overlay render mode", () => {
test("draws bbox and syncs selected_bounds to Python with overlay render_mode", async ({
page,
}) => {
const { notebookRoot } = await openNotebookFresh(
page,
"simple-map-overlay.ipynb",
{
workspaceId: `bbox-overlay-${Date.now()}`,
},
);
await runFirstNCells(page, notebookRoot, 2);
await page.waitForTimeout(5000);

// Start bbox selection mode
const bboxButton = page.getByRole("button", { name: "Select BBox" });
await expect(bboxButton).toBeVisible({ timeout: 10000 });
await bboxButton.click();

// Verify drawing mode is active
const cancelButton = page.getByRole("button", { name: "Cancel drawing" });
await expect(cancelButton).toBeVisible({ timeout: 5000 });

// Draw bbox using simple mouse events
await drawBboxOnMapLibre(page, { x: 200, y: 200 }, { x: 400, y: 400 });

// Verify bbox was drawn successfully
const finalClearButton = page.getByRole("button", {
name: "Clear bounding box",
});
await expect(finalClearButton).toBeVisible({ timeout: 5000 });

// Execute cell to check selected bounds
const output = await executeCellAndWaitForOutput(notebookRoot, 2);
const outputText = await output.textContent();
validateBounds(outputText);
});
});
28 changes: 28 additions & 0 deletions tests/e2e/helpers/maplibre.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Page } from "@playwright/test";

/**
* Draws a bounding box on the MapLibre map using click-click pattern.
* In overlay mode, MapLibre handles events and forwards them to deck.gl via MapboxOverlay.
*
* The bbox selection pattern matches deck-first mode: click at start, hover at end, click at end.
*/
export async function drawBboxOnMapLibre(
page: Page,
start: { x: number; y: number },
end: { x: number; y: number },
): Promise<void> {
// Find the map canvas (MapLibre renders the map canvas directly)
const canvas = page.locator("canvas").first();
await canvas.waitFor({ state: "visible", timeout: 10000 });

// Bbox selection pattern: click at start, hover at end, click at end
// Use locator-based actions which are more robust than page.mouse
await canvas.click({ position: { x: start.x, y: start.y } });
await page.waitForTimeout(500);

await canvas.hover({ position: { x: end.x, y: end.y } });
await page.waitForTimeout(500);

await canvas.click({ position: { x: end.x, y: end.y } });
await page.waitForTimeout(1000);
}