Repository: capricorn86/happy-dom
Pull request #681 (2022-12-19 07:32:30)

#681@minor: Add scrollX, scrollY, pageXOffset, pageYOffset to window.
Add [scrollX](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollX), [scrollY](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY), [pageXOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window/pageXOffset) and [pageYOffset](https://developer.mozilla.org/en-US/docs/Web/API/Window/pageYOffset)  to `Window`


Patch:
diff --git a/packages/happy-dom/src/window/IWindow.ts b/packages/happy-dom/src/window/IWindow.ts
index 3cb9eed8..019cfc9b 100644
--- a/packages/happy-dom/src/window/IWindow.ts
+++ b/packages/happy-dom/src/window/IWindow.ts
@@ -245,6 +245,10 @@ export default interface IWindow extends IEventTarget, NodeJS.Global {
 	readonly sessionStorage: Storage;
 	readonly localStorage: Storage;
 	readonly performance: Performance;
+	readonly pageXOffset: number;
+	readonly pageYOffset: number;
+	readonly scrollX: number;
+	readonly scrollY: number;
 
 	/**
 	 * Evaluates code.
diff --git a/packages/happy-dom/src/window/Window.ts b/packages/happy-dom/src/window/Window.ts
index ac232fb9..1c1638b8 100644
--- a/packages/happy-dom/src/window/Window.ts
+++ b/packages/happy-dom/src/window/Window.ts
@@ -483,6 +483,42 @@ export default class Window extends EventTarget implements IWindow {
 		this.document._onWindowReady();
 	}
 
+	/**
+	 * The number of pixels that the document is currently scrolled horizontally
+	 *
+	 * @returns number
+	 */
+	public get scrollX(): number {
+		return this.document?.documentElement?.scrollLeft ?? 0;
+	}
+
+	/**
+	 * The read-only Window property pageXOffset is an alias for scrollX.
+	 *
+	 * @returns number
+	 */
+	public get pageXOffset(): number {
+		return this.scrollX;
+	}
+
+	/**
+	 * The number of pixels that the document is currently scrolled vertically
+	 *
+	 * @returns number
+	 */
+	public get scrollY(): number {
+		return this.document?.documentElement?.scrollTop ?? 0;
+	}
+
+	/**
+	 * The read-only Window property pageYOffset is an alias for scrollY.
+	 *
+	 * @returns number
+	 */
+	public get pageYOffset(): number {
+		return this.scrollY;
+	}
+
 	/**
 	 * The CSS interface holds useful CSS-related methods.
 	 *


Test patch:
diff --git a/packages/happy-dom/test/window/Window.test.ts b/packages/happy-dom/test/window/Window.test.ts
index 92fb7aa5..99304c20 100644
--- a/packages/happy-dom/test/window/Window.test.ts
+++ b/packages/happy-dom/test/window/Window.test.ts
@@ -667,37 +667,63 @@ describe('Window', () => {
 
 	for (const functionName of ['scroll', 'scrollTo']) {
 		describe(`${functionName}()`, () => {
-			it('Sets the properties scrollTop and scrollLeft.', () => {
+			it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset', () => {
 				window[functionName](50, 60);
 				expect(window.document.documentElement.scrollLeft).toBe(50);
 				expect(window.document.documentElement.scrollTop).toBe(60);
+				expect(window.pageXOffset).toBe(50);
+				expect(window.pageYOffset).toBe(60);
+				expect(window.scrollX).toBe(50);
+				expect(window.scrollY).toBe(60);
 			});
 
-			it('Sets the properties scrollTop and scrollLeft using object.', () => {
+			it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset using object.', () => {
 				window[functionName]({ left: 50, top: 60 });
 				expect(window.document.documentElement.scrollLeft).toBe(50);
 				expect(window.document.documentElement.scrollTop).toBe(60);
+				expect(window.pageXOffset).toBe(50);
+				expect(window.pageYOffset).toBe(60);
+				expect(window.scrollX).toBe(50);
+				expect(window.scrollY).toBe(60);
 			});
 
-			it('Sets only the property scrollTop.', () => {
+			it('Sets only the property scrollTop, pageYOffset, and scrollY', () => {
 				window[functionName]({ top: 60 });
 				expect(window.document.documentElement.scrollLeft).toBe(0);
 				expect(window.document.documentElement.scrollTop).toBe(60);
+				expect(window.pageXOffset).toBe(0);
+				expect(window.pageYOffset).toBe(60);
+				expect(window.scrollX).toBe(0);
+				expect(window.scrollY).toBe(60);
 			});
 
-			it('Sets only the property scrollLeft.', () => {
+			it('Sets only the property scrollLeft, pageXOffset, and scrollX', () => {
 				window[functionName]({ left: 60 });
 				expect(window.document.documentElement.scrollLeft).toBe(60);
 				expect(window.document.documentElement.scrollTop).toBe(0);
+				expect(window.document.documentElement.scrollLeft).toBe(60);
+				expect(window.document.documentElement.scrollTop).toBe(0);
+				expect(window.pageXOffset).toBe(60);
+				expect(window.pageYOffset).toBe(0);
+				expect(window.scrollX).toBe(60);
+				expect(window.scrollY).toBe(0);
 			});
 
-			it('Sets the properties scrollTop and scrollLeft with animation.', async () => {
+			it('Sets the properties scrollTop, scrollLeft, scrollY, scrollX, pageXOffset and pageYOffset with animation.', async () => {
 				window[functionName]({ left: 50, top: 60, behavior: 'smooth' });
 				expect(window.document.documentElement.scrollLeft).toBe(0);
 				expect(window.document.documentElement.scrollTop).toBe(0);
+				expect(window.pageXOffset).toBe(0);
+				expect(window.pageYOffset).toBe(0);
+				expect(window.scrollX).toBe(0);
+				expect(window.scrollY).toBe(0);
 				await window.happyDOM.whenAsyncComplete();
 				expect(window.document.documentElement.scrollLeft).toBe(50);
 				expect(window.document.documentElement.scrollTop).toBe(60);
+				expect(window.pageXOffset).toBe(50);
+				expect(window.pageYOffset).toBe(60);
+				expect(window.scrollX).toBe(50);
+				expect(window.scrollY).toBe(60);
 			});
 		});
 	}