QTI.JS
IMS QTI Delivery Engine in Javascript. Serverless. Themable. Responsive. Single Page App. Zero config. Supports all features of QTI v2.2, including all interactions, all response processing operators, templates, adaptive items, all feedback types, rubrics, branchRules and preConditions, selection/ordering, linear/nonlinear, and results reporting.
Install / Use
/learn @QTIJS/QTI.JSREADME
QTI.JS
This is the initial "preview/beta" release of the QTI.JS Delivery Engine for IMS Question & Test Interoperability. It supports the latest version of QTI, Version 2.2.2.
Preview
If you would like to have a no-fuss preview, the build outputs of this project can be seen at:
http://qtihub.org.s3-website-us-east-1.amazonaws.com
This is an Amazon S3 bucket setup for static web hosting, containing the sample QTI assessment tests built by this project. Included in the preview are almost all the QTI v2.2 examples distributed by IMS Global Learning Consortium, along with some other sample tests. No login is required, and no results will be reported anywhere.
The preview is best viewed using a recent version of Google Chrome. There has so far not been very much testing with other browsers; so if you want to try a different browser, you might encounter problems, and almost certainly will if the browser is more than a couple of years old. If you run into any problems, I would appreciate hearing about them.
Build
The QTI.JS build is done with a bash script. From the directory where you cloned the repository, enter the command.
tools/build.sh
This will generate:
- a package directory
- a zipped version of the package directory, called qtijs.package.zip
- a docroot directory, a copy of the test directory with symlinks resolved, for uploading to a static web hosting service.
The Amazon S3 bucket mentioned in the previous section is just a copy of the docroot generated by the build.
The package directory and the qtijs.package.zip archive file are both already in the repository; so a build is necessary only if you have changed the QTI.JS source code or want your own copy of docroot for testing or some other purpose.
QTI.JS Package Contents
The QTI.JS package consists of the following.
- the Javascript source files in src, bundled into a single script file, called qti.js.
- a Single Page Application (SPA) HTML file, called index.html.
- a subirectory, theme, containing the CSS stylesheets and image files for the default QTI.JS theme, basic.
- the QTI.JS LICENSE, the MIT license.
- a VERSION file, which gives QTI.JS version of the package
- this README.md file
The Single Page Application loads qti.js, which finds QTI XML content by various means, and transforms it with its referenced resources into HTML. The generated HTML is appended to the initially empty body of the SPA, and event handlers are set up to manage user interactions, to do response and outcome processing, and to submit candidate responses and outcomes.
The SPA also loads a MathJax Javascript from a Content Distribution Network, for MathML support. This is the only external dependency of QTI.JS, and it can be removed from the SPA if you do not need MathML support.
The name of the SPA is not required to be index.html, in case you need some other file to have that name. The SPA file is also editable, but you should bear in mind that QTI.JS will be trying to coexist with whatever edits you make.
If you do edit the SPA, perhaps to put a header or footer on the page, or to load scripts to handle customInteractions, etc, you might need to edit the QTI.JS theme too. For example, the default basic QTI.JS theme assumes it can position fixed elements at the top of the browser viewport.
Deployment
The following sections cover various scenarios for deploying QTI.JS.
You have a QTI 2.2 Content Package with a single test
Many QTI-compliant authoring systems have the ability to export a QTI "content package". This is just a zip archive containing a manifest file, called imsmanifest.xml, along with the actual content, consisting of XML and other files.
To deploy a QTI content package with QTI.JS, do the following:
- unzip the content package into an empty "deployment" directory.
- unzip qtijs.package.zip into the same directory, or copy the files from the package directory into the deployment directory.
- upload the deployment directory to a static web hosting service.
The URL for the test would then be something like http://example.com/mytest/index.html, mytest being the name of the deployment directory on the webhost. This would be omitted if the deployment has been copied to the root of the web host. Depending on the web host, the index.html part of the URL may also be unnecessary. If you have changed the name of the QTI.JS Single Page Application from the default of index.html, the URL would need to reflect your different name. If everything defaults right, the minimal absolute URL for a QTI.JS test can just be the URL for a domain, http://example.com/, which would make the QTI content the top level content of the domain.
If you proceed this way, when a user invokes the URL of the SPA in a browser, qti.js will load. It will then load the manifest, imsmanifest.xml, and play the first test it finds listed in the manifest. Currently, if this test does not exist, QTI.JS will not continue by trying any subsequent tests in the manifest, but will simply display a blank screen.
The manifest-based approach is illustrated by the tao sample, but it works only if there is just one test in the manifest or you can edit the manifest to make the one test you need be first.
You have QTI 2.2 files for a single test
Do the following:
- copy your QTI 2.2 content to an empty "deployment" directory.
- unzip qtijs.package.zip, or copy the files in the QTI.JS package directory into the deployment directory.
- let QTI.JS know which file is its "root" by renaming the root file to index.xml, or if you prefer your own name, and your web hosting service supports symbolic links, create a symbolic link called index.xml pointing to the root file.
- upload the deployment directory to a static web hosting service.
As with the previous deployment scenario, the URL for the test will be something like: http://example.com/mytest/index.html , with mytest and index.html possibly omitted.
This is how most of the sample tests are deployed for the preview.
You have QTI 2.2 files for multiple tests
Do the following:
- copy your QTI 2.2 content to an empty "deployment" directory.
- unzip qtijs.package.zip, or copy the files in the QTI.JS package directory into the deployment directory.
- upload the deployment directory to a static web hosting service.
Since there is no manifest or index.xml to let QTI.JS know which test to play, this must be specified using the root query string parameter on the URL for the QTI.JS Single Page App. For example, http://example.com/mytest/index.html?root=sometest.xml
This lets you run any of multiple QTI tests out of the same deployment directory. This approach comes at the cost of a more complex URL for the SPA, which users probably won't be able to remember, and which therefore can only be used in links.
The root parameter can point to a file containing any of the following:
- an assessmentTest
- an assessmentSection
- an assessmentItem
Your QTI.JS package and QTI 2.2 content have different locations
The previous deployment scenarios assumed that the QTI.JS SPA *index.html", qti.js, theme subdirectory, and the QTI 2.2 content are all deployed to the same directory on a web host. This is not actually required and more complex cross-directory and cross-domain deployments are possible.
The root query string parameter mentioned in the previous section takes a URL as its value, either relative or absolute. This means that the QTI.JS package and the root XML file of the QTI content can be at different locations within the same HTTP/HTTPS domain or even be within different HTTP/HTTPS domains.
With different domains, Cross-Origin Resource Sharing (CORS) comes into the picture. However, CORS and security allowing, a deployment of the QTI.JS package anywhere on the web can be used to run a QTI assessmentTest which is anywhere on the web, containing QTI content resources from anywhere on the web, even if the servers with those resources are oblivious to QTI.JS. For example, the following URL will play an assessmentTest on example.com without any QTI.JS presence at all on example.com:
http://qtihub.org/package/index.html?root=http://example.com/test.xml
In this URL, the QTI.JS package is on qtihub.org and the root of the QTI assessment content is on example.com. Possibly some of the resources referenced via hrefs in the assessmentTest are on yet other servers.
(Incidentally http://qtihub.org/package/index.html is a real URL and refers to an Amazon S3 bucket. You are welcome to use it for testing, at least for the beta/preview period. Take it easy on the hits, though.)
As powerful as cross-origin deployment may potentially be, the need for CORS to be configured on the servers which hold the QTI content perhaps makes this deployment scenario an advanced one.
The QTI.JS package and/or the content are in the local file system
It is possible to have the QTI.JS package in the local file system, accessed by the browser using the file: URL scheme. A QTI.JS SPA loaded from the file system can access QTI content on the Web. For example,
file://path-to-qtijs/package/index.html?root=http://example.com/test.xml
This results in a cross-origin request, so CORS has to be enabled on the servers with the QTI content (example.com, and possibly others, in this case).
In addition, in some browsers, a QTI.JS SPA with a file: origin can access QTI content in the local file system, also with a file: origin, PROVIDED the browser is started in a special mode or the content is in a special location. For example, the URI
file://path-to-qtijs/index.html?root=path-to-test/test.xml
starts QTI.JS from the local file path-to-test/index.html to run the test in the local file path-to-test/test.xml.
For this to work in Chrome on a desktop, the bro
