Skip to content
On this page

Implmeneted APIs

This file lists all the implemented APIs, their caveots, limitations, and example tests. Example tests are writen with vitest.

Not all APIs are implemented

For all APIs not listed here, you will have to mock the functions behavior yourself, or you can submit a PR to add support 😄


  • All alarms APIs are implemented as in production, except for onAlarm.
  • You have to manually call onAlarm.trigger() for your event listeners to be executed.


  • create, clear, and getAll are fully implemented
  • You have to manually trigger all the events (onClosed, onClicked, onButtonClicked, onShown)

Example Tests

import { describe, it, beforeEach, vi, expect } from 'vitest';
import browser, { Notifications } from 'webextension-polyfill';
import { fakeBrowser } from '@webext-core/fake-browser';

async function ensureNotificationExists(
  id: string,
  notification: Notifications.CreateNotificationOptions,
): Promise<void> {
  const notifications = await browser.notifications.getAll();
  if (!notifications[id]) await browser.notifications.create(id, notification);

describe('ensureNotificationExists', () => {
  const id = 'some-id';
  const notification: Notifications.CreateNotificationOptions = {
    type: 'basic',
    title: 'Some Title',
    message: 'Some message...',

  beforeEach(() => {

  it('should create a notification if it does not exist', async () => {
    const createSpy = vi.spyOn(browser.notifications, 'create');

    await ensureNotificationExists(id, notification);

    expect(createSpy).toBeCalledWith(id, notification);

  it('should not create the notification if it already exists', async () => {
    await fakeBrowser.notifications.create(id, notification);
    const createSpy = vi.spyOn(browser.notifications, 'create');

    await ensureNotificationExists(id, notification);

import { describe, it, beforeEach, vi, expect } from 'vitest';
import browser from 'webextension-polyfill';
import { fakeBrowser } from '@webext-core/fake-browser';

async function setupNotificationShownReports(
  reportEvent: (notificationId: string) => void,
): Promise<void> {
  browser.notifications.onShown.addListener(id => reportEvent(id));

describe('setupNotificationShownReports', () => {
  beforeEach(() => {

  it('should properly report an analytics event when a notification is shown', async () => {
    const reportAnalyticsEvent = vi.fn();
    const id = 'notification-id';

    await fakeBrowser.notifications.onShown.trigger(id);



  • All events have been implemented, but all of them other than onMessage must be triggered manually.
  • is a hardcoded string. You can set this to whatever you want, but it is reset to the hardcoded value when calling reset().
  • Unlike in a real production, sendMessage will trigger onMessage listeners setup in the same JS context. This allows you to add a listener when setting up your test, then call sendMessage to trigger it.


  • The local, sync, session, and managed storages are all stored separately in memory.
  • storage.onChanged, storage.{area}.onChanged events are all triggered when updating values.
  • Each storage area can be reset individually.

tabs and windows

  • Fully implemented.
  • All methods trigger corresponding tabs events AND windows events depending on what happened (ie: closing the last tab of a window would trigger both tabs.onRemoved and windows.onRemoved).


  • The two functions, getFrame and getAllFrames are not implemented. You will have to mock their return values yourself.
  • All the event listeners are implemented, but none are triggered automatically. They can be triggered manually by calling browser.webNavigation.{event}.trigger(...)

Released under the MIT License.