VOOZH about

URL: https://dev.to/weatherclockdash/how-to-test-firefox-extensions-without-publishing-local-development-tips-5332

⇱ How to Test Firefox Extensions Without Publishing: Local Development Tips - DEV Community


How to Test Firefox Extensions Without Publishing: Local Development Tips

Publishing to AMO every time you want to test a change is slow and painful. Here's the full toolkit for local development.

Temporary Add-on Loading

The fastest way to load your extension:

  1. Open Firefox and go to about:debugging
  2. Click This Firefox in the left sidebar
  3. Click Load Temporary Add-on...
  4. Navigate to your extension folder and select manifest.json

The extension is loaded immediately. It disappears when Firefox restarts, but stays active during the session.

Auto-Reload on File Changes

Manually clicking "Reload" in about:debugging is tedious. Use web-ext for auto-reload:

npm install --save-dev web-ext

# Auto-reload on any file change
npx web-ext run --source-dir . --watch

# Or add to package.json scripts
{"scripts":{"dev":"web-ext run --source-dir .","build":"web-ext build --source-dir . --artifacts-dir dist"}}

web-ext opens a new Firefox profile with your extension loaded, and reloads it automatically when you save any file.

Inspecting the Extension's DevTools

Each extension context has its own DevTools:

For new tab page / popup:

  • Right-click anywhere on the new tab → Inspect
  • Or open DevTools on the popup while it's visible

For background scripts/service workers:

  1. Go to about:debugging#/runtime/this-firefox
  2. Click Inspect next to your extension
  3. This opens a dedicated DevTools window for the background context

Testing storage.sync

Simulate sync changes in DevTools console:

// In the extension's background context DevTools
await browser.storage.sync.set({ theme: 'dark' });
await browser.storage.sync.get(null); // Get all stored values
await browser.storage.sync.clear(); // Clear everything (for fresh testing)

Testing Across Multiple Firefox Profiles

To simulate sync across devices, use two Firefox profiles:

# Create two profiles
firefox --createprofile profile1
firefox --createprofile profile2

# Launch both simultaneously
firefox --profile profile1 &
firefox --profile profile2 &

Log into the same Firefox Account on both, install the extension on both via temporary loading, and watch changes sync.

Debugging the New Tab Override

New tab pages are special — they can't be right-clicked and inspected directly from the tab. Workarounds:

// Option 1: Open the new tab page as a regular page
// Navigate to moz-extension://YOUR-EXTENSION-ID/newtab.html

// Option 2: Log the extension ID
console.log(browser.runtime.id);
// Then navigate to moz-extension://<id>/newtab.html

Or from about:debugging, click Inspect on your extension and look for the new tab URL.

Mock browser.storage for Unit Tests

For unit testing without a real browser:

// mock-browser-storage.js
const storage = {
 local: { _data: {} },
 sync: { _data: {} },
};

for (const area of ['local', 'sync']) {
 storage[area].get = async (keys) => {
 if (!keys) return { ...storage[area]._data };
 if (typeof keys === 'string') return { [keys]: storage[area]._data[keys] };
 const result = {};
 for (const key of Object.keys(keys)) {
 result[key] = key in storage[area]._data ? storage[area]._data[key] : keys[key];
 }
 return result;
 };
 storage[area].set = async (items) => {
 Object.assign(storage[area]._data, items);
 };
 storage[area].clear = async () => {
 storage[area]._data = {};
 };
}

global.browser = { storage };

Then in your tests:

require('./mock-browser-storage');
const { loadPreferences } = require('./preferences');

test('loads defaults on first run', async () => {
 const prefs = await loadPreferences();
 expect(prefs.theme).toBe('auto');
 expect(prefs.temperatureUnit).toBe('celsius');
});

web-ext lint

Catch issues before submitting to AMO:

npx web-ext lint --source-dir .

This checks:

  • Manifest validity
  • Deprecated APIs
  • Common mistakes
  • Permission warnings

Run this before every AMO submission.

Testing the Install/First-Run Flow

To test how your extension behaves on first install:

# Launch with a clean profile every time
npx web-ext run --source-dir . --firefox-profile temp-test --profile-create-if-missing

This creates a fresh profile, so storage is always empty — you see exactly what a new user sees.

Summary

Task Tool
Quick load about:debugging temporary add-on
Auto-reload dev web-ext run
Production build web-ext build
Linting web-ext lint
Storage debugging DevTools console
Fresh install test web-ext run --profile-create-if-missing

The web-ext tool is genuinely excellent — it's the official Mozilla CLI and makes extension development feel like normal web dev with hot reload.


Weather & Clock Dashboard — free Firefox new tab extension. Built and tested using all these techniques.