Skip to content
Open
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
60 changes: 57 additions & 3 deletions __tests__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const COOKBOOK_BOUND_MULTIVOLUME_MANIFEST =
const PDF_MULTI_FILE_MANIFEST =
"https://digital.library.villanova.edu/Item/vudl:294631/Manifest";

// 3D manifest for model viewer tests
const MODEL_3D_MANIFEST =
"https://biiif-template-example-3kntb3jpl-mnemoscene.vercel.app/3d/index.json";

const viewerUrl = (manifestUrl) => {
//const separator = BASE_URL.includes("#?") ? "&" : "#?";
return `${BASE_URL}#?manifest=${encodeURIComponent(manifestUrl)}`;
Expand Down Expand Up @@ -211,9 +215,8 @@ describe("Universal Viewer", () => {
// COOKBOOK MANIFEST TEST
describe("viewer controls", () => {
beforeEach(async () => {
await page.goto(viewerUrl(COOKBOOK_BOUND_MULTIVOLUME_MANIFEST),
{
waitUntil: "domcontentloaded"
await page.goto(viewerUrl(COOKBOOK_BOUND_MULTIVOLUME_MANIFEST), {
waitUntil: "domcontentloaded",
});
});

Expand Down Expand Up @@ -483,4 +486,55 @@ describe("Universal Viewer", () => {
expect(page.url()).toContain("cv=1");
});
});

// 3D manifest test
describe("3D manifest", () => {
beforeEach(async () => {
await page.goto(viewerUrl(MODEL_3D_MANIFEST), {
waitUntil: "domcontentloaded",
});

await page.waitForSelector(".uv", {
visible: true,
});
});

it("loads the 3D manifest", async () => {
expect(page.url()).toContain(encodeURIComponent(MODEL_3D_MANIFEST));
});

it("allows zoom interaction", async () => {
const viewer = await page.$(".uv, .centerPanel, canvas");
expect(viewer).toBeTruthy();

const box = await viewer.boundingBox();
expect(box).toBeTruthy();

await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
await page.mouse.wheel({ deltaY: -600 });
await page.mouse.wheel({ deltaY: 600 });

const uv = await page.$(".uv");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I'm missing or misunderstanding something, but I don't quite see how this check is confirming the effect of the mouse wheel actions above. Same issue in the following test. From trying this manually, I see that there doesn't really seem to be anything we can measure to verify the effect of these actions.

I wonder if the basic test should check for a rendered canvas, just to further confirm that the right code has loaded.

For these other tests, I think they would be very valuable if we could confirm that they did anything... but if we can't, they may be misleading rather than helpful. Do we need to add something to the code itself to allow measurement? (That may be out of scope for the current work -- and if so, maybe we should just go with the most minimal test, and then open an issue to track the need for follow-up).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demiankatz, You're right, I tried using cameraOrbit but wasn't successful. I agree the zoom/rotation tests are a bit misleading right now since they only confirm that the interactions can be triggered, not that they actually changed anything. I'll simplify this to a basic smoke test that verifies the 3D manifest loads successfully and add your suggested check for a rendered canvas.

@LanieOkorodudu LanieOkorodudu Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demiankatz, Following the suggestion about confirming that the correct code has loaded, I tried replacing the interaction-based test with a manifest-specific assertion.

The test navigates to the 3D manifest URL:

await page.goto(viewerUrl(MODEL_3D_MANIFEST), {
  waitUntil: "domcontentloaded",
});

const title = await page.$eval(
  "#uv .mainPanel .centerPanel h1",
  el => el.textContent.trim()
);

expect(title).toContain("Astronaut");

The manifest URL being loaded is:

http://localhost:4444/#?manifest=https%3A%2F%2Fbiiif-template-example-3kntb3jpl-mnemoscene.vercel.app%2F3d%2Findex.json

And the test output is:

Loaded URL: http://localhost:4444/#?manifest=https%3A%2F%2Fbiiif-template-example-3kntb3jpl-mnemoscene.vercel.app%2F3d%2Findex.json&xywh=-143%2C0%2C5157%2C3371

Title: Wunder der Vererbung / von Fritz Bolle.

When opening the same 3D manifest manually in the browser, the same selector returns:

Astronaut

So the test appears to be reaching the correct URL, but the viewer is still rendering the default OpenSeadragon manifest in the automated environment rather than the Astronaut 3D manifest.

Because of that, I wasn't able to create a reliable assertion that the 3D model itself was loaded. The remaining option would be a minimal smoke test that verifies a canvas is rendered, unless we want to investigate why the 3D manifest is not activating the model-viewer path in automation.

@LanieOkorodudu LanieOkorodudu Jun 17, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@demiankatz, I think I might just close this PR for now, as I'm not convinced the test is solid enough to reliably verify the 3D manifest.
I tried a few approaches to confirm that the Astronaut manifest was actually loaded:

  • Verified that the test navigates to the correct 3D manifest URL.
  • Added checks against the rendered title (Astronaut).
  • Waited for additional time after load to rule out a timing issue.
  • Verified the selector using both the existing CSS selector and XPath.

In all cases, the result was the same:
console.log
Loaded URL: http://localhost:4444/#?manifest=https%3A%2F%2Fbiiif-template-example-3kntb3jpl-mnemoscene.vercel.app%2F3d%2Findex.json&xywh=-143%2C0%2C5157%2C3371

console.log
Initial title: Wunder der Vererbung / von Fritz Bolle.

console.log
Title after 5 seconds: Wunder der Vererbung / von Fritz Bolle.

What I find strange is that the test appears to be navigating to the correct 3D manifest URL, but the viewer still seems to be showing the default manifest content. Since the title never changes to Astronaut, I don't currently have a reliable way to prove that the 3D model has actually been loaded in the automated environment.

I think this probably needs some investigation into how the 3D manifest is being loaded before we can create a meaningful automated test for it.
In the meantime, I will continue to address the rest that I listed in #1750

expect(uv).toBeTruthy();
});

it("allows model rotation", async () => {
const viewer = await page.$(".uv, .centerPanel, canvas");
expect(viewer).toBeTruthy();

const box = await viewer.boundingBox();
expect(box).toBeTruthy();

const centerX = box.x + box.width / 2;
const centerY = box.y + box.height / 2;

await page.mouse.move(centerX, centerY);
await page.mouse.down();
await page.mouse.move(centerX + 200, centerY, { steps: 20 });
await page.mouse.up();

const uv = await page.$(".uv");
expect(uv).toBeTruthy();
});
});
});