From 123357ec7565b093400f92a78510ea888b77ee4c Mon Sep 17 00:00:00 2001 From: jiuqingsong Date: Tue, 30 Jun 2026 16:56:05 -0700 Subject: [PATCH] Fix applyChange tests to pass at all screen scales generateDataURL sizes the output canvas by window.devicePixelRatio, but the expected newSrc images were captured at 100% scale, so the IHDR dimension assertions failed on hosts at other scales. Pin devicePixelRatio to 1 for these tests so canvas output is deterministic regardless of screen scale. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../test/imageEdit/utils/applyChangeTest.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/roosterjs-content-model-plugins/test/imageEdit/utils/applyChangeTest.ts b/packages/roosterjs-content-model-plugins/test/imageEdit/utils/applyChangeTest.ts index 6e11a0fa5ff0..068a39efc412 100644 --- a/packages/roosterjs-content-model-plugins/test/imageEdit/utils/applyChangeTest.ts +++ b/packages/roosterjs-content-model-plugins/test/imageEdit/utils/applyChangeTest.ts @@ -57,8 +57,20 @@ describe('applyChange', () => { let img: HTMLImageElement; let editor: IEditor; let triggerEvent: jasmine.Spy; + let originalDevicePixelRatio: PropertyDescriptor | undefined; beforeEach(async () => { + // generateDataURL sizes the output canvas as targetWidth/Height * window.devicePixelRatio + // ("Adjust the canvas size and scaling for high display resolution"). The expected newSrc + // values below were captured at 100% screen scale (devicePixelRatio === 1), so on a host + // running at any other scale the generated PNG would be larger and the dimension assertions + // would fail. Pin devicePixelRatio to 1 so these tests are deterministic at any screen scale. + originalDevicePixelRatio = Object.getOwnPropertyDescriptor(window, 'devicePixelRatio'); + Object.defineProperty(window, 'devicePixelRatio', { + configurable: true, + get: () => 1, + }); + // Create a fresh model image per test. It is otherwise shared module-level state, and // applyChange persists/clears editingInfo on it, so a stale rotation/crop from a prior // test would make checkEditInfoState misclassify the next one (flaky across spec order). @@ -80,6 +92,12 @@ describe('applyChange', () => { afterEach(() => { img?.parentNode?.removeChild(img); + + if (originalDevicePixelRatio) { + Object.defineProperty(window, 'devicePixelRatio', originalDevicePixelRatio); + } else { + delete (window as any).devicePixelRatio; + } }); function runTest(input: ContentModelDocument, callback: () => boolean) {