Skip to content

Instantly share code, notes, and snippets.

@ZhangYiJiang
Last active January 21, 2019 05:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ZhangYiJiang/01d58e0964485932d47bfff22a0d06ec to your computer and use it in GitHub Desktop.
Save ZhangYiJiang/01d58e0964485932d47bfff22a0d06ec to your computer and use it in GitHub Desktop.
Automatically take IVLE quizzes (DO NOT USE ON QUIZZES THAT HAVE LIMITED ATTEMPTS)
// ==UserScript==
// @name Automatic Test Taker
// @namespace yijiang
// @description Automatically takes repeatable tests
// @include https://ivle.nus.edu.sg/v1/Assessment/Student/assessment_content.aspx*
// @include https://ivle.nus.edu.sg/v1/Assessment/Student/result_details.aspx*
// @include https://ivle.nus.edu.sg/v1/Assessment/Student/result_main.aspx*
// @version 1.1
// @include https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// @grant none
// ==/UserScript==
function getAssessment(str) {
var query = str.split('?')[1].split('&');
for (var i = 0; i < query.length; i++) {
var parts = query[i].split('=');
if (parts[0] === 'assessmentid') {
return parts[1];
}
}
}
function getData(assessment) {
var data = JSON.parse(window.localStorage.getItem('testscript') || '{}');
return data.hasOwnProperty(assessment) ?
data[assessment] : { wrong: [], correct: [], checking: {} };
}
function saveData(assessment, data) {
var original = JSON.parse(window.localStorage.getItem('testscript') || '{}');
original[assessment] = data;
window.localStorage.setItem('testscript', JSON.stringify(original));
}
// Random int (exclude max)
function randInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
function randItem(arr) {
return arr[randInt(0, arr.length)];
}
// Quiz taking page
if (window.location.toString().indexOf('assessment_content') !== -1) {
var form = $('form[action^="./assessment_content"]');
var startBtn = $('<button>', {
'class': 'btn btn-primary pull-right',
text: 'Automatic Test Taker'
}).click(function(evt) {
evt.preventDefault();
var assessment = getAssessment(form.attr('action'));
var answers = getData(assessment);
var questions = {};
answers.checking = {};
answers.correct.forEach((id) => {
var input = $('#' + id).prop('checked', true),
name = input.prop('name');
input.siblings().css('color', '#3c763d');
$(`input[name="${name}"]`).addClass('do-not-choose');
});
answers.wrong.forEach((id) => {
$('#' + id).addClass('do-not-choose')
.siblings().css('color', '#a94442');
})
$('input[type="radio"]')
.filter((i, e) => !$(e).hasClass('do-not-choose'))
.each((i, e) => {
var input = $(e),
name = input.prop('name');
if (questions.hasOwnProperty(name)) {
questions[name].push(input);
} else {
questions[name] = [input];
}
});
for (var q in questions) {
if (questions.hasOwnProperty(q)) {
var selected = randItem(questions[q]);
selected.prop('checked', true);
answers.checking[q] = selected.prop('id');
}
}
console.log(answers);
saveData(assessment, answers);
form.find('.btn.btn-danger').click();
});
form.prepend(startBtn);
}
// Quiz response details page
if (window.location.toString().indexOf('result_details') !== -1) {
var assessment = getAssessment($('#aspnetForm').prop('action'));
var answers = getData(assessment);
$('b').filter((i, e) => $(e).text().includes('Your Marks'))
.each((i, e) => {
var question = $(e).closest('.row')
.prevUntil('.form-inline')
.last().prev()
.find('b')
.text().trim();
var qnNumber = parseInt(question, 10);
var key = 'Question' + qnNumber;
var score = +$(e).closest('td').next().text().trim().match(/^\d+/)[0];
if (!answers.checking.hasOwnProperty(key))
return;
if (score > 0) {
answers.correct.push(answers.checking[key]);
} else {
answers.wrong.push(answers.checking[key]);
}
});
console.log(answers);
saveData(assessment, answers);
}
// Post quiz page
if (window.location.toString().indexOf('result_main') !== -1) {
$('button').filter((i, e) => $(e).text().indexOf('Detailed') !== -1).click();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment