From d992e34801856fed7c924298390e011af3f3ed93 Mon Sep 17 00:00:00 2001 From: Nathan Richards Date: Wed, 17 Jun 2026 18:31:13 +0200 Subject: [PATCH] fix: ensure first tracking events for html and python projects only fire once --- .../WebComponentProject/WebComponentProject.jsx | 12 +++++++++--- .../WebComponentProject/WebComponentProject.test.js | 5 +++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/WebComponentProject/WebComponentProject.jsx b/src/components/WebComponentProject/WebComponentProject.jsx index 2456573a5..0a830c6f8 100644 --- a/src/components/WebComponentProject/WebComponentProject.jsx +++ b/src/components/WebComponentProject/WebComponentProject.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useMediaQuery } from "react-responsive"; import { marked } from "marked"; @@ -64,6 +64,7 @@ const WebComponentProject = ({ ); const isMobile = useMediaQuery({ query: MOBILE_MEDIA_QUERY }); const [codeHasRun, setCodeHasRun] = useState(codeHasBeenRun); + const prevCodeRunTriggeredRef = useRef(false); const dispatch = useDispatch(); const renderer = new marked.Renderer(); @@ -120,10 +121,15 @@ const WebComponentProject = ({ }, [dispatch, projectInstructions, permitInstructionsOverride]); useEffect(() => { - if (codeRunTriggered) { + if (codeRunTriggered && !prevCodeRunTriggeredRef.current) { document.dispatchEvent(runStartedEvent({ step: currentStepPosition })); setCodeHasRun(true); - } else if (codeHasRun) { + } + prevCodeRunTriggeredRef.current = codeRunTriggered; + }, [codeRunTriggered, currentStepPosition]); + + useEffect(() => { + if (!codeRunTriggered && codeHasRun) { const mz_criteria = Sk.sense_hat ? Sk.sense_hat.mz_criteria : { ...defaultMZCriteria }; diff --git a/src/components/WebComponentProject/WebComponentProject.test.js b/src/components/WebComponentProject/WebComponentProject.test.js index a673d6255..8827dc08a 100644 --- a/src/components/WebComponentProject/WebComponentProject.test.js +++ b/src/components/WebComponentProject/WebComponentProject.test.js @@ -65,6 +65,7 @@ const renderWebComponentProject = ({ describe("When state set", () => { beforeEach(() => { + runStartedHandler.mockClear(); renderWebComponentProject({ instructions: "My amazing instructions", codeRunTriggered: true, @@ -83,8 +84,8 @@ describe("When state set", () => { expect(codeChangedHandler.mock.lastCall[0].detail).toHaveProperty("step"); }); - test("Triggers runStarted event", () => { - expect(runStartedHandler).toHaveBeenCalled(); + test("Triggers runStarted event once", () => { + expect(runStartedHandler).toHaveBeenCalledTimes(1); expect(runStartedHandler.mock.lastCall[0].detail).toHaveProperty("step"); });