Skip to content

Instantly share code, notes, and snippets.

@tyeth
Created March 13, 2025 21:26
Show Gist options
  • Save tyeth/1a67d331e651deca6eb398b50855c5a3 to your computer and use it in GitHub Desktop.
Save tyeth/1a67d331e651deca6eb398b50855c5a3 to your computer and use it in GitHub Desktop.
async function simulateCursorMovement(startEl, endEl, duration = 1000) {
// Create fake cursor if it doesn't exist
let fakeCursor = document.getElementById('fake-cursor');
if (!fakeCursor) {
fakeCursor = document.createElement('div');
fakeCursor.id = 'fake-cursor';
Object.assign(fakeCursor.style, {
position: 'fixed',
top: '250px',
left: '250px',
width: '12px',
height: '12px',
backgroundColor: 'red',
borderRadius: '50%',
zIndex: '9999',
pointerEvents: 'none',
transition: `top 0ms, left 0ms`,
});
document.body.appendChild(fakeCursor);
}
//debugger;
if (startEl === endEl) startEl = fakeCursor;
const rectStart = startEl.getBoundingClientRect();
const rectEnd = endEl.getBoundingClientRect();
const startX = rectStart.left + rectStart.width / 2;
const startY = rectStart.top + rectStart.height / 2;
const endX = rectEnd.left + rectEnd.width / 2;
const endY = rectEnd.top + rectEnd.height / 2;
const steps = 100;
const stepDuration = duration / steps;
function triggerMouseEvent(el, type, clientX, clientY) {
el.dispatchEvent(new MouseEvent(type, {
view: window,
bubbles: true,
cancelable: true,
clientX,
clientY,
}));
}
// Set initial position immediately
fakeCursor.style.left = `${startX}px`;
fakeCursor.style.top = `${startY}px`;
// Move cursor smoothly
for (let i = 0; i <= steps; i++) {
const x = startX + ((endX - startX) * i) / steps;
const y = startY + ((endY - startY) * i) / steps;
fakeCursor.style.left = `${x}px`;
fakeCursor.style.top = `${y}px`;
const elem = document.elementFromPoint(x, y);
triggerMouseEvent(elem, 'mousemove', x, y);
await new Promise(resolve => setTimeout(resolve, stepDuration));
}
// Perform click at the end
triggerMouseEvent(endEl, 'mouseover', endX, endY);
triggerMouseEvent(endEl, 'mousedown', endX, endY);
triggerMouseEvent(endEl, 'mouseup', endX, endY);
triggerMouseEvent(endEl, 'click', endX, endY);
}
async function navigateToAdafruitIOKey() {
const menuButton = document.getElementById('mobile-menu-button');
if (!menuButton) {
console.error('Menu button not found');
return;
}
await simulateCursorMovement(menuButton, menuButton, 800);
await new Promise(r => setTimeout(r, 500));
const submenuItem = Array.from(document.querySelectorAll('a'))
.find(el => el.textContent.trim() === 'View Adafruit IO Key');
if (!submenuItem) {
console.error('Submenu item "View Adafruit IO Key" not found');
return;
}
await simulateCursorMovement(menuButton, submenuItem, 1000);
// possibly move to username next, remove cursor for now
await new Promise(r => setTimeout(r, 500));
document.getElementById('fake-cursor').remove();
}
// Execute the script
await navigateToAdafruitIOKey();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment