Skip to content

Instantly share code, notes, and snippets.

@rgabs
Created February 15, 2024 13:24
Show Gist options
  • Select an option

  • Save rgabs/da14e58dda6732db76d00a026f602b97 to your computer and use it in GitHub Desktop.

Select an option

Save rgabs/da14e58dda6732db76d00a026f602b97 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name DVSA finder - This scripts find the slots on or before the specified date/month around a postcode, every 50seconds
// @namespace Script Runner Pro
// @match https://driverpracticaltest.dvsa.gov.uk/manage*
// @grant none
// ==/UserScript==
const MAX_NO_OF_MONTH = 2; // Alert will be triggered when the available month is atleast Feb.
const MAX_DATE = 27; // Example: 27/2
const TIMEOUT = 50000; // Search will be triggered 50 seconds after the page load.
const TEST_AREA_POST_CODE = 'wd25';
window.$ = window.$ || document.querySelector;
(function() {
'use strict';
try {
if(document.title === "Booking details - Change booking") { // View booking flow
setTimeout(handleViewBookingFlow, 1000);
return;
}
if(document.title.toLowerCase().includes("search limit reached")) {
throw "Search limit reached!";
}
console.log('Loaded the result page and the slots are ', getAvailability());
if(getAvailability().length > 0) {
notify(function onFinish () {
alert(`Slot(s) before or on ${MAX_DATE}/${MAX_NO_OF_MONTH}/2024 are available in ${JSON.stringify(getAvailability())}`);
});
}
if($("#search-results").length === 0) { // The search button hasn't been clicked once
searchArea();
}
setTimeout(searchArea, TIMEOUT);
}
catch(e) {
console.log('caught', e);
setTimeout(() => {
console.log('Navigating back to the login page');
window.location = "https://www.gov.uk/change-driving-test"; // Navigate to the login page.
}, TIMEOUT);
}
})();
function handleViewBookingFlow() {
console.log('clicking on the change test center btn');
$('#test-centre-change')[0].click();
}
/*
function isInvalidSearchPage() {
return $('#main-iframe')?.src?.includes("https://driverpracticaltest.dvsa.gov.uk/_Incapsula_Resource") ||
($("#main") && $("#main")[0]?.innerText?.toLowerCase().includes("search limit reached")) ||
($('.underlay-wrapper') && $('.underlay-wrapper')[0]?.innerText.toLowerCase().includes("search limit reached"));
}
*/
function searchArea() {
if($('#test-centres-input')[0])
$('#test-centres-input')[0].value = TEST_AREA_POST_CODE;
$("#test-centres-submit").click();
}
function extractDateFromHeading(el) {
const fullDate = el.innerText.split(' ').pop(); // 02/07/2024
const testCenterName = el.parentElement.firstElementChild.innerText;
return {
date: fullDate.split('/')[0],
month: fullDate.split('/')[1],
year: fullDate.split('/')[2],
testCenterName,
}
}
function getAvailability() {
return [...document.querySelectorAll(".test-centre-details h5")]
.filter(h => !h.innerText.includes("No tests found"))
.map(extractDateFromHeading)
.filter(({month, date}) => (month <= MAX_NO_OF_MONTH) && (date <= MAX_DATE));
}
function getFirstAvailableLocation() {
return document.querySelectorAll(".test-centre-details h4")[0].innerText;
}
function notify(onFinish, duration = 200) {
var context = new AudioContext()
var o = context.createOscillator()
o.type = "sine"
o.connect(context.destination)
o.start();
let timer = setTimeout(() => {
clearTimeout(timer);
o.stop();
onFinish && requestAnimationFrame(onFinish);
}, duration);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment