{"id":13367,"library":"jest-chrome","title":"Jest Chrome API Mock","description":"jest-chrome provides a comprehensive mock of the Chrome Extension API, designed specifically for testing Chrome extensions with Jest. It aims for a complete and accurate representation of the Chrome API, with built-in TypeScript support derived directly from the `@types/chrome` package, ensuring type safety and intellisense. The package is actively maintained, with the current stable version being 0.8.0. Releases occur periodically to address Jest compatibility, improve API coverage, and fix build-related issues, though there isn't a strict time-based cadence. Its primary differentiator is the completeness of the mock and its strong adherence to the official Chrome API types, enabling robust testing of extension logic without needing a real browser environment. This allows for faster, more reliable unit and integration tests for Chrome extensions.","status":"active","version":"0.8.0","language":"javascript","source_language":"en","source_url":"https://github.com/extend-chrome/jest-chrome","tags":["javascript","api","chrome","chromium","extension","jest","mock","test","typescript"],"install":[{"cmd":"npm install jest-chrome","lang":"bash","label":"npm"},{"cmd":"yarn add jest-chrome","lang":"bash","label":"yarn"},{"cmd":"pnpm add jest-chrome","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Runtime peer dependency for Jest testing framework.","package":"jest","optional":false}],"imports":[{"note":"The `chrome` object is a named export, not a default export. Used for Intellisense and linting in test files.","wrong":"import chrome from 'jest-chrome'","symbol":"chrome","correct":"import { chrome } from 'jest-chrome'"},{"note":"This CommonJS pattern is recommended for Jest setup files (`setupFilesAfterEnv`) to make the mocked `chrome` object globally available to all tests.","wrong":"import { chrome } from 'jest-chrome'; Object.assign(global, { chrome });","symbol":"global chrome assignment","correct":"Object.assign(global, require('jest-chrome'))"},{"note":"While types are automatically inferred with `jest-chrome`, explicit type imports for specific mocked browser features may be useful for stricter type checking, often utilizing `type` keyword for tree-shaking benefits.","wrong":"import { Browser } from 'jest-chrome'","symbol":"types","correct":"import type { Browser } from 'jest-chrome'"}],"quickstart":{"code":"import { chrome } from 'jest-chrome';\n\ndescribe('chrome.runtime.sendMessage', () => {\n  test('should handle messages and callbacks', () => {\n    const message = { greeting: 'hello?' };\n    const response = { greeting: 'here I am' };\n    const callbackSpy = jest.fn();\n\n    // Mock the sendMessage function to call the callback with a response\n    chrome.runtime.sendMessage.mockImplementation(\n      (msg, callback) => {\n        expect(msg).toEqual(message);\n        callback(response);\n      },\n    );\n\n    // Call the function under test\n    chrome.runtime.sendMessage(message, callbackSpy);\n\n    // Assertions\n    expect(chrome.runtime.sendMessage).toBeCalledWith(\n      message,\n      callbackSpy,\n    );\n    expect(callbackSpy).toBeCalledWith(response);\n  });\n\n  test('should handle lastError in callback', () => {\n    const message = { greeting: 'error test' };\n    const callbackSpy = jest.fn();\n\n    chrome.runtime.sendMessage.mockImplementation(\n      (msg, callback) => {\n        // Simulate an error by setting lastError before calling the callback\n        Object.defineProperty(chrome.runtime, 'lastError', {\n          get: () => ({ message: 'Something went wrong' }),\n          configurable: true,\n        });\n        callback(undefined);\n        // Clear lastError after the callback, as Chrome does\n        delete chrome.runtime.lastError;\n      },\n    );\n\n    chrome.runtime.sendMessage(message, callbackSpy);\n\n    expect(callbackSpy).toBeCalledWith(undefined);\n    // You might also check if your extension's error handling was triggered\n  });\n});\n","lang":"typescript","description":"This example demonstrates how to mock asynchronous Chrome API functions, specifically `chrome.runtime.sendMessage`, including handling callbacks and simulating `chrome.runtime.lastError` for robust error testing."},"warnings":[{"fix":"Update all `import` and `require` statements in your project from `jest-chrome` to `@extend-chrome/jest-chrome`.","message":"The package moved to a new npm organization. The import path changed from `jest-chrome` to `@extend-chrome/jest-chrome`.","severity":"breaking","affected_versions":">=0.6.0"},{"fix":"Review any custom type definitions or test helpers that interact directly with Jest's mock types and update them to use `jest.MockedFunction` if necessary.","message":"The internal implementation for mock functions changed from `jest.Mock` to `jest.MockedFunction`. While this might not directly break runtime code, it can affect type definitions or custom test utilities relying on the old type.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Add a `jest.setup.js` file (or similar) to your Jest configuration, and within it, use `Object.assign(global, require('jest-chrome'))`.","message":"The `chrome` object must be assigned to the global scope in a Jest setup file (`setupFilesAfterEnv`) for it to be available in your test files.","severity":"gotcha","affected_versions":">=0.5.0"},{"fix":"Always provide a `mockImplementation` for asynchronous Chrome API functions (e.g., `chrome.runtime.sendMessage.mockImplementation(...)`) to define their behavior during testing.","message":"Chrome API functions that use callbacks for asynchronous operations have no default mock implementation. You must explicitly `mockImplementation` for each function you call in your tests.","severity":"gotcha","affected_versions":">=0.5.0"},{"fix":"Avoid using version 0.5.2. Upgrade to version 0.5.3 or later to ensure a stable build.","message":"Version 0.5.2 was deprecated on NPM due to a broken build caused by stricter TypeScript plugin versions.","severity":"deprecated","affected_versions":"0.5.2"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure your `jest.config.js` includes `setupFilesAfterEnv: ['./jest.setup.js']` and `jest.setup.js` contains `Object.assign(global, require('jest-chrome'))`.","cause":"The mocked `chrome` object has not been made globally available to your tests.","error":"ReferenceError: chrome is not defined"},{"fix":"Verify that `jest-chrome` is correctly loaded in your setup file, and that you are trying to mock a valid Chrome API method that `jest-chrome` intercepts.","cause":"The `chrome` object or its methods are not recognized as Jest mock functions.","error":"TypeError: (some chrome method).mockImplementation is not a function"},{"fix":"Review your `mockImplementation` for asynchronous functions to ensure the callback argument is correctly invoked (e.g., `callback(response)` or `Promise.resolve(response)` if it's a promise-based API).","cause":"An asynchronous Chrome API function mock did not call its callback, leading to a Jest timeout.","error":"Error: expect(jest.fn()).toBeCalledWith(...). Call stack: ... Async callback was not invoked within the 5000ms timeout specified by jest.DEFAULT_TIMEOUT_INTERVAL."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}