diff --git a/client/__tests__/e2e/cellxgeneActions.ts b/client/__tests__/e2e/cellxgeneActions.ts index 2abdd53ee..6192f01f9 100644 --- a/client/__tests__/e2e/cellxgeneActions.ts +++ b/client/__tests__/e2e/cellxgeneActions.ts @@ -43,6 +43,18 @@ export async function drag(testId: any, start: any, end: any, lasso = false) { await page.mouse.up(); } +export async function scroll({testId, deltaY, coords}: {testId: string, deltaY: number, coords: number[]}) { + const layout = await waitByID(testId); + if (layout){ + const x = coords[0]; + const y = coords[1]; + await page.mouse.move(x, y); + await page.mouse.down(); + await page.mouse.up(); + await page.mouse.wheel({ deltaY }); + } +} + export async function keyboardUndo() { await page.keyboard.down("MetaLeft"); await page.keyboard.press("KeyZ"); diff --git a/client/__tests__/e2e/e2e.test.ts b/client/__tests__/e2e/e2e.test.ts index 83e49aad6..838f81c75 100644 --- a/client/__tests__/e2e/e2e.test.ts +++ b/client/__tests__/e2e/e2e.test.ts @@ -26,6 +26,7 @@ import { calcDragCoordinates, calcTransformDragCoordinates, drag, + scroll, expandCategory, subset, createGeneset, @@ -58,6 +59,8 @@ import { import { datasets } from "./data"; +import { scaleMax } from "../../src/util/camera"; + const BLUEPRINT_SKELETON_CLASS_NAME = Classes.SKELETON; // geneset CRUD @@ -444,6 +447,32 @@ describe("graph overlay", () => { }); }); +test("zoom limit is 12x", async () => { + await goToPage(pageUrl); + + const category = Object.keys(data.categorical)[0]; + + await clickOn(`colorby-${category}`); + await clickOn("centroid-label-toggle"); + await clickOn("mode-pan-zoom"); + + + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + const categoryValue = Object.keys(data.categorical[category])[0]; + const initialCoordinates = await getElementCoordinates( + `${categoryValue}-centroid-label` + ); + + await tryUntil(async () => { + await scroll({testId: "layout-graph", deltaY: -10000, coords: initialCoordinates}); + await page.waitForTimeout(1000); + const newGraph = await page.waitForSelector("[data-test-id^=graph-wrapper-]") + const newGraphTestId = await newGraph?.evaluate((el) => el.getAttribute("data-test-id")) + const newDistance = newGraphTestId?.split("distance=").at(-1); + expect(parseFloat(newDistance)).toBe(scaleMax); + }); +}); + test("pan zoom mode resets lasso selection", async () => { await goToPage(pageUrl); diff --git a/client/src/components/graph/graph.tsx b/client/src/components/graph/graph.tsx index f1a896a7a..7409ebcf4 100644 --- a/client/src/components/graph/graph.tsx +++ b/client/src/components/graph/graph.tsx @@ -126,6 +126,8 @@ class Graph extends React.Component<{}, GraphState> { return !shallowEqual(props.watchProps, prevProps.watchProps); } + private graphRef = React.createRef(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS. cachedAsyncProps: any; @@ -264,6 +266,11 @@ class Graph extends React.Component<{}, GraphState> { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS. componentDidMount() { window.addEventListener("resize", this.handleResize); + if (this.graphRef.current) { + this.graphRef.current.addEventListener("wheel", this.disableScroll, { + passive: false, + }); + } } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/ban-types --- FIXME: disabled temporarily on migrate to TS. @@ -323,6 +330,9 @@ class Graph extends React.Component<{}, GraphState> { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS. componentWillUnmount() { window.removeEventListener("resize", this.handleResize); + if (this.graphRef.current) { + this.graphRef.current.removeEventListener("wheel", this.disableScroll); + } } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS. @@ -496,6 +506,11 @@ class Graph extends React.Component<{}, GraphState> { }); } + disableScroll = (event: WheelEvent) => { + // disables browser scrolling behavior when hovering over the graph + event.preventDefault(); + }; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS. setReglCanvas = (canvas: any) => { // Ignore null canvas on unmount @@ -910,6 +925,7 @@ class Graph extends React.Component<{}, GraphState> { } = this.props; const { modelTF, projectionTF, camera, viewport, regl } = this.state; const cameraTF = camera?.view()?.slice(); + return (
{ top: 0, left: 0, }} + data-test-id={`graph-wrapper-distance=${camera?.distance()}`} + ref={this.graphRef} >