Encountered a WebGL context creation error when running TypeScript tests with Jest

When attempting to initialize WebGLRenderer in one of my Jest test cases, I encounter the following error:

 Error creating WebGL context.                                                                                                                
                                                                                                                                                 
       9 |                                                                                                                                       
      10 |   it('should set the main renderer', () => {                                                                                          
    > 11 |     const webglRenderer: WebGLRenderer = new WebGLRenderer({
         |                                          ^
      12 |       antialias: true,
      13 |       alpha: true,
      14 |       powerPreference: 'high-performance',

      at new WebGLRenderer (../../node_modules/three/build/three.js:19318:13)
      at Object.<anonymous> (src/tests/managers/three-manager/renderer-manager.test.ts:11:42)

Although I'm testing TypeScript and not encountering any compile-time errors.

Full stack trace:

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
        at module.exports (C:\..\Desktop\phoenix\node_modules\jsdom\lib\jsdom\browser\not-implemented.js:9:17)
        at HTMLCanvasElementImpl.getContext (C:\..Desktop\phoenix\node_modules\jsdom\lib\jsdom\living\nodes\HTMLCanvasElement-impl.js:42:5)
        at HTMLCanvasElement.getContext (C:\..\Desktop\phoenix\node_modules\jsdom\lib\jsdom\living\generated\HTMLCanvasElement.js:131:58)
        at getContext (C:\..Desktop\phoenix\node_modules\three\build\three.js:19279:29)
        at new WebGLRenderer (C:\..Desktop\phoenix\node_modules\three\build\three.js:19315:10)
        at Object.<anonymous> (C:\..\Desktop\phoenix\packages\phoenix-event-display\src\tests\managers\three-manager\renderer-manager.test.ts:11:42)
        at Promise.then.completed (C:\..Desktop\phoenix\node_modules\jest-circus\build\utils.js:391:28)
        at new Promise (<anonymous>)
        at callAsyncCircusFn (C:\..Desktop\phoenix\node_modules\jest-circus\build\utils.js:316:10)
        at _callCircusTest (C:\..\Desktop\phoenix\node_modules\jest-circus\build\run.js:218:40) undefined

      at VirtualConsole.<anonymous> (../../node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
      at module.exports (../../node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
      at HTMLCanvasElementImpl.getContext (../../node_modules/jsdom/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js:42:5)
      at HTMLCanvasElement.getContext (../../node_modules/jsdom/lib/jsdom/living/generated/HTMLCanvasElement.js:131:58)
      at getContext (../../node_modules/three/build/three.js:19279:29)
      at new WebGLRenderer (../../node_modules/three/build/three.js:19315:10)

Chrome version: 102.0.5005.115 (Official Build) (64-bit) (cohort: Stable) OS: Windows 11 Version 21H2 (Build 22000.739)
JavaScript: V8 10.2.154.8
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/102.0.0.0 Safari/537.36

chrome://gpu

WebGL: Hardware accelerated
WebGL2: Hardware accelerated
WebGPU: Hardware accelerated

Thank you in advance! :))

Answer №1

To effectively test the functionality of WebGLRenderer with Jest, one approach is to create a utility function:

import createContext from 'gl';

import * as THREE from 'three';
import { createCanvas } from 'canvas';

export default function initializeRenderer(
  options?: THREE.WebGLRendererParameters
) {
  const window = {
    innerWidth: 800,
    innerHeight: 600,
  };
  const context = createContext(1, 1);
  const canvas: HTMLCanvasElement = createCanvas(
    window.innerWidth,
    window.innerHeight
  ) as any;

  // Mocking function to prevent errors within THREE.WebGlRenderer():
  canvas.addEventListener = function () {};

  return new THREE.WebGLRenderer({ context, canvas, ...options });
}

Hopefully, this function proves useful. I drew inspiration from a similar library: https://github.com/Bartozzz/jest-three

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

Tips for preventing CORS and SSL issues when using localhost

Attempting to log in with Google on my Svelte app involves sending a request to an Express server. However, I encounter different errors on different browsers. On Firefox, I receive a Cross-Origin Request Blocked: The Same Origin Policy disallows reading t ...

Understanding the concept of inconsistent return points in Typescript: What implications does it carry?

I am currently working on converting a NodeJs JavaScript code to TypeScript. The code snippet below shows how I save uploaded files using JavaScript and now I'm encountering an error when trying to do the same in TypeScript. The error message says "Fu ...

Next JS now includes the option to add the async attribute when generating a list of script files

We are currently working on a nextJs application and are looking to add asynchronous functionality to all existing script tags. Despite numerous attempts, we haven't been successful in achieving this. Can anyone provide some guidance or assistance? &l ...

Error: You can't use the 'await' keyword in this context

I encountered a strange issue while using a CLI that reads the capacitor.config.ts file. Every time the CLI reads the file, it throws a "ReferenceError: await is not defined" error. Interestingly, I faced a similar error with Vite in the past but cannot ...

Are ngFormModel characteristics subject to change?

I've been facing challenges while working with ngFormModel and dynamic properties from classes. Despite my efforts, I'm unable to update the ngFormModel when changing variables to reflect new values. You can see an example of this issue in the fo ...

Eliminating the nested API call within a loop

After making an API call to retrieve a set of data such as a list of users, I noticed that I am implementing a for loop and within it, I am making another API call to obtain each user's profile details based on their ID. I understand that this approac ...

React Native: Picker value remains static

I'm encountering an issue where the value of the picker does not change when I select a new value from it. This problem started occurring after I added the onValueChange function. If anyone has any insights or suggestions on how to resolve this, I wou ...

Create an array variable for services in Angular

My goal is to define this user as an array. users = new BehaviorSubject<any>([]); In my component, I am attempting to add the userID to the array. this.Service.users.push(userID); To subscribe to it, I use the following code: this.Service.users.su ...

Encountered an issue while trying to assign a value to the 'value' property on an 'HTMLInputElement' within a reactive form

When I upload a picture as a data record, the image is sent to a server folder and its name is stored in the database. For this editing form, I retrieve the file name from the server and need to populate <input type="file"> in Angular 6 using reacti ...

Angular form requests can utilize the Spring Security Jwt Token to allow all options methods

Despite checking numerous sources online, I am facing a persistent issue with my Angular application. The problem arises when using HttpClient along with an Angular interceptor to set headers for authentication in my Java Rest API using JWT tokens. The int ...

Exploring the latest upgrades in React 18 with a focus on TypeScript integration

I am currently working on a complex TypeScript project with React and recently made the decision to upgrade to the new version of React 18. After running the following commands: npm install react@18 npm install react-dom@18 npm install @types/react-dom@18 ...

The textgeometry element is not appearing in the three.js scene

I've inserted a boxgeometry into the scene with the intention of adding text to indicate the side of the cube. However, I am encountering difficulties in incorporating textgeometry into the scene. This is my code: const loader = new FontLoader(); loa ...

Hide the FormArray in a Reactive Form if it is not populated or cannot be determined

As a newcomer to Angular 4, I've embarked on my first project and started learning the ropes. I have devised a Reactive Form to showcase a form structure that looks like this: Form (FormGroup) | --> aggLevels (FormArray) | --> ...

Tips for troubleshooting the error message: "The relative import path "$fresh/dev.ts" is not prefaced with / or ./ or ../"

My editor is showing a TypeScript error for a Deno module I am working on. The import path "$fresh/dev.ts" should be prefixed with / or ./ or ../ I have an import_map.json file set up with the following content. { "imports": { "$fre ...

Best practices for receiving messages from SQS in Node.js

I am exploring how to implement SQS in a similar manner as RabbitMQ or Kafka, where we usually set up a listener. However, after going through their documentation, I couldn't find any instructions on how to set up a listener for SQS: Currently, I am ...

Troubleshooting the issue of process.nextTick not being recognized in Calgolia places.js

After successfully implementing Algolia's places.js in my Angular 7 project using NPM, I encountered an issue. I have integrated a form where one of the fields should be an input. <form [formGroup]="myForm"> <pre style="color: white; b ...

The upcoming developer manages to execute the program successfully, however, it continues to load indefinitely

Executing the command yarn dev consistently runs successfully in my VS Code terminal: $ yarn dev yarn run v1.22.19 warning ..\..\..\..\package.json: No license field $ next dev ready - started server on 0.0.0.0:3000, url: http://localho ...

Accessing the ViewModel property of a parent component from the ViewModel of its child in Aurelia

Having a scenario with two distinct components: <parent-component type="permanent"> <div child-component></div> </parent-component> class ParentComponentCustomElement { @bindable public type: string = "permanent"; } clas ...

Dynamically manipulate menu items in material-ui and react by adding, removing, editing, or toggling their state

I have scoured every corner of the internet in search of an answer to this dilemma. Imagine a scenario where there is a menu located at the top right of a navigation bar, initially showcasing TWO options (1. Login. 2. Register). When a user clicks on eithe ...

TypeScript and Angular: Error Encountered when Trying to Combine Two Arrays

I'm attempting to combine two arrays of the same type that are nested within a "parent" array. The end goal is to flatten the structure. Below is the code I have been using: ngOnInit() { this.Logs.getAllLogs() .subscribe(logs => { ...