-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed exam remaining time display offset #140
Conversation
if (!limitReached && secondsLeft < LIMIT) { | ||
clearInterval(timer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved this to be handled in the interval block, since I find it easier to understand.
const LIMIT = GRACE_PERIOD_SECS ? 0 - GRACE_PERIOD_SECS : 0; | ||
const CRITICAL_LOW_TIME = timeLimitMins * 60 * TIME_LIMIT_CRITICAL_PCT; | ||
const LOW_TIME = timeLimitMins * 60 * TIME_LIMIT_LOW_PCT; | ||
let liveInterval = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The control variable was moved to the useEffect block, since the component refresh would overwrite this value rendering it useless.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #140 +/- ##
==========================================
+ Coverage 93.25% 93.86% +0.61%
==========================================
Files 68 68
Lines 1052 1076 +24
Branches 291 295 +4
==========================================
+ Hits 981 1010 +29
+ Misses 66 61 -5
Partials 5 5 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks good. REALLY appreciate getting test coverage on the TimerProvider component, thank you!
Few small comments but otherwise approved 👍
be24626
to
616158e
Compare
Description
Ticket: COSMO-180 🔒
While taking an exam, the remaining time displayed in the exam timer is inconsistent. It gets an increasing offset when navigating around in a course in a way that requires a browser refresh. It appears that this does not occur when the browser does not refresh (e.g. navigating between units in the same subsection via the navigation bar). It’s usually up to a 40 second difference in either direction.
Cause
The cause for this offset was caused by the fact that we weren't using a fixed time reference for the remaining time. The endpoint returns the remaining time in seconds which was saved in the redux store, and then when the TimerProvider was rendered it was calculating the remaining time based on the current time. The first render would be accurate but after that each re-render of the component would take the same value to start the timer. This caused an offset which eventually would be corrected by a poll that happens every minute, which mitigates but does not solve the problem.
Proposed solution
In order to fix this, my approach is to calculate a
timerEnds
date at the moment we store this information in Redux, and then use this timer to calculate the seconds to show to the user. Since the date is fixed in time, no offset is created no matter the reloads.Extra changes
There are some minor issues that I detected wile working on this. For example, sometimes the frontend wanted to poll periodically to an url that was returned by the endpoint
exam_started_poll_url
, which was indicated by a comment in the codepoll url may be null if this is an LTI exam
. In my experience, these cases were showing an obscure error to the user.I've used this opportunity to reshape the error in a more descriptive way:
We are now avoiding the poll when the url is not provided to avoid this error overall, but I thought it was a nice thing to keep just in case.
Update (2024-02-27)
act()
to wrap theawait expect()
to wait for update changes, since there are state changes involved and jest expects us to useact()
when this happens.useTimeout()
to wait for the children render to subscribe to the emitter. Please check it when reviewing.Update (2024-02-29)
ping_interval
is set, it runs first at half of the time, and then each full interval. I left it as it is, but I wanted to bring attention to it.test:watch
topackage.json
's scripts that's handy when working on new tests. The coverage output gets too much in the way.