A full-featured competitive exam mock test platform, hosted on GitHub Pages.
No backend. No cloud. All data lives in your browser (test-urself.db via IndexedDB + localStorage).
Live demo: https://<your-username>.github.io/mock-test/
| Feature | Details |
|---|---|
| Exams supported | JEE Mains, JEE Advanced, NEET, NDA, UPSC CSE, CAT, GATE, CUET, SSC CGL, IBPS PO, CLAT, GRE, SAT, GMAT |
| Multi-paper exams | NDA (Math + GAT), JEE Adv (P1 + P2), UPSC (GS + CSAT) with inter-paper break timer |
| Question types | MCQ (single), MCQ (multi-correct), Integer value, Section A/B |
| Marking schemes | Per-exam, per-section, auto-loaded from config.json |
| Calculator | On-screen, mouse-only (enabled per exam, e.g. CAT) |
| Login system | Roll number (10-digit) + password (5-char) generated on registration |
| Fake profile | Name, DOB, phone, email, exam, date/time – all labelled FAKE |
| Photo | Camera/upload → always replaced by default manga avatar (safety) |
| Persistence | IndexedDB (test-urself.db) + localStorage, auto-saved every 1 second |
| Crash recovery | Session restored on next visit; timer resumes automatically |
| Question rendering | Questions and options rendered as canvas images (prevents copy/paste) |
| PYQ tags | Questions marked with pyq field show a PYQ badge |
| Results | Score, accuracy, topic-wise table, donut + bar + line charts |
| Improvement | Score trend over last 10 tests |
| Adaptive UI | Sidebar grid on desktop; bottom nav + modal grid on mobile |
| Weekly scraper | GitHub Actions workflow scrapes open PYQ sources every Sunday |
| Question validation | CI workflow validates all question bank JSONs on every push |
mock-test/
├── index.html # Login / Register
├── dashboard.html # Exam picker + history + charts
├── exam.html # Exam interface
├── results.html # Result analysis
├── 404.html
├── css/
│ └── styles.css
├── js/
│ ├── db.js # IndexedDB + localStorage persistence
│ ├── auth.js # Register / login / roll-no generation
│ ├── exam.js # Exam engine (timer, scoring, state)
│ ├── render.js # Canvas renderer for questions/options
│ ├── calculator.js # On-screen calculator (mouse-only)
│ └── charts.js # Canvas charts (donut, bar, line)
├── assets/
│ └── profile-default.svg # Default profile avatar (manga style)
├── exams/
│ ├── registry.json # List of all exams + colors
│ ├── nda/
│ │ ├── config.json # Exam config (papers, marking, duration)
│ │ └── questions/
│ │ ├── maths/ # q001.json, q002.json …
│ │ └── gat/
│ ├── jee/
│ │ ├── config.json
│ │ └── questions/
│ │ ├── physics/
│ │ ├── chemistry/
│ │ └── maths/
│ ├── jee-adv/ …
│ ├── neet/ …
│ ├── upsc/ …
│ └── cat/ …
├── scripts/
│ ├── scraper.py # Weekly question bank scraper
│ ├── select_questions.py # Utility: select N questions for a paper
│ └── gen_assets.py # Generate profile PNG from SVG
└── .github/workflows/
├── deploy.yml # Auto-deploy to GitHub Pages on push to main
├── scraper.yml # Weekly scraper (Sunday 00:00 UTC)
└── validate.yml # Validate question JSON on every push
git clone https://github.com/<you>/mock-test.git
cd mock-test- Go to Settings → Pages
- Source: GitHub Actions
git add .
git commit -m "initial deploy"
git push origin mainThe deploy.yml workflow fires automatically.
Questions live in exams/<exam>/questions/<subject>/q001.json etc.
Each file is a JSON array of question objects:
[
{
"id": "nda-math-unique-id",
"text": "What is $\\int_0^{\\pi} \\sin x \\, dx$?",
"options": ["0", "1", "2", "-2"],
"correct": [2],
"type": "mcq",
"subject": "maths",
"topic": "Calculus",
"difficulty": "easy",
"pyq": { "exam": "NDA", "year": 2022, "paper": "I" },
"solution": "[-cos x]₀^π = 1+1 = 2"
}
]Types:
mcq– single correct (index into options array)mcq_multi– multiple correct (array of indices)integer– numeric answer ("correct": [42])
Multiple files are merged automatically. Name them q001.json, q002.json, etc.
Each exam has exams/<id>/config.json. Key fields:
{
"id": "nda",
"name": "NDA & NA",
"papers": [
{
"id": "nda-math",
"name": "Paper I – Mathematics",
"duration": 150,
"totalQuestions": 120,
"totalMarks": 300,
"subjects": [
{ "id": "maths", "name": "Mathematics", "folder": "maths", "questions": 120 }
],
"marking": { "correct": 2.5, "wrong": -0.83, "unattempted": 0 },
"questionTypes": ["mcq"],
"hasCalculator": false,
"shuffleQuestions": true,
"shuffleOptions": true
}
],
"isMultiPaper": true,
"breakBetweenPapers": 30
}# All exams, 24-hour limit
python scripts/scraper.py --all --max-hours 24
# Specific exam
python scripts/scraper.py --exam nda --subject maths
# Specific exam, all subjects
python scripts/scraper.py --exam jeeThe scraper runs weekly automatically via GitHub Actions (Sunday midnight UTC).
You can also trigger it manually from Actions → Weekly Question Scraper → Run workflow.
- No server. No database. No cloud.
- All user data (profile, sessions, results) stored in your browser only.
IndexedDBdatabase name:test-urself- Local storage key prefix:
user:,session:,result: - Clearing browser cache/storage deletes everything. A warning is shown before every exam.
- Photos: even if a user uploads/captures a photo, the platform always uses the default avatar — no real photos are stored.
- Add entry to
exams/registry.json - Create
exams/<id>/config.json(copy from an existing one) - Create
exams/<id>/questions/<subject>/folders - Add question JSON files
- Optionally add scraper sources in
scripts/scraper.py - Push → auto-deploys