Skip to content

Solvro/extension-testownik

Repository files navigation

extension-testownik

Chrome MV3 extension for importing quizzes and study content from supported web apps into Testownik. The first supported source is NotebookLM Quiz App.

What Was Built

  • WXT + React + TypeScript + Tailwind v4 extension.
  • shadcn-style UI copied to Base UI primitives, using Testownik design tokens.
  • Toolbar popup for auth status, login/logout, and opening Testownik.
  • NotebookLM content scripts:
    • top frame injects Dodaj do Testownika into the Studio App footer,
    • sandbox frame reads quiz JSON from app-root[data-app-data],
    • iframe sends quiz data to the top frame with postMessage.
  • Background service worker handles OAuth2 Authorization Code + PKCE, token refresh, storage, and POST /api/quizzes/.
  • One-click import: unauthenticated users sign in first, then the quiz is created directly.
  • Imported questions are marked is_ai_generated: true.

Extension Architecture

Source integrations are isolated under src/sources/<source>/.

  • src/sources/types.ts: shared adapter contract.
  • src/sources/notebooklm/adapter.ts: source identity and mapper binding.
  • src/sources/notebooklm/mapping.ts: NotebookLM JSON to Testownik quiz body.
  • src/sources/notebooklm/footer.ts: NotebookLM-specific footer anchor logic.
  • src/sources/notebooklm/types.ts: NotebookLM payload/message types.
  • src/lib/dom.tsx: source-neutral shadow DOM mounting.
  • src/components/AddToTestownikButton.tsx: source-neutral import button.
  • src/entrypoints/background.ts: source-neutral OAuth/token/API bridge.

To add another source later, add a new src/sources/<source>/ folder, create a new content entrypoint for that site, implement SourceImportAdapter, provide a mount-target finder, and call watchSourceButtonMount.

Backend Work

  • QuizViewSet accepts OAuth2 bearer tokens in addition to JWT/session auth.
  • OAuth tokens need quizzes:write for unsafe quiz writes.
  • JWT/session quiz creation still works without OAuth scopes.
  • CORS_ALLOWED_ORIGINS must include the extension origin:
CORS_ALLOWED_ORIGINS=https://testownik.solvro.pl,chrome-extension://<EXTENSION_ID>
  • OAuth Applications now have optional Testownik metadata with logo_uri; the logo is returned by the consent and authorized-apps APIs.

Configuration

Use one target per build:

VITE_TESTOWNIK_API_BASE_URL=https://api.testownik.solvro.pl
VITE_TESTOWNIK_FRONTEND_URL=https://testownik.solvro.pl
VITE_TESTOWNIK_OAUTH_CLIENT_ID=<public OAuth client id>

Create a django-oauth-toolkit app for the extension:

  • Client type: Public
  • Grant type: Authorization code
  • Redirect URI: https://<EXTENSION_ID>.chromiumapp.org/
  • Scopes: quizzes:write
  • Logo URI: set in the Application admin inline metadata

Development

pnpm install
pnpm dev

Load .output/chrome-mv3 in chrome://extensions. After reloading the extension, refresh any open supported source page.

Build

pnpm typecheck
pnpm build
pnpm zip

The unpacked extension is in .output/chrome-mv3; the store zip is in .output.

Publish Timeline

  1. Finish OAuth app registration in local and production admin.
  2. Build the production extension and load it once to confirm the final extension ID.
  3. Add chrome-extension://<EXTENSION_ID> to backend CORS_ALLOWED_ORIGINS.
  4. Set the OAuth redirect URI to https://<EXTENSION_ID>.chromiumapp.org/.
  5. Run end-to-end import from NotebookLM to production Testownik.
  6. Create the Chrome Web Store item: screenshots, icon, description, privacy answers, single purpose, and host permission justification.
  7. Add GitHub repository variables and secrets:
    • VITE_TESTOWNIK_API_BASE_URL
    • VITE_TESTOWNIK_FRONTEND_URL
    • VITE_TESTOWNIK_OAUTH_CLIENT_ID
    • CHROME_EXTENSION_ID
    • CHROME_CLIENT_ID
    • CHROME_CLIENT_SECRET
    • CHROME_REFRESH_TOKEN
  8. Publish a GitHub release or run Publish to Chrome Web Store manually.
  9. Wait for Chrome Web Store review, then verify the published install.

Runtime Checks

  • Button appears once in the NotebookLM Studio App footer.
  • Button stays inline and truncates instead of overflowing.
  • Clicking creates the quiz directly.
  • Expired tokens refresh silently.
  • Missing quizzes:write shows an error.
  • Created Testownik quiz has correct answers, explanations, title, and AI-generated question flags.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages