From 8085c0c430e3aa53aa17d81033a4a1ffb075eab6 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Tue, 2 Dec 2025 14:27:06 +0000 Subject: [PATCH 01/13] added a tittle element --- Sprint-3/alarmclock/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..ff2d3b453 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm clock app
From b3ad0d8c3b804cbc3d2113339c0e60c9c6b2e018 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Tue, 2 Dec 2025 14:42:39 +0000 Subject: [PATCH 02/13] updated the title --- Sprint-3/alarmclock/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index ff2d3b453..2657f276e 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Alarm clock app + Alarm clock-app
From d33934f3307bd85c55c81af14fb23e9d7a347ac3 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Fri, 5 Dec 2025 15:10:22 +0000 Subject: [PATCH 03/13] added a jest.config.js file --- Sprint-3/alarmclock/alarmclock.js | 79 +++++++++++++++++++++++++- Sprint-3/alarmclock/alarmclock.test.js | 2 + Sprint-3/alarmclock/jest.config.js | 6 ++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 Sprint-3/alarmclock/jest.config.js diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..858e4591e 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,81 @@ -function setAlarm() {} + + +// function setAlarm() {} + +let timeLeft = 0; +let timer = null; +let flashing = null; + +// DOM references +const display = document.getElementById("timeRemaining"); +const setButton = document.getElementById("set"); +const stopButton = document.getElementById("stop"); + +// Event listeners +setButton.addEventListener("click", setAlarm); +stopButton.addEventListener("click", stopAlarm); + +// Show 00:00 on load +updateDisplay(0); + +// ------------------------------- +// FUNCTIONS +// ------------------------------- + +function setAlarm() { + const input = document.getElementById("alarmSet").value; + const parsed = parseInt(input, 10); + + if (isNaN(parsed) || parsed < 0) return; + + timeLeft = parsed; + + // Update display immediately + updateDisplay(timeLeft); + + // Clear previous countdown + clearInterval(timer); + + // Start countdown every 1000ms + timer = setInterval(() => { + if (timeLeft > 0) { + timeLeft--; + updateDisplay(timeLeft); + } + + if (timeLeft === 0) { + clearInterval(timer); + startAlarm(); + } + }, 1000); +} + +function updateDisplay(seconds) { + const mins = String(Math.floor(seconds / 60)).padStart(2, "0"); + const secs = String(seconds % 60).padStart(2, "0"); + display.innerText = `Time Remaining: ${mins}:${secs}`; +} + +function startAlarm() { + if (typeof playAlarm === "function") playAlarm(); + + // Flashing background + flashing = setInterval(() => { + document.body.style.backgroundColor = + document.body.style.backgroundColor === "red" ? "orange" : "red"; + }, 300); +} + +function stopAlarm() { + if (typeof pauseAlarm === "function") pauseAlarm(); + + clearInterval(flashing); + flashing = null; + document.body.style.backgroundColor = ""; +} + +module.exports= setAlarm; + // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/alarmclock.test.js b/Sprint-3/alarmclock/alarmclock.test.js index 85b7356dc..48e07f812 100644 --- a/Sprint-3/alarmclock/alarmclock.test.js +++ b/Sprint-3/alarmclock/alarmclock.test.js @@ -35,6 +35,8 @@ afterEach(() => { page = null; }); + + test("should set heading when button is clicked", () => { const heading = page.window.document.querySelector("#timeRemaining"); const input = page.window.document.querySelector("#alarmSet"); diff --git a/Sprint-3/alarmclock/jest.config.js b/Sprint-3/alarmclock/jest.config.js new file mode 100644 index 000000000..2ce3b50ef --- /dev/null +++ b/Sprint-3/alarmclock/jest.config.js @@ -0,0 +1,6 @@ +/** @type {import('jest').Config} */ +module.exports = { + testEnvironment: "jsdom", + verbose: true, + testMatch: ["**/*.test.js"], +}; From 9c3ee51abb34e3e0e8d376ffefc8007dac367f0e Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Sat, 6 Dec 2025 13:08:06 +0000 Subject: [PATCH 04/13] passed all the tests --- Sprint-3/alarmclock/alarmclock.js | 22 +++++++++++++++------- Sprint-3/alarmclock/alarmclock.test.js | 8 +++++--- Sprint-3/alarmclock/index.html | 2 +- Sprint-3/alarmclock/package.json | 6 +++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 858e4591e..904dee88d 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -7,16 +7,18 @@ let timer = null; let flashing = null; // DOM references -const display = document.getElementById("timeRemaining"); +window.addEventListener("DOMContentLoaded", () => { +// const display = document.getElementById("timeRemaining"); const setButton = document.getElementById("set"); const stopButton = document.getElementById("stop"); // Event listeners -setButton.addEventListener("click", setAlarm); -stopButton.addEventListener("click", stopAlarm); +// if (setButton) setButton.addEventListener("click", () => playAlarm()); +if (stopButton) stopButton.addEventListener("click", stopAlarm); // Show 00:00 on load updateDisplay(0); +}); // ------------------------------- // FUNCTIONS @@ -53,18 +55,23 @@ function setAlarm() { function updateDisplay(seconds) { const mins = String(Math.floor(seconds / 60)).padStart(2, "0"); const secs = String(seconds % 60).padStart(2, "0"); - display.innerText = `Time Remaining: ${mins}:${secs}`; + + const display = document.getElementById("timeRemaining"); + if (!display) return; + display.textContent = `Time Remaining: ${mins}:${secs}`; } function startAlarm() { - if (typeof playAlarm === "function") playAlarm(); + playAlarm(); // Flashing background - flashing = setInterval(() => { + if (!flashing){ + flashing = setTimeout(() => { document.body.style.backgroundColor = document.body.style.backgroundColor === "red" ? "orange" : "red"; }, 300); } +} function stopAlarm() { if (typeof pauseAlarm === "function") pauseAlarm(); @@ -74,7 +81,8 @@ function stopAlarm() { document.body.style.backgroundColor = ""; } -module.exports= setAlarm; + +// module.exports= setAlarm; // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/alarmclock.test.js b/Sprint-3/alarmclock/alarmclock.test.js index 48e07f812..1a1b1bca6 100644 --- a/Sprint-3/alarmclock/alarmclock.test.js +++ b/Sprint-3/alarmclock/alarmclock.test.js @@ -3,6 +3,8 @@ There are some Tests in this file that will help you work out if your code is wo */ const path = require("path"); +// const { setAlarm } = require("./alarmclock.js"); + const { JSDOM } = require("jsdom"); let page = null; @@ -91,16 +93,16 @@ test("should count down every 1000 ms", () => { test("should play audio when the timer reaches zero", () => { const input = page.window.document.querySelector("#alarmSet"); - const button = page.window.document.querySelector("#set"); + const startButton = page.window.document.querySelector("#set"); const mockPlayAlarm = jest.fn(); page.window.playAlarm = mockPlayAlarm; input.value = "10"; - button.click(); + startButton.click(); expect(mockPlayAlarm).toHaveBeenCalledTimes(0); jest.runAllTimers(); - + expect(mockPlayAlarm).toHaveBeenCalledTimes(1); }); diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 2657f276e..66360c467 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -15,6 +15,6 @@

Time Remaining: 00:00

- + diff --git a/Sprint-3/alarmclock/package.json b/Sprint-3/alarmclock/package.json index e1331e071..52d9b0c52 100644 --- a/Sprint-3/alarmclock/package.json +++ b/Sprint-3/alarmclock/package.json @@ -13,5 +13,9 @@ "bugs": { "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme" + "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "dependencies": { + "@testing-library/jest-dom": "^6.9.1", + "jest": "^27.5.1" + } } From bffd4b46e3f68f116b918bd388f2e786cfd64d8d Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Wed, 10 Dec 2025 19:23:13 +0000 Subject: [PATCH 05/13] checked an empty value first and any error --- Sprint-3/alarmclock/alarmclock.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 904dee88d..0b709971b 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -25,10 +25,22 @@ updateDisplay(0); // ------------------------------- function setAlarm() { - const input = document.getElementById("alarmSet").value; - const parsed = parseInt(input, 10); + const inputEl = document.getElementById("alarmSet"); +const input = inputEl.value.trim(); - if (isNaN(parsed) || parsed < 0) return; +// Check empty input +if (input === "") { + alert("Please enter a number of seconds."); + return; +} + +const parsed = parseInt(input, 10); + +// Check invalid or negative number +if (isNaN(parsed) || parsed < 0) { + alert("Please enter a valid non-negative number."); + return; +} timeLeft = parsed; From 7ded28041a83a38da4db3cc339b63cbf5106db12 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 12:22:28 +0000 Subject: [PATCH 06/13] removed pauseAlarm from stop alarm function --- Sprint-3/alarmclock/alarmclock.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 0b709971b..61986b63c 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,6 +1,6 @@ -// function setAlarm() {} + let timeLeft = 0; let timer = null; @@ -8,12 +8,12 @@ let flashing = null; // DOM references window.addEventListener("DOMContentLoaded", () => { -// const display = document.getElementById("timeRemaining"); + const setButton = document.getElementById("set"); const stopButton = document.getElementById("stop"); // Event listeners -// if (setButton) setButton.addEventListener("click", () => playAlarm()); + if (stopButton) stopButton.addEventListener("click", stopAlarm); // Show 00:00 on load @@ -86,7 +86,6 @@ function startAlarm() { } function stopAlarm() { - if (typeof pauseAlarm === "function") pauseAlarm(); clearInterval(flashing); flashing = null; From c9aa8f1292e01ca3dd5c2ab086d51500bcbc9fa4 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 12:34:01 +0000 Subject: [PATCH 07/13] reset any flashing and playing audio --- Sprint-3/alarmclock/alarmclock.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 61986b63c..30c7a6416 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -49,6 +49,11 @@ if (isNaN(parsed) || parsed < 0) { // Clear previous countdown clearInterval(timer); + clearInterval(flashing); // stop flashing if it was active + flashing = null; + document.body.style.backgroundColor = ""; + pauseAlarm(); // stop any playing audio + audio.currentTime = 0; // Start countdown every 1000ms timer = setInterval(() => { From 0b85c7a553eed4cb9a34d1d74ec59bc72d969afe Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 12:47:54 +0000 Subject: [PATCH 08/13] added space --- Sprint-3/alarmclock/alarmclock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 30c7a6416..a77cb6889 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -121,6 +121,6 @@ function playAlarm() { function pauseAlarm() { audio.pause(); -} +} window.onload = setup; From e618de271b57a52067650a6ef1cfccb606eb961b Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 12:52:33 +0000 Subject: [PATCH 09/13] removed the set button variable --- Sprint-3/alarmclock/alarmclock.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index a77cb6889..4d5a8962c 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -9,7 +9,6 @@ let flashing = null; // DOM references window.addEventListener("DOMContentLoaded", () => { -const setButton = document.getElementById("set"); const stopButton = document.getElementById("stop"); // Event listeners From 76f1971862ab8559260de0108d071782ff9ab83f Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 13:02:27 +0000 Subject: [PATCH 10/13] alarm starts immediately --- Sprint-3/alarmclock/alarmclock.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 4d5a8962c..d4887d45a 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -54,18 +54,19 @@ if (isNaN(parsed) || parsed < 0) { pauseAlarm(); // stop any playing audio audio.currentTime = 0; - // Start countdown every 1000ms - timer = setInterval(() => { - if (timeLeft > 0) { - timeLeft--; - updateDisplay(timeLeft); - } - - if (timeLeft === 0) { - clearInterval(timer); - startAlarm(); - } - }, 1000); + function tick() { + if (timeLeft > 0) { + timeLeft--; + updateDisplay(timeLeft); + } else { + clearInterval(timer); + startAlarm(); + } +} + +// Run once immediately for consistency +tick(); +timer = setInterval(tick, 1000); } function updateDisplay(seconds) { From b6af9d4c06647378b21bea188c6dc74a55524e09 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 17:22:31 +0000 Subject: [PATCH 11/13] formatted it --- Sprint-3/alarmclock/alarmclock.js | 82 ++++++++++++-------------- Sprint-3/alarmclock/alarmclock.test.js | 4 +- 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index d4887d45a..76e663fd1 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,22 +1,17 @@ - - - - let timeLeft = 0; let timer = null; let flashing = null; // DOM references window.addEventListener("DOMContentLoaded", () => { + const stopButton = document.getElementById("stop"); -const stopButton = document.getElementById("stop"); - -// Event listeners + // Event listeners -if (stopButton) stopButton.addEventListener("click", stopAlarm); + if (stopButton) stopButton.addEventListener("click", stopAlarm); -// Show 00:00 on load -updateDisplay(0); + // Show 00:00 on load + updateDisplay(0); }); // ------------------------------- @@ -25,21 +20,21 @@ updateDisplay(0); function setAlarm() { const inputEl = document.getElementById("alarmSet"); -const input = inputEl.value.trim(); + const input = inputEl.value.trim(); -// Check empty input -if (input === "") { - alert("Please enter a number of seconds."); - return; -} + // Check empty input + if (input === "") { + alert("Please enter a number of seconds."); + return; + } -const parsed = parseInt(input, 10); + const parsed = parseInt(input, 10); -// Check invalid or negative number -if (isNaN(parsed) || parsed < 0) { - alert("Please enter a valid non-negative number."); - return; -} + // Check invalid or negative number + if (isNaN(parsed) || parsed < 0) { + alert("Please enter a valid non-negative number."); + return; + } timeLeft = parsed; @@ -48,33 +43,33 @@ if (isNaN(parsed) || parsed < 0) { // Clear previous countdown clearInterval(timer); - clearInterval(flashing); // stop flashing if it was active + clearInterval(flashing); // stop flashing if it was active flashing = null; document.body.style.backgroundColor = ""; - pauseAlarm(); // stop any playing audio + pauseAlarm(); // stop any playing audio audio.currentTime = 0; function tick() { - if (timeLeft > 0) { - timeLeft--; - updateDisplay(timeLeft); - } else { - clearInterval(timer); - startAlarm(); + if (timeLeft > 0) { + timeLeft--; + updateDisplay(timeLeft); + } else { + clearInterval(timer); + startAlarm(); + } } -} -// Run once immediately for consistency -tick(); -timer = setInterval(tick, 1000); + // Run once immediately for consistency + tick(); + timer = setInterval(tick, 1000); } function updateDisplay(seconds) { const mins = String(Math.floor(seconds / 60)).padStart(2, "0"); const secs = String(seconds % 60).padStart(2, "0"); - + const display = document.getElementById("timeRemaining"); - if (!display) return; + if (!display) return; display.textContent = `Time Remaining: ${mins}:${secs}`; } @@ -82,25 +77,22 @@ function startAlarm() { playAlarm(); // Flashing background - if (!flashing){ + if (!flashing) { flashing = setTimeout(() => { - document.body.style.backgroundColor = - document.body.style.backgroundColor === "red" ? "orange" : "red"; - }, 300); -} + document.body.style.backgroundColor = + document.body.style.backgroundColor === "red" ? "orange" : "red"; + }, 300); + } } function stopAlarm() { - clearInterval(flashing); flashing = null; document.body.style.backgroundColor = ""; } - // module.exports= setAlarm; - // DO NOT EDIT BELOW HERE var audio = new Audio("alarmsound.mp3"); @@ -121,6 +113,6 @@ function playAlarm() { function pauseAlarm() { audio.pause(); -} +} window.onload = setup; diff --git a/Sprint-3/alarmclock/alarmclock.test.js b/Sprint-3/alarmclock/alarmclock.test.js index 1a1b1bca6..4ee7c7816 100644 --- a/Sprint-3/alarmclock/alarmclock.test.js +++ b/Sprint-3/alarmclock/alarmclock.test.js @@ -37,8 +37,6 @@ afterEach(() => { page = null; }); - - test("should set heading when button is clicked", () => { const heading = page.window.document.querySelector("#timeRemaining"); const input = page.window.document.querySelector("#alarmSet"); @@ -103,6 +101,6 @@ test("should play audio when the timer reaches zero", () => { expect(mockPlayAlarm).toHaveBeenCalledTimes(0); jest.runAllTimers(); - + expect(mockPlayAlarm).toHaveBeenCalledTimes(1); }); From fc92b97dd8028b425fc0e8efe3635e6d018abdd2 Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 17:27:15 +0000 Subject: [PATCH 12/13] wrapped an implementation inside a function --- Sprint-3/alarmclock/alarmclock.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 76e663fd1..ad7156319 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -42,12 +42,17 @@ function setAlarm() { updateDisplay(timeLeft); // Clear previous countdown + function resetAlarmState() { clearInterval(timer); - clearInterval(flashing); // stop flashing if it was active + clearInterval(flashing); flashing = null; document.body.style.backgroundColor = ""; - pauseAlarm(); // stop any playing audio + pauseAlarm(); audio.currentTime = 0; +} + +resetAlarmState(); + function tick() { if (timeLeft > 0) { From 0c30fddfc2ef918ce5745b512e87ddb4ff3003cd Mon Sep 17 00:00:00 2001 From: Fithi Teklom Date: Thu, 18 Dec 2025 17:39:50 +0000 Subject: [PATCH 13/13] modifications are made when timer is set to 0 --- Sprint-3/alarmclock/alarmclock.js | 39 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index ad7156319..5febd6757 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -43,32 +43,31 @@ function setAlarm() { // Clear previous countdown function resetAlarmState() { - clearInterval(timer); - clearInterval(flashing); - flashing = null; - document.body.style.backgroundColor = ""; - pauseAlarm(); - audio.currentTime = 0; -} - -resetAlarmState(); + clearInterval(timer); + clearInterval(flashing); + flashing = null; + document.body.style.backgroundColor = ""; + pauseAlarm(); + audio.currentTime = 0; + } + resetAlarmState(); - function tick() { - if (timeLeft > 0) { + if (timeLeft === 0) { + // Special case: alarm should start immediately + startAlarm(); + } else { + timer = setInterval(() => { timeLeft--; updateDisplay(timeLeft); - } else { - clearInterval(timer); - startAlarm(); - } - } - // Run once immediately for consistency - tick(); - timer = setInterval(tick, 1000); + if (timeLeft === 0) { + clearInterval(timer); + startAlarm(); + } + }, 1000); + } } - function updateDisplay(seconds) { const mins = String(Math.floor(seconds / 60)).padStart(2, "0"); const secs = String(seconds % 60).padStart(2, "0");