Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to know the image is loaded for Cypress ? #2476

Open
athimannil opened this issue Feb 16, 2024 · 2 comments
Open

How to know the image is loaded for Cypress ? #2476

athimannil opened this issue Feb 16, 2024 · 2 comments
Labels

Comments

@athimannil
Copy link

I am writing Unit Test for openseadragon react component in Cypress. Is there option in opneseadragon to know the image is loaded.

React component is

const { DEV } = import.meta.env;

interface OpenSeaDragonImageProps {
  tileSourcesUrl: string;
}

const OpenSeaDragonImage = ({ tileSourcesUrl }: OpenSeaDragonImageProps) => {
  const viewerRef = useRef<OpenSeadragon.Viewer | null>(null);

  useEffect(() => {
    viewerRef.current = OpenSeadragon({
      id: "osdviewer",
      tileSources: tileSourcesUrl,
    });

    if (window.Cypress && DEV) {
      window.osdViewer = viewerRef.current;
    }

    return () => viewerRef.current?.destroy();
  }, [tileSourcesUrl]);

  return (
    <div id="osdviewer" />
  );
};

export default OpenSeaDragonImage;

Here is the current test code.

import { Viewer } from "openseadragon";
import OpenSeaDragonImage from "./OpenSeaDragonImage";

declare global {
  interface Window {
    osdViewer: Viewer;
  }
}

context(OpenSeaDragonImage.name, () => {
  describe("OpenSeaDragon view", () => {
    beforeEach(() => {
      cy.mount(
        <OpenSeaDragonImage tileSourcesUrl="https://openseadragon.github.io/example-images/highsmith/highsmith.dzi" />
      );
      cy.get(".openseadragon-container").should("exist");
    });

    it("Should OSD view zoom-in with custom button", () => {
      cy.window().then((window) => {
        expect(window.osdViewer.viewport.getZoom()).to.equal(1);

        window.osdViewer.addHandler("open", function () {
          cy.get("#navControlZoomIn").as("zoomIn");
          cy.get("@zoomIn").click();
          cy.get("@zoomIn").then(() => {
            expect(window.osdViewer.viewport.getZoom()).to.equal(2);
          });
        });
      });
    });

    it("Should OSD view zoom-out with custom button", () => {
      cy.window().then((window) => {
        cy.get("#navControlZoomIn").dblclick();

        window.osdViewer.addHandler("open", function () {
          cy.get("#navControlZoomOut").as("zoomOut");
          cy.get("@zoomOut").click();
          cy.get("@zoomOut").then(() => {
            expect(window.osdViewer.viewport.getZoom()).to.equal(2);
          });
        });
      });
    });

    it("Should OSD view reset view in custom button", () => {
      cy.window().then((window) => {
        cy.get("#navControlZoomIn").dblclick();

        window.osdViewer.addHandler("open", function () {
          cy.get("#navControlReset").as("viewReset");
          cy.get("@viewReset").click();
          cy.get("@viewReset").then(() => {
            expect(window.osdViewer.viewport.getZoom()).to.equal(1);
          });
        });
      });
    });
  });
});

Images are not loaded while testing zoom button and other tests.

Are there solution for finding image is loaded to call test ?

@Aiosa
Copy link
Contributor

Aiosa commented Feb 20, 2024

I solved this like this:

 // do something to start the test
 cy.visit({
        url: ...,
        headers: ...,
        method: ...,
        body: ...
 })
// custom function
utils.waitForViewer();

you can check the implementation here: https://github.com/RationAI/xopat/blob/development/test/support/utilities.js
with requirements:

 "cypress": "^10.9.0",
 "cypress-wait-until": "^1.7.2"

@iangilman
Copy link
Member

Here's my response on StackOverflow: https://stackoverflow.com/a/78036033/306351

You want the fully-loaded-change event. Something like this:

function whenFullyLoaded(tiledImage, callback) {
  if (tiledImage.getFullyLoaded()) {
    setTimeout(callback, 1); // So both paths are asynchronous
  } else {
    tiledImage.addOnceHandler('fully-loaded-change', function() {
      callback(); // Calling it this way keeps the arguments consistent (if we passed callback into addOnceHandler it would get an event on this path but not on the setTimeout path above)
    });
  }
}

whenFullyLoaded(viewer.world.getItemAt(0), function() {
  // Success!
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants