Jest is raising a TypeError: Unable to access attributes of an object that is undefined (referencing 'getVideoTracks')

When running my unit tests with Jest, I encountered an error:

TypeError: Cannot read properties of undefined (reading 'getVideoTracks')

Does anyone have any suggestions on how to properly test the following line using Jest?

[videoTrack] = (await navigator.mediaDevices.getUserMedia({video: true})).getVideoTracks();

This is a snippet from my unit test file:

import { Track } from './Track';
import { } from '../index';

const mockMediaDevices = {
    getUserMedia: jest.fn()
};

Object.defineProperty(window.navigator, 'mediaDevices', {
    writable: true,
    value: mockMediaDevices,
});

Object.defineProperty(navigator.mediaDevices.getUserMedia, 'getVideoTracks', {
    writable: true,
    value: jest.fn(),
});

describe('Track', () => {
    describe('applyConstraints()', () => {
        let track: Track;
        let videoTrack: MediaStreamTrack;

        beforeEach(async () => {
            [videoTrack] = (await navigator.mediaDevices.getUserMedia({ video: true })).getVideoTracks();
            track = new Track(videoTrack as MediaStreamTrack);
        });

        it('should have applyConstraints method', () => {
            expect(typeof track.applyConstraints).toEqual('function');
        });
    });
});

Here is the detailed error message:

TypeError: Cannot read properties of undefined (reading 'getVideoTracks')

      67 |
      68 |     beforeEach(async () => {
    > 69 |       [videoTrack] = (await navigator.mediaDevices.getUserMedia({video: true})).getVideoTracks();
         |                                                                                 ^
      70 |       track = new Track(videoTrack as MediaStreamTrack);
      71 |     });
      72 |

      at Object.<anonymous> (Media/Track/Track.test.ts:69:81)

I also attempted the following code:

const mockMediaDevices = {
  getUserMedia: jest.fn().mockReturnValue({ getVideoTracks: jest.fn() })
};
Object.defineProperty(navigator, 'mediaDevices', {
  writable: true,
  value: mockMediaDevices,
});

However, this resulted in another error:

TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

      73 |
      74 |     beforeEach(async () => {
    > 75 |       [videoTrack] = (await navigator.mediaDevices.getUserMedia({video: true})).getVideoTracks();

Answer №1

To imitate mediaDevices, try this approach:

Object.defineProperty(global.navigator, 'mediaDevices', {
            configurable: true,
            writable: true,
            value: {
                getUserMedia: jest.fn().mockResolvedValueOnce(mockMediaStreamObject),
            },
        });

For the getUserMedia function, you can create a mocked version with a return value to customize the getVideoTracks method according to your needs.

export const mockMediaStreamObject: MediaStream = {
    getVideoTracks(): MediaStreamTrack[] {
        return [];
    },
...
}

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

The AddClass function fails to function properly after an ajax form is submitted

I am facing a challenge in setting up validation for my ajax form. My goal is to have a red border appear around the input field if it is submitted empty. Unfortunately, when I try to use addClass(), it does not seem to have any effect. The alert message ...

The failure of the Selenium script can be attributed to the presence of the AJAX

Struggling to automate an application with an AJAX loader causing issues? Getting the dreaded error message about element not being clickable when the loader is active? Frustrating, right? But fear not! I have devised a clever solution in the form of a wr ...

Revitalizing HTML and Google Maps with AJAX, PHP, and JQuery

Context: I am currently working on a project that involves integrating a Simple Google Map with an HTML form right below it. The form collects user input and upon submission, sends the data via AJAX to a PHP script for processing API calls and generating i ...

Populate a select list in real time with dynamically generated options

I'm facing a challenge at the moment; I am using JavaScript to dynamically generate select boxes, however, I require Ajax to populate them with options. At the moment, my code is returning undefined and I am unsure of how to proceed. While my PHP succ ...

Glow Texture Hiding Edges in THREE.js SpriteMaterial

While adding a SpriteMaterial glow texture to certain THREE.js nodes, I've encountered some rendering issues, particularly with how it appears over edges. Interestingly, at some angles, everything looks fine, but from other perspectives, the edges see ...

Modifying one instance of an object will automatically alter the other instance as well

Currently, I am working on developing a simple table in Angular where specific functions are applied to modify the table based on different conditions. These include sorting the data upon pressing the sort button and adding salutations based on the gender. ...

Conceal certain digits of a credit card number in a masked format for security purposes

Is there a reliable method to mask Credit Card numbers in password format within a text field? **** **** **** 1234 If you are aware of a definitive solution, please share it with us. ...

AngularJS directive $destroy is a useful tool for managing the

My angular application has been configured with the use of ng-view. Within one specific view, there is a dynamically loaded component alongside the view itself. This component acts as a directive that compiles its contents to allow for further interaction ...

Code snippet for adding a div element with an embedded image using JavaScript

I am attempting to create a function that generates three div elements, each containing an image, and then appends them to the body using a for loop. As a beginner in JavaScript, I am struggling with this task. Can anyone please provide guidance on what ...

What is the best way to display a date picker from a different page as a pop-up when a button is clicked on the current

Chapter One <button class="btn btn-outline-primary btn-sm btn-block " >Place order</button> Chapter Two <button class="simplepicker-btn" >Show Date Picker</button> > <script> > let simplepicker = new SimpleP ...

Unexpected behavior in Next.js when using Auth0: pageProps are empty when wrapped with withPageAuthRequired HOC

Explaining the Issue The problem arises when using withPageAuthRequired with getServerSideProps, as the pageProps object is empty. Despite following common practices, the pageProps parameter remains undefined. Expected Outcome Upon calling getServerSideP ...

JavaScript Tab Fade Effect

I have a tab system that utilizes JavaScript to switch tabs. I am trying to implement a fade in and out effect when switching tabs. The current JavaScript simply adds or removes the clicked tab selected by the user. I have managed to partially achieve the ...

The absence of a 'body' argument in the send() json() method within the Next.js API, coupled with TypeScript, raises an important argument

Currently, I have set up an API route within Next.js. Within the 'api' directory, my 'file.tsx' consists of the following code: import type { NextApiRequest, NextApiResponse } from "next"; const someFunction = (req: NextApiReq ...

Perform an Ajax request to a C# Controller Function

In my javascript file named "data handling.js" within a folder labeled "JS", you'll find the following piece of code: document.getElementById('submit-new-project').addEventListener("click", function () { var ProjectName = document.getEl ...

I am attempting to change a "+" symbol to a "-" symbol using a Bootstrap toggle feature

Click on the text to reveal more information that drops down below. I am using Bootstrap icons and attempting to show a "+" icon when the toggle is collapsed, and a "-" icon when it's open. I've been trying to use display properties, but haven&ap ...

Avoiding redundancy by establishing the loading state in a redux reducer

Let's dive into a concrete example to better illustrate my point. In the webapp I'm working on, users can apply for jobs using a job reducer that handles various actions such as creating_job, created_job, fetching_job, fetched_job, fecthing_jobs, ...

Exploring Symfony2 controller integration with Javascript arguments

I am currently working on a project with Symfony2 and I have a question regarding receiving arguments from a template in a controller. My goal is to take the value of the argument and store it in the database. The argument's value will be generated by ...

Triggering an event from a component to its parent module resulting in an exception situation

Here is my app.component.ts code: import { Component, Input, OnInit, OnChanges, SimpleChanges} from '@angular/core'; import {Counter } from './counter' @Component({ selector: 'my-app', template: ` <custom-counter [ ...

Encountered Angular SSR Serve Error: NullInjectorError - StaticInjectorError in AppServerModule with the following reference:

While working on building an application with Angular's SSR and serving it, I encountered a specific error. All services and components have been properly injected. Error: ERROR Error [NullInjectorError]: StaticInjectorError(AppServerModule)[REQUEST] ...

What could be the reason behind the malfunction of this jQuery post request?

I am currently studying AJAX with jQuery, but I am facing an issue with my registration system. The following code does not seem to work: $('#submitr').click(function () { var username = $('#usernamefieldr').val(); var password ...