From a18c1f6bb6bb038bcec178c85164600c0e1969d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 May 2026 16:03:42 +0000 Subject: [PATCH 1/2] build(deps-dev): bump systeminformation from 5.31.5 to 5.31.6 Bumps [systeminformation](https://github.com/sebhildebrandt/systeminformation) from 5.31.5 to 5.31.6. - [Release notes](https://github.com/sebhildebrandt/systeminformation/releases) - [Changelog](https://github.com/sebhildebrandt/systeminformation/blob/master/CHANGELOG.md) - [Commits](https://github.com/sebhildebrandt/systeminformation/compare/v5.31.5...v5.31.6) --- updated-dependencies: - dependency-name: systeminformation dependency-version: 5.31.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e714912..d0a20b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7101,9 +7101,9 @@ "license": "MIT" }, "node_modules/systeminformation": { - "version": "5.31.5", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.5.tgz", - "integrity": "sha512-5SyLdip4/3alxD4Kh+63bUQTJmu7YMfYQTC+koZy7X73HgNqZSD2P4wOZQWtUncvPvcEmnfIjCoygN4MRoEejQ==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.6.tgz", + "integrity": "sha512-Uv2b2uGGM6ns+26czgW2cYRabYdnswM0ddSOOlryHOaelzsmDSet1iM/NT7VOYxW8x/BW+HkY+b1Ve2pLTSGSA==", "dev": true, "license": "MIT", "os": [ From f0ec83e1179a82b1f65cc2745594f7adfc693a87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 13 May 2026 21:20:09 +0000 Subject: [PATCH 2/2] fix: use useLayoutEffect for test event listener to prevent Cypress race condition Root cause: useEffect registers the test:targetClick listener after the browser paints, creating a race where Cypress finds the target-sphere DOM element and dispatches events before the listener is ready. Fix: switch to useLayoutEffect (runs before paint) so the listener is always registered by the time any Cypress test can dispatch events. Also add cy.wait(100) after event dispatch in screenshots.cy.ts, consistent with the pattern in gameplay.cy.ts, to give React time to process state updates. Agent-Logs-Url: https://github.com/Hack23/game/sessions/cc45c339-eb55-475b-8b72-29b9fab0ce47 Co-authored-by: pethers <1726836+pethers@users.noreply.github.com> --- cypress/e2e/screenshots.cy.ts | 5 ++++- src/App.tsx | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cypress/e2e/screenshots.cy.ts b/cypress/e2e/screenshots.cy.ts index cf6c794..f90865f 100644 --- a/cypress/e2e/screenshots.cy.ts +++ b/cypress/e2e/screenshots.cy.ts @@ -60,7 +60,10 @@ describe("Game Visual Documentation", () => { win.dispatchEvent(new CustomEvent('test:targetClick')); win.dispatchEvent(new CustomEvent('test:targetClick')); }); - + + // Wait for React to process the state updates (consistent with gameplay.cy.ts pattern) + cy.wait(100); + // Verify score updated cy.get("[data-testid=score-value]").should("not.contain", "0"); diff --git a/src/App.tsx b/src/App.tsx index 342d798..a30ff16 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { Canvas } from "@react-three/fiber"; -import { useRef, useState, useCallback, useEffect } from "react"; +import { useRef, useState, useCallback, useEffect, useLayoutEffect } from "react"; import type { JSX } from "react"; import { useGameState } from "./hooks/useGameState"; import { useAudioManager } from "./hooks/useAudioManager"; @@ -96,7 +96,10 @@ function App(): JSX.Element { const gameStateRef = useRef(gameState); gameStateRef.current = gameState; - useEffect(() => { + // useLayoutEffect (not useEffect) ensures the listener is registered synchronously + // before the browser paints, preventing a race where Cypress finds the target-sphere + // in the DOM before the test event listener is ready to receive events. + useLayoutEffect(() => { const handleTestTargetClick = (): void => { const gs = gameStateRef.current; if (gs.isPlaying && gs.timeLeft > 0 && gs.targets.length > 0) {