Thank you! your feedback is a game changer. Yes, setTimeout should not be used as it’s not tracked by this.state. Just by replacing the setTimeout with an if statement within the setInterval to invoke switch whenever (remaining) duration is -1000 (0 is suppose to be working, but the spec needs to see the 00:00 for a second, thus the -1000), it passed most specs, leaving 2 errors:
25 + 5 clock has paused but time continued elapsing: expected '53' to equal '55'
which means there’s a 2 seconds difference between the pause and replay during the test case running. Easy patch were to just add 2000ms and update the duration, which could make the app pass the test specs… on first run only, but if we ran a consecutive test, it’ll fail the subsequent test. Partly because at the end of the test, my clock kept running and could not be stopped nor reset.
This is the codes for the flawed app:
https://codepen.io/shugyoza/pen/wvqRPqx
After I tweaked some more, I passed all the specs with this one:
https://codepen.io/shugyoza/pen/RwZvNyE?editors=1111
Hypothetically, the two last mentioned errors were caused by my chaining the beep.play, this.setState(()=>), and clearInterval() SERIALLY, causing the different timestamps between the alarm sound started to play, the (left)state.duration captured, and the clearing of setInterval (as much as 2 seconds). This flaw was resolved by moving all of them inside the this.setState(()=>) callback function so that the state updating and the invocation of all required functions were done at once, thus they’re synchronized.
Also I moved the clearInterval() to on top of the reset() method so that either there is or there is not an active clock ticking, this clock will stop. Thus this fixed the symptom where after running the test specs, my clock were always kept ticking and can’t be stopped nor reset.
Thank you for your help! I hope this note may be beneficial for someone after me.