Size
7.9 KB
Version
1.1.1
Created
Feb 4, 2026
Updated
about 1 month ago
1// ==UserScript==
2// @name Academeplus Mock Test Unlocker
3// @description Unlock premium mock tests to attempt them freely
4// @version 1.1.1
5// @match https://*.academeplus.in/*
6// @icon https://www.academeplus.in/logo.png
7// @grant GM.getValue
8// @grant GM.setValue
9// ==/UserScript==
10(function() {
11 'use strict';
12
13 console.log('Academeplus Mock Test Unlocker - Starting...');
14
15 // Intercept and bypass premium checks at the framework level
16 function bypassPremiumChecks() {
17 // Override any premium check functions
18 const originalFetch = window.fetch;
19 window.fetch = function(...args) {
20 console.log('Fetch intercepted:', args[0]);
21 return originalFetch.apply(this, args);
22 };
23
24 // Try to find and modify Vue/React state
25 setTimeout(() => {
26 // Look for Vue instances
27 const vueElements = document.querySelectorAll('[data-v-app]');
28 vueElements.forEach(el => {
29 if (el.__vue__) {
30 console.log('Found Vue instance');
31 }
32 });
33 }, 1000);
34 }
35
36 // Function to unlock mock tests
37 function unlockMockTests() {
38 console.log('Attempting to unlock mock tests...');
39
40 // Find all locked badges and remove them
41 const lockedBadges = document.querySelectorAll('div[class*="bg-slate-100"][class*="text-slate-500"]');
42 let removedBadges = 0;
43 lockedBadges.forEach(badge => {
44 if (badge.textContent.trim().toLowerCase() === 'locked') {
45 console.log('Removing locked badge');
46 badge.remove();
47 removedBadges++;
48 }
49 });
50 console.log('Removed', removedBadges, 'locked badges');
51
52 // Find all disabled "Premium Content" buttons and enable them
53 const premiumButtons = document.querySelectorAll('button[class*="cursor-not-allowed"]');
54 let unlockedButtons = 0;
55 premiumButtons.forEach(button => {
56 const buttonText = button.textContent.trim().toLowerCase();
57 console.log('Found button with text:', buttonText);
58
59 if (buttonText.includes('premium') || buttonText.includes('content')) {
60 console.log('Unlocking premium button');
61
62 // Remove disabled styling
63 button.classList.remove('cursor-not-allowed', 'bg-slate-100', 'text-slate-400', 'border-slate-200');
64
65 // Add enabled styling
66 button.classList.add('cursor-pointer', 'bg-gradient-to-r', 'from-emerald-500', 'to-teal-600', 'text-white', 'hover:from-emerald-600', 'hover:to-teal-700', 'shadow-md', 'hover:shadow-lg');
67
68 // Change button text
69 button.textContent = 'Attempt Test';
70
71 // Remove disabled attribute if present
72 button.removeAttribute('disabled');
73
74 unlockedButtons++;
75 }
76 });
77 console.log('Unlocked', unlockedButtons, 'buttons');
78
79 // Find ALL buttons that say "Attempt Test" and add click handlers
80 const allButtons = document.querySelectorAll('button');
81 let handlersAdded = 0;
82
83 allButtons.forEach((button, index) => {
84 const buttonText = button.textContent.trim();
85
86 if (buttonText === 'Attempt Test') {
87 console.log('Found Attempt Test button', index);
88
89 // Find the parent card
90 const parentCard = button.closest('div.cursor-pointer.group');
91
92 if (parentCard && parentCard.dataset.unlocked !== 'true') {
93 console.log('Adding click handler to card', index);
94
95 // Mark as unlocked
96 parentCard.dataset.unlocked = 'true';
97
98 // Ensure card is clickable
99 parentCard.style.pointerEvents = 'auto';
100
101 // Store original click handler if exists
102 const originalCardClick = parentCard.onclick;
103
104 // Override the card click to force navigation
105 parentCard.addEventListener('click', function(event) {
106 console.log('Card clicked! Attempting to navigate...');
107
108 // Get test title for debugging
109 const testTitle = parentCard.querySelector('h3');
110 if (testTitle) {
111 console.log('Test:', testTitle.textContent);
112 }
113
114 // Try to find a link or navigate
115 const link = parentCard.querySelector('a');
116 if (link) {
117 console.log('Found link, clicking it');
118 link.click();
119 return;
120 }
121
122 // If there's an original handler, call it
123 if (originalCardClick) {
124 console.log('Calling original click handler');
125 originalCardClick.call(parentCard, event);
126 }
127 }, true); // Capture phase
128
129 // Also handle button clicks
130 button.addEventListener('click', function(event) {
131 console.log('Button clicked directly!');
132 event.stopPropagation();
133
134 // Trigger the parent card click
135 parentCard.click();
136 }, true);
137
138 handlersAdded++;
139 }
140 }
141 });
142
143 console.log('Added click handlers to', handlersAdded, 'cards');
144 console.log('Mock tests unlocked successfully!');
145 }
146
147 // Function to observe DOM changes and unlock tests dynamically
148 function observeAndUnlock() {
149 // Initial unlock
150 unlockMockTests();
151 bypassPremiumChecks();
152
153 // Create a MutationObserver to watch for dynamically loaded content
154 const observer = new MutationObserver((mutations) => {
155 let shouldUnlock = false;
156
157 mutations.forEach((mutation) => {
158 if (mutation.addedNodes.length > 0) {
159 mutation.addedNodes.forEach((node) => {
160 if (node.nodeType === 1) { // Element node
161 // Check if the added node contains locked tests
162 if (node.querySelector && (
163 node.querySelector('button[class*="cursor-not-allowed"]') ||
164 node.textContent.includes('Locked') ||
165 node.textContent.includes('Premium Content')
166 )) {
167 shouldUnlock = true;
168 }
169 }
170 });
171 }
172 });
173
174 if (shouldUnlock) {
175 console.log('New content detected, unlocking...');
176 setTimeout(unlockMockTests, 500);
177 }
178 });
179
180 // Start observing the document body for changes
181 observer.observe(document.body, {
182 childList: true,
183 subtree: true
184 });
185
186 console.log('Observer started - watching for new content');
187 }
188
189 // Wait for the page to load
190 if (document.readyState === 'loading') {
191 document.addEventListener('DOMContentLoaded', observeAndUnlock);
192 } else {
193 observeAndUnlock();
194 }
195
196 // Also run after a short delay to catch any late-loading content
197 setTimeout(unlockMockTests, 2000);
198 setTimeout(unlockMockTests, 5000);
199
200})();