HotPot's drag and drop was by far the easiest and the funniest one to automate.

As you can see, the developers clearly have an eye for design. For this one, I decided to check out the code first. I used inspect element on the "Tarkista" (check answers) button, which showed me that it called a CheckAnswers function. Now, I'm not exactly a webdev, so I clicked on the button to show me to the source of the event.

Which brought me to this:

Which wasn't particularly useful, but as you can see on the left, something called "attempt.php" was selected. This was literally just the webpage, but I didn't realize this at the time. It told me some error and to refresh the page when I clicked on it, so I did. It then showed to me that it was just the webpage. I then decided to search up CheckAnswers on it, and I found this disgusting pile of garbage (you don't need to read it):
function CheckAnswers(ForceQuizEvent){
HP.onclickCheck();
if (Locked == true){return;}
var TotalCorrect = 0;
Score = 0;
var Feedback = '';
if (AnswersTried.length > 0){AnswersTried += ' | ';}
var i, j;
for (i=0; i<D.length; i++){
if (i>0){AnswersTried += ',';}
AnswersTried += D[i][1] + '.' + D[i][2] + '';
if ((D[i][2] == D[i][1])&&(D[i][2] > 0)){
TotalCorrect++;
} else {
DC[i].SetL(DC[i].GetL() + 10);
DC[i].Highlight();
}
}
Score = Math.floor((100*(TotalCorrect-Penalties))/F.length);
var AllDone = false;
if (TotalCorrect == F.length) {
AllDone = true;
}
if (AllDone == true){
Feedback = YourScoreIs + ' ' + Score + '%.';
ShowMessage(Feedback + '<br />' + CorrectResponse);
} else {
Feedback = YourScoreIs + ' ' + Score + '%.' + '<br />' + IncorrectResponse;
ShowMessage(Feedback);
Penalties++;
}
if (AllDone){
var QuizEvent = HP.EVENT_COMPLETED;
} else if (ForceQuizEvent){
var QuizEvent = ForceQuizEvent;
} else if (TimeOver){
var QuizEvent = HP.EVENT_TIMEDOUT;
} else {
var QuizEvent = HP.EVENT_CHECK;
}
if (HP.end_of_quiz(QuizEvent)) {
if (window.Interval) {
clearInterval(window.Interval);
}
TimeOver = true;
Locked = true;
Finished = true;
}
if (Finished || HP.sendallclicks){
if (QuizEvent==HP.EVENT_COMPLETED){
setTimeout('HP_send_results('+QuizEvent+')', SubmissionTimeout);
} else {
HP_send_results(QuizEvent);
}
}
}
As you can see, it's an unreadable sack of shit. Still, from this I managed to deduce that the D array must hold something relating to the answers. After some investigation, I found out how it works.
D = [
0: [
0: text_of_answer,
1: target_answer,
2: given_answer
],
1: [
0: text_of_answer,
1: target_answer,
2: given_answer
],
...
]
text_of_answer is the text in the draggable box, target_answer is where you're supposed to drag it, and given_answer is where you have dragged the box. This leads to a fairly obvious solution: just set given_answer to target_answer.
for (i = 0; i < D.length; i++) {
D[i][2] = D[i][1]
}
It worked first try.

This took me max 10 minutes, and is quite funny in its simplicity. But there's more. Look at this line:
Score = Math.floor((100*(TotalCorrect-Penalties))/F.length);
TotalCorrect is reset at the beginning of CheckAnswers, but Penalties is not. Perhaps we could set Penalties to a negative number, and that would allow us to get > 100% score.
for (i = 0; i < D.length; i++) {
D[i][2] = D[i][1]
}
Penalties = -56789
It worked:


There were some other things I discovered too, but I've written enough.