-
Notifications
You must be signed in to change notification settings - Fork 125
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
handleSessionTime #37
base: master
Are you sure you want to change the base?
Conversation
Seems like a good addition to the wrapper code to me... at the moment anyone wanting to use the wrapper has to provide their own implementation (here's how we do it in the Adapt framework) so having this provided by the wrapper would save anyone wanting to use it from having to create their own implementation - whilst still allowing someone to do so if they choose/need to. |
On the README for this repo it does say:
I would argue that having the wrapper handle session time for you goes a long way towards achieving that aim |
Thanks for submitting. I am willing to merge, but I need to be sure it doesn't introduce any bugs. I will take a look when I have some spare time (I've been pretty busy lately, so it my be a while). In the meantime, if anyone has tested and can confirm it works for them, feedback would be appreciated. |
i’ll try and have a look over the next week |
Hi guys! Did you have the time to check this? |
src/JavaScript/SCORM_API_wrapper.js
Outdated
this.set("cmi.core.session_time",pipwerks.UTILS.MillisecondsToCMIDuration(n)); | ||
break; | ||
case "2004": | ||
//success = this.set("cmi.session_time",centisecsToISODuration(Math.floor(n/10))); |
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.
please remove commented-out line of code
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.
removed!
src/JavaScript/SCORM_API_wrapper.js
Outdated
//the time format is different on scorm 1.2 or 2004, so we use | ||
//different conversions depending on the case | ||
case "1.2" : | ||
//success = this.set("cmi.core.session_time",MillisecondsToCMIDuration(n)); |
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.
please remove commented-out line of code
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.
removed!
@canvasplay no sorry it's been a horribly busy few months! One thing that might help is if you had some unit tests showing that those functions have the correct output for various inputs... |
@moloko, about the unit testing, I'm not a unit testing expert and I don't really know how to fit them in this project... but ok, I accept the challenge :) I have added in my repo an inital approach to unit testing for the sake of this matter. Please could you take a look at my approach and provide some feedback to implement the testing part? PS: Maybe I am introducing too much complexity to the repo... :D |
Hey! Happy new year! 😄 I have moved forward with QUnit as unit testing engine. I think it is a better way so we can do crossbrowser testing and there is no need of an AMD compatible module. I have created some basic tests... Did I miss any test case? Looking forward for your feedback. |
src/JavaScript/SCORM_API_wrapper.js
Outdated
|
||
var dtm = new Date(); | ||
|
||
//in the next line you substract the time recorded when initialising |
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.
typo: 'substract' should be 'subtract'
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.
thanks for doing this! one last comment is that I would add a few more tests for different cs/ms values for each of the two functions you're testing, currently you've only got one test of an actual time in each.
src/JavaScript/SCORM_API_wrapper.js
Outdated
str += "T"; | ||
if (nH > 0) str += nH + "H"; | ||
if (nMin > 0) str += nMin + "M"; | ||
if (nCs > 0) str += (nCs / 100) + "S"; |
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.
indentation is a bit off here
src/JavaScript/SCORM_API_wrapper.js
Outdated
pipwerks.UTILS.MillisecondsToCMIDuration = function(n){ | ||
|
||
//Convert duration from milliseconds to 0000:00:00.00 format | ||
n = (!n || n<0)? 0 : n; //default value and force positive duration |
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.
could you add some spacing around the operators for consistency with the rest of the code?
src/JavaScript/SCORM_API_wrapper.js
Outdated
Return: String | ||
---------------------------------------------------------------------------- */ | ||
|
||
pipwerks.UTILS.MillisecondsToCMIDuration = function(n){ |
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.
it's just my opinion but I think the function name could be shortened to msToCMIDuration
and the intention of it would still be clear. similarly csToISODuration
still seems like a clear name to me.
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.
totally agree ;)
src/JavaScript/SCORM_API_wrapper.js
Outdated
var h = "0" + Math.floor(n / 3600000); | ||
var m = "0" + dtm.getMinutes(); | ||
var s = "0" + dtm.getSeconds(); | ||
hms = h.substr(h.length-2)+":"+m.substr(m.length-2)+":"; |
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.
could you add some spacing around the operators for consistency (and readability)
src/JavaScript/SCORM_API_wrapper.js
Outdated
var nMin = Math.floor(nCs /6000); | ||
nCs -= nMin * 6000 | ||
// Now we can construct string | ||
if (nY > 0) str += nY + "Y"; |
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 love that you've assumed someone may have spent years in the same session - that would be one dedicated learner ;-) I didn't even bother going above days in my implementation!!
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.
We are not gonna set the limits of the eLearning ;)
src/JavaScript/SCORM_API_wrapper.js
Outdated
|
||
pipwerks.UTILS.MillisecondsToCMIDuration = function(n){ | ||
|
||
//Convert duration from milliseconds to 0000:00:00.00 format |
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.
could you move this comment to the main comment block above?
test/JavaScript/test.js
Outdated
var t2 = 1513938095752; | ||
var d = t2 - t1; | ||
|
||
assert.equal(pipwerks.UTILS.centisecsToISODuration(d), 'PT17M11.2S'); |
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.
could you add descriptions for your tests? e.g.
assert.equal(pipwerks.UTILS.centisecsToISODuration(null), 'PT0H0M0S', 'Check null is correctly handled');
Besides the formatting changes, the tests part looks much better now 😄 |
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.
Thanks for the updates, all looking pretty good from a review point of view aside from some final (minor) things.
I've now started testing for real (i.e. against an LMS - Moodle 1.9 purely because that's what I have installed on my PC but I'll try and find some time to check in SCORM Cloud too) and have been doing so by comparing the time your new code logs against what our existing code would do.
My reasoning behind this is that we've been using our code internally for around 8 years on many hundreds of e-learning courses (mainly SCORM1.2) and the same code is of course used in Adapt so will have been used on even more hundreds of courses built by the many people/companies who use Adapt.
in SCORM 1.2 it all looks fine to me, the only real difference I can see is that our code is slightly more precise i.e. it will log the time as 0000:00:03.46 whereas your code does 00:00:03 - but that seems fine to me.
In SCORM 2004, however, the differences are slightly bigger - here's a few examples...
Ours: PT3S.92S
Yours: PT4.3S
Ours: PT45S.60S
Yours: PT45.98S
Ours: PT2M34S.71S
Yours: PT2M35.02S
Certainly Moodle is not flagging the format of yours as being a problem so I'm guessing it's just showing the same information only in a slightly different way? Equally there will be a very slight difference in time due our code running first- it's on the line immediately before our code calls scorm.quit()
so there shouldn't be much in it.
I did most of the testing in Firefox (open source ftw!!) but also did a quick check in IE11 and Chrome. All fine in those.
src/JavaScript/SCORM_API_wrapper.js
Outdated
var s = "0" + dtm.getSeconds(); | ||
hms = h.substr(h.length - 2) + ":"+ m.substr(m.length - 2) + ":"; | ||
hms += s.substr(s.length - 2); | ||
return hms |
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.
missing semicolon
src/JavaScript/SCORM_API_wrapper.js
Outdated
@@ -33,11 +33,13 @@ pipwerks.SCORM = { //Define the SCORM object | |||
version: null, //Store SCORM version. | |||
handleCompletionStatus: true, //Whether or not the wrapper should automatically handle the initial completion status | |||
handleExitMode: true, //Whether or not the wrapper should automatically handle the exit mode | |||
handleSessionTime: true, //Whether or not the wrapper should automatically handle the session time |
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.
trailing space on the end of this line (and on the majority of lines you have added)
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.
and just a thought but defaulting this to true
could cause problems for anyone who goes to update to the latest version in their project... if they don't realised this functionality has been added then they run the risk of having two separate bits of code trying to set the session_time... I'll defer to @pipwerks as to what he thinks the default should be.
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.
Changed to false
, I do agree this way will allow a more "retrocompatible" upgrade.
src/JavaScript/SCORM_API_wrapper.js
Outdated
var nH = Math.floor(nCs / 360000); | ||
nCs -= nH * 360000; | ||
var nMin = Math.floor(nCs /6000); | ||
nCs -= nMin * 6000 |
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.
missing semi colon
Hi @moloko! I have added the missing semicolons and fixed all the wired trailing spaces, also changed the default value for I'm glad to hear that everything is working properly in your testing!! aside from some final (minor) things 😄 I guess the amount of time differences your are getting are due to code execution delays as you mention, from my experience, SCORM request/response communication is not always speedlight. I'm confused about the time format differences in SCORM 2004. I have checked the ISO and could not find any references to that double designator "S" for the seconds. Yours: PT3S.92S Looks like yours is trying to distinguish seconds from centiseconds, so in this example your format is defining two separate values for seconds and using the same designator twice ("3S" and ".92S"). Anyways I guess both formats are still valid. My concern about your format is that I'm not sure what is the final value, depending on server's implementation I can figure out two possibilities, the two values get sum or maybe one of the two gets ignored. What do you think? |
I suspect your version is probably correct. Like I say, most of our experience is with SCORM 1.2 so I'm certainly not claiming that our code is correct, more just raising it as something to look at! Maybe @pipwerks knows the answer... Anyway I'm happy with all of this now and would be happy to have it go in as-is - but this repository belongs to @pipwerks so I will need to defer to him at this point as I can't take it any further. |
@canvasplay @pipwerks please ignore everything I said about the SCORM 2004 time format - @canvasplay is absolutely correct to say 'format should be number+designator' i.e. PT4.3S and not PT4S.3S. Turns out that the code I was comparing against had an old version of our 'convertToSCORM2004Time' function that had a bug in the time format that was causing an additional 'S' to be included. The worst part is that I found, logged and fixed that bug - so I really should have known what the correct format is..! |
Hi guys Thanks for the work on this. I've been quiet on the thread, but I've been following your posts. I haven't really talked about it much, but I wrote an entirely new wrapper years ago that included session time handling and a bunch of other features. Never released it because the wrapper was focused on improving CMI interaction handling, but most LMSs don't allow reporting on CMI interaction data fields, so why bother. I shelved it. :/ Anyway, the way I approached session timer was to add an option Regarding keeping exact time... session time handling will rarely align perfectly with time kept by the LMS, because the point at which the timer is started and the point at which it is stopped will vary. For example, an LMS like SumTotal will automatically start a session timer once the course window is opened, even if the SCORM API has not been initialized. (There is no rule that the SCORM API has to be initialized the second the window opens.) Some developers may choose to initialize the course after a user action, such as clicking a 'start' button. Likewise, the course may have its SCORM API terminated before the user closes the course window, but the LMS may keep tracking session time until the window is closed. So IMO it's safer to work under the assumption that time tracking is imperfect, and you can only do so much. For kicks, here are excerpts from my code:
In the
In the
@canvasplay , your code is significantly different than mine (notably the |
I just noticed I started work on the second wrapper in 2009 and last worked on it in 2011. Seven to nine years ago. Sheesh, time flies. |
Hey @pipwerks! Is the new wrapper going to replace this one or are you planning to create a new one? Cheers! |
No plans to officially release the other wrapper, though one of these days I might dust it off and post it for anyone interested. |
Hi! About your concern on understanding my Regarding the other differences with your code, I am sorry but you are the only one who can see the whole thing cause the other wrapper is not online.... Differences apart, you will make me happy by accepting this pull request 😄 , and will make me feel like the effort was worth it. Thanks so much!! |
@pipwerks don't suppose you've had a chance to look at this have you? I think what @canvasplay has done would be a really useful addition... |
👀 |
Geez, it has been almost a year since this was submitted. Sorry about that. I have made some minor updates to the wrapper, including adding module support. However I am still wary of adding new features for fear of introducing bugs. I am open to adding support for timers, but I will need to review again to see which path I feel comfortable with -- namely, which approach is the simplest and most reliable. Thanks |
@pipwerks there are some unit tests in place if you want to verify it all behaves as it should... |
Hello! I'm back :D |
Hi!
I've been using this for years, since some LMS platforms does not handle automatically the session time I have added an option for the wrapper to handle it. Maybe someone would find it helpful too.
If you dont mind, could you pull it? I have followed the same approach as other options like "handleCompletionStatus", adapt it as you consider.
Keep in touch!
Thanks.