Playing around with Jest (Typescript - Simulate chrome namespace)

I've developed a chrome extension using React. I've started adding some tests, but I'm struggling with a few of them.

The issue lies in testing my <App/> component, as I keep encountering errors no matter what approach I take.

Here's what I've tried:

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import App from "../../App";
import { BMEUtils } from "../../app/helpers/utils/BMEUtils";
import { FormContainerID } from "../../app/dom-elements/_components/forms/AbsoluteContainer";
import renderer from 'react-test-renderer';


describe("tests ", () => {

  it("test App", () => {
    const component = renderer.create(
      <App />,
    );
    const b = document.getElementById(FormContainerID)
    const a =  document.getElementById("login-btn");
    
    let tree = component.toJSON();
    expect(tree).toMatchSnapshot();
    
    expect(a).not.toBeNull();
    expect(b).not.toBeNull();
   
  });
});

However, I keep encountering an error during the test:

ReferenceError: chrome is not defined

This error occurs because one of the components references the chrome namespace to add a listener (

chrome.runtime.onMessage.addListener
).

I've attempted the following solutions:

global.chrome = jest.fn() as any;
jest.mock('chrome');
import chrome from "sinon-chrome";
 beforeAll(function () {
    global.chrome = chrome as any;
 });
const chrome = require('sinon-chrome/extensions');
beforeAll(function () {
    global.chrome = chrome ;
});
var globalRef:any =global;
globalRef.chrome = jest.fn().mockImplementation();
const component = renderer.create(
   <App />,
);
import { mount } from 'enzyme';
const wrapper = mount(
   <App/>
);
const p = wrapper.find('#login-btn');

Unfortunately, none of these solutions have worked for me.

This remains my main issue.

Another problem I'm facing, which may be related to the previous one, is figuring out how to mock the implementation of certain functions that are executed internally and are not part of any modules.

For instance:

// Test as Base64 Image
// Utils is a namespace
test('base64Image', () => {
  ...
  const file = ...;
  let base64Image = Utils.asBase64Image(file);
  expect(base64Image).not.toEqual("");
  ...
});
function asBase64Image(file:File) {
  ...
  canvas.getContext("2d");
  img.onload
  ...
}

To work around this, I've resorted to using Modules to replace these functions and mock them, such as replacing img.onload with module.loadImage(img).then(...). However, I'm eager to learn the correct way of doing this if possible.

Nevertheless, my current pressing issue is the inability to successfully test my <App/> component.

Answer №1

If you're still facing this issue in 2023, I managed to resolve it with the steps below:


import { pathsToModuleNameMapper, type JestConfigWithTsJest } from 'ts-jest';
const chrome = require('sinon-chrome/extensions');

const jestConfiguration: JestConfigWithTsJest = {
  extensionsToTreatAsEsm: ['.ts'],
  verbose: true,
  preset: 'ts-jest/presets/default-esm',
  testEnvironment: 'node',
  transform: {
    '^.+\\.(ts)?$': ['ts-jest', { useESM: true }],
  },
  testPathIgnorePatterns: ['./dist'],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths /*, { prefix: '<rootDir>/' } */),
  // setupFilesAfterEnv: ['./jest.setup.js'],
  globals: {
    chrome,
  },
};

export default jestConfiguration;

Credits to for the helpful suggestion!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

You are able to use a null type as an index in angular.ts(2538) error message occurred

onClick() { let obj = { fName: "ali", LName: "sarabi", age: "19", } let fieldName = prompt("field"); alert(obj[fieldName]); } I encountered an issue with the code above where alert(obj[fieldName] ...

How should we correctly import jquery.inputmask?

Struggling to import jquery.inputmask using webpack and TypeScript? Head over to this discussion at Issue #1115 : Here's how I configured things with jqlite: To import in your app, use the following code: import InputMask from 'inputmask&apos ...

Issue with npm during installation of REACT - not functioning as expected

After executing all the necessary commands on the command line, including globally installing npm with npm install -g create-react-app, as well as running npx create-react-app <myprojectname> and clearing the npm cache, I consistently encountered an ...

Error: Disappearing textarea textContent in HTML/TS occurs when creating a new textarea or clicking a button

I've encountered an issue with my HTML page that consists of several textareas. I have a function in place to dynamically add additional textareas using document.getElementById("textAreas").innerHTML += '<textarea class="textArea"></text ...

Angular Material - Adding tooltips to Mat-table rows

I am currently working with Angular Material Mat-Table and I have a requirement to show a tooltip when hovering over any row. Essentially, I need to filter data from mGridDataSource based on the row id. Since I am new to Angular, I would greatly appreciate ...

I am deciding between using CommonJS or ES module for my sub packages in a Yarn workspace for my Next.js project. Which one

Currently working on a Next.js monorepo project using TypeScript and yarn workspace. Within the yarn workspace, there are two packages: /web and /api. The /web package is a next.js project, while /api serves as a shared subpackage utilized by /web. /my-pr ...

When working with Typescript and Vue.js, it's important to ensure that properties are initialized before

Check out the following code snippet: export default class PrimitiveLink extends Vue { style = { // Reset display: 'inline-block', textDecoration: 'none', outline: 'none', // Theme ...this.themeStyle ...

The speed of the OpenLayers web application is significantly hindered when accessed from a mobile device using Android

Although it may seem like a common question that should be closed, I have reached a roadblock and cannot find a solution. I hope to provide enough details to make this question suitable for SO. I am currently working on an OpenLayers web application that ...

Why does React redirect me to the main page after refreshing the page, even though the user is authenticated in a private route?

In the process of developing a private route component that restricts unauthenticated users and redirects them to the homepage, we encountered an issue upon page refresh. The problem arises when the current user variable momentarily becomes null after a ...

What steps can be taken to fix the error message about 'isServer' when using npm?

I encountered this issue after running npm install. Current versions are npm - 8.0.0 and nodejs - 16.11.0. npm ERR! Cannot read properties of undefined (reading 'isServer') ...

Issue with the declaration of custom types in Typescript

I've created a type declaration for r-dom as shown below: /// <reference types="react" /> declare module 'r-dom' { interface IRDOMFacade extends React.ReactDOM { (component: React.Component<any, any>, properties?: ...

Simulating an ES6 module that returns a factory function for moment.js

Disclaimer: I'm a beginner with Jest so please bear with me. I'm currently working on testing a Vue2.js filter named DateFilter using Jest. This filter simply formats a date that is passed to it. DateFilter.js import Vue from 'vue'; ...

Understanding the operational aspects of Typescript's target and lib settings

When the tsconfig.json file is configured like this: "target": "es5", "lib": [ "es6", "dom", "es2017" ] It appears that es2017 features are not being converted to es5. For example, code like the following will fail in IE11: var foo = [1, 2, 3].includes( ...

What is preventing me from installing gulp dependencies using npm?

My computer recently crashed and now none of the install packages seem to be working properly. When I try to install a package, this is what shows up in the command line: npm install --save-dev gulp-autoprefixer npm ERR! Windows_NT 6.3.9600 npm ERR! argv ...

SVG Error: You might require a suitable loader to manage this file format, as there are currently no configured loaders to handle it

Encountered an issue with my application - everything was functioning properly until I executed npm run audit fix force. Now, I am receiving the following error message related to an SVG file. The error indicates that there may be a need for a loader to h ...

What is the process of converting an Array that is nested within an Object?

I am facing compile errors while attempting to convert an Object containing an Array of Objects. Here is the initial structure: export interface CourseRaw { metaInfo: MetaInfoRaw; gameCode: number; gameText: string; images?: ImageRaw[]; // Having ...

Issue with Angular 2 Observable testing: Trying to use setInterval in an async zone test is not allowed

I am currently in the process of testing a component that relies on a service for making asynchronous HTTP calls. The service returns an Observable, which is then subscribed to by the component. Snippet from the service code: getRecentMachineTemperatures ...

Leverage TypeScript to access custom component properties and URL parameters from react-router-dom

In my react-router-dom setup, I have a route structured like this: <Route path="/result/:result" component={ResultsView} audio={audio} speechRecognition={speechRecognition} /> Furthermore, I have a component with specified props as follows ...

Typescript is failing to return nested types when attempting to return a nested object

My goal is for my function to return a nested type of Content, but it's not working even though the type that should be returned is known. Let's take a look at an example: type Content = { some: { extra: string; prop: number; ...

It is feasible to completely override a class in TypeScript

I have a subclass defined as follows: customException.ts /** * Custom Error class. * * @class Error * @extends {Error} */ class Error { /** * @type {string} * @memberof Error */ message: string; /** * @type {boolean} * @memberof ...