Unit tests are failing after upgrading from Angular 14 to Angular 15

I'm currently in the process of upgrading my Angular application from version 14 to version 15. Following the steps outlined in the Angular Upgrade guide, I have successfully built the application and can run it using ng serve. However, I am facing persistent errors when running unit tests.

The first error I encountered was a TypeScript issue:

Debug Failure. Unexpected node.
Node HeritageClause was unexpected.

at classElementVisitorWorker (../../node_modules/typescript/lib/typescript.js:93950:37)
at ../../node_modules/typescript/lib/typescript.js:93917:92
at saveStateAndInvoke (../../node_modules/typescript/lib/typescript.js:93773:27)
at ../../node_modules/typescript/lib/typescript.js:93917:45
at visitArrayWorker (../../node_modules/typescript/lib/typescript.js:91402:48)
at Object.visitNodes (../../node_modules/typescript/lib/typescript.js:91366:23)
at visitClassDeclaration (../../node_modules/typescript/lib/typescript.js:94199:117)
at visitTypeScript (../../node_modules/typescript/lib/typescript.js:94067:28)
at visitorWorker (../../node_modules/typescript/lib/typescript.js:93829:24)
at sourceElementVisitorWorker (../../node_modules/typescript/lib/typescript.js:93854:28)

To address this issue, I made changes to update Jest, Webpack, and tslib, which resolved the Node HeritageClause failure. However, another error surfaced in the form of a ReferenceError stating that Window is not defined:

FAIL   user-management  libs/user-management/src/lib/user-management.module.spec.ts
  ● Test suite failed to run

    ReferenceError: Window is not defined

      20 |
      21 |   constructor(
    > 22 |     @Inject(WINDOW) private readonly window: Window,
         |                                              ^
      23 |     private readonly componentFactoryResolver: ComponentFactoryResolver,
      24 |     private readonly applicationRef: ApplicationRef,
      25 |     private readonly injector

      at Object.<anonymous> (../common-ui/src/lib/window/window-manager.service.ts:22:46)
      at Object.<anonymous> (../common-ui/src/index.ts:3:1)
      at Object.<anonymous> (src/lib/user-management.module.ts:17:1)
      at Object.<anonymous> (src/lib/user-management.module.spec.ts:2:1)

Currently, my environment is running on Node version 18.10.0 and Angular version 15.2.10. The Angular application utilizes various libraries and frameworks, including ngrx, nrwl, RxJS, and Jest.

In my package.json file, you will find dependencies related to Angular, Azure, Microsoft, NGRX, and several other packages essential for my project.

Despite these efforts, I am unsure if the issues with Jest are caused by misconfigured packages or if there is a larger underlying problem at play. Any insights or guidance would be highly appreciated.

Answer №1

It surprises me that this issue didn't come up sooner, considering that Jest runs in NodeJs and not the browser, so defining Window is not straightforward. Your tests probably handled this well previously, but it seems like the upgrade is enforcing stricter typings.

To work around this, you could create a custom WindowType based on the return type of your WINDOW injection token and use that type in your service. Depending on the test environment, the type will be either the Window type or a fallback option:

export const WINDOW = new InjectionToken('Global window object', {
  factory: () => typeof window !== 'undefined' ? window : undefined
});
export type WindowType = typeof WINDOW extends InjectionToken<infer T> ? T : never;

Implement the new WindowType in your service.

constructor(
  @Inject(WINDOW) private readonly window: WindowType,
  /* ... */
)

Alternatively, assigning the type of the defaultView property of Document to window should also function correctly since it exists in NodeJs.

constructor(
  @Inject(WINDOW) private readonly window: Document['defaultView'],
  /* ... */
)

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

Utilizing a React hook to render and map elements in a function

Can the hook return function be assigned to a render map in React? In this example, we have the socialAuthMethodsMap map with the onClick parameter. I tried to assign the signInWithApple function from the useFirebaseAuth hook, but it violates React's ...

Error message: "Angular schematics installation not found on Mac OS"

Having trouble installing the schematics-cli for Angular on my Mac (running Sierra 10.12.6). When I try to run it in the command line, I keep getting "command not found" errors. I've installed it globally using: npm install -g @angular-devkit/schem ...

Prevent automatic suggestions from appearing in Ionic app on Android

Our Ionic v4 (Angular, Cordova) app features form input fields (<ion-input>) like the example below: <ion-input formControlName="firstName" type="text" inputmode="text" autocapitalize="sentences"></ion-input> When running the Android ap ...

405 we're sorry, but the POST method is not allowed on this page. This page does

I'm currently working on a small Form using the kit feature Actions. However, I'm facing an issue when trying to submit the form - I keep receiving a "405 POST method not allowed. No actions exist for this page" error message. My code is quite st ...

Utilize the "toLowerCase" method on an optional property of an interface

I am working on an Angular application for filtering data. I am populating a Mat-Table with information and implementing filters to minimize the number of displayed projects. One issue I am encountering is with the 'Project' interface, specifica ...

Inquiring about how to toggle a button within a mat table

Is there a way to update the button only on the row that I clicked on? In my TypeScript file: arrow = 'fa fa-caret-right fa-lg'; toggleArrow() { if (this.arrow === 'fa fa-caret-right fa-lg') { this.arrow = 'fa fa-sort-desc ...

How can you initialize a JavaScript class that has a member variable of its own class?

I've come across an interesting puzzle. I am creating a class that can dynamically replicate itself to different levels, similar to an expandable menu. The initial definition looks like this: class MyClass { name: string = ''; fields ...

Adjust the range of selection within the Visual Studio Code document

Before running a command in an extension, I need to modify the selection range to include entire lines... const sel = textEditor.selection; const firstLine = textEditor.document.lineAt(sel.start.line); const lastLine = textEditor.document.lineAt(sel.end.l ...

Having trouble dispatching a TypeScript action in a class-based component

I recently switched to using this boilerplate for my react project with TypeScript. I'm facing difficulty in configuring the correct type of actions as it was easier when I was working with JavaScript. Now, being new to TypeScript, I am struggling to ...

Display excerpts of code within an Angular application within the HTML segment

I'm currently developing a tutorial page using Angular where I intend to display code snippets in various programming languages such as 'Java', 'TypeScript', 'C#', and 'Html'. Although there is a snippet called ...

Troubleshooting problem with handling Angular modules

I'm currently working on effectively organizing folders in my Angular application. Specifically, I've set up a /components directory for shared components and a /pages directory for page-specific components. Each directory has its own module but ...

What is the purpose of adding "/dist" to the library import statement?

Currently, I am in the process of developing a react component library using vite as my primary build tool. After successfully compiling the project and deploying it to the npm registry, I encountered an issue when importing it into my client app. Specifi ...

Tips for Implementing Two Conditionals in an Angular Selector

I am working on a multiple input component with selectors that look like this: <app-input type="currency" formControlName="currency"></app-input> <app-input type="date" formControlName="dateOfBirth"&g ...

Incorporating a custom transpiled file format into Typescript imports

I am trying to import a file format .xyz that does not have fixed types for all instances of the format: import { Comment, Article, User } from "./Blog.xyz" However, I keep getting this error message: TS2307: Cannot find module './Blog.xy ...

Angular - Highlight a section of a string variable

Is there a way to apply bold formatting to part of a string assigned to a variable? I attempted the following: boldTxt = 'bold' message = 'this text should be ' + this.boldTxt.toUpperCase().bold() ; However, the HTML output is: thi ...

How can a border be applied to a table created with React components?

I have been utilizing the following react component from https://www.npmjs.com/package/react-sticky-table Is there a method to incorporate a border around this component? const Row = require("react-sticky-table").Row; <Row style={{ border: 3, borderco ...

Angular 4 Error: The function being called is not defined

I'm feeling stuck with my current project. I've come across similar questions asked multiple times in this thread and also here, but none of the solutions seems to fit my specific problem. It seems that the main issue lies in how this is referenc ...

Managing null values in RxJS map function

I'm facing a scenario where my Angular service retrieves values from an HTTP GET request and maps them to an Observable object of a specific type. Sometimes, one of the properties has a string value, while other times it's null, which I want to d ...

Setting up Jest

I'm currently attempting to integrate the Jest Testing framework into my React Native project. Unfortunately, I am encountering an error message: Failed to retrieve mock metadata: /Users/me/Documents/Development/project/node_modules/global/window.js ...

Guide on uploading an image to Azure Blob Storage using v10 SDK

Currently, I am attempting to upload an image to the Blob Storage in Microsoft Azure using SDK V10 within an Angular framework. The code snippet below demonstrates how I establish a connection to the Storage and retrieve the names of all containers: // E ...