Cypress - Premature evaluation of assertion due to potential error in promise chaining

I am currently working on a Cypress/TypeScript test case that involves editing the selected value of a dropdown.

While chaining promises and utilizing Page Objects, I have encountered two main issues:

  1. The assertion meant to be evaluated at the end is executed prematurely.
  2. This premature execution leads to a failed assertion, yet the test still passes inexplicably.

screenshot: cl.ly/e4cb6837377c

spec

    it.only('C180: Change Tracking type: Important tasks => Time measurement', function () {
        const timeMeasurement = 'Time measurement'
        billing.currentTrackingType().then((trackingType) => {
            if(trackingType == timeMeasurement)
                this.skip()
            billing.changeTrackingType(1).then(() => {
                billing.currentTrackingType().then(($trackingType) => {
                    expect($trackingType).to.contain(timeMeasurement)
                })
            })
        })
    })

Page object:

    currentTrackingType() {
        return new Promise((resolve, reject) => {
            const timer = Cypress.$(this.elements.timer)
            resolve(timer.length? 'Time measurement':'Important tasks')
        })
    }

    changeTrackingType(index: any){
        const settingsChanged = 'Timesheet settings has been changed'
        return new Promise((resolve, reject) => {
            cy.get(this.elements.trackingType).select(index.toString())
            cy.get(this.elements.save).eq(3).click()
                resolve()
        })
    }
}

Answer №1

When using Cypress, remember that commands run asynchronously, queued and executed in order.

For example:

        return new Promise((resolve, reject) => {
            cy.get(this.elements.trackingType).select(index.toString())
            cy.get(this.elements.save).eq(3).click()
                resolve()
        })

In this case, the promise will resolve right away as

cy.get().select().get().eq().click()
is enqueued synchronously followed by an immediate call to resolve().

If you insist on using the Promise pattern, consider structuring it like so:

        return new Promise((resolve, reject) => {
            cy.get(this.elements.trackingType).select(index.toString())
            cy.get(this.elements.save).eq(3).click()
            .then(resolve)
        })

resolve will be triggered once the click operation completes.


I would suggest revising your code to align with how Cypress operates rather than attempting to "promisify" it.

Test:

    it.only('C180: Change Tracking type: Important tasks => Time measurement', function () {
        const timeMeasurement = 'Time measurement'
        const trackingType = billing.currentTrackingType()
        if(trackingType == timeMeasurement)
            this.skip()
        billing.changeTrackingType(1)
        const newTrackingType = billing.currentTrackingType()
        expect(newTrackingType).to.contain(timeMeasurement)
    })

"Page object":

    currentTrackingType() {
        // Note that this may not work as expected - consider using
        // cy.get(this.elements.timer).then($el => { ... }) instead
        const timer = Cypress.$(this.elements.timer)
        return timer.length ? 'Time measurement':'Important tasks'
    }

    changeTrackingType(index: any){
        const settingsChanged = 'Timesheet settings has been changed'
        cy.get(this.elements.trackingType).select(index.toString())
        cy.get(this.elements.save).eq(3).click()
    }

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

An angular component that is functioning properly when connected to a live server, however, it is experiencing issues when trying to run `

I tried integrating versitka into my Angular component by placing the version HTML file and all necessary assets in the appropriate directories. However, when I run ng serve, only the HTML file seems to be working, while the CSS and images fail to load. I ...

Tips for organizing an NPM package containing essential tools

Currently facing the challenge of creating an NPM package to streamline common functionality across multiple frontend projects in our organization. However, I am uncertain about the correct approach. Our projects are built using Typescript, and it seems th ...

What is the reason for a type narrowing check on a class property failing when it is assigned to an aliased variable?

Is there a way to restrict the type of property of a class in an aliased conditional expression? Short: I am trying to perform a type narrowing check within a class method, like this._end === null && this._head === null, but I need to assign the r ...

Exporting External JavaScript Variables in Angular 2 Using Typescript

In my Configuration JS file, I have defined some configuration variables. For example: var config = {url:"xyz.com"}; I need to access these configuration parameters throughout my application. I attempted to export the config variables like this: export ...

Setting up Serverless Lambda for a Graphql API with Typescript: Step-by-step guide

Recently, I ventured into the world of AWS and attempted to deploy a GraphQL API written in NodeJS on an AWS Lambda using Serverless. Despite following multiple tutorials that were similar to my project, I encountered difficulties with the handler function ...

Execution issue with Typescript function

In my Nativescript project, I have the following TypeScript file: import { Observable } from 'tns-core-modules/data/observable'; import { isIOS } from "tns-core-modules/platform"; import { Color } from "tns-core-modules/color"; import { request, ...

Error encountered in Typescript parsing when setting EXTEND_ESLINT to true in create-react-app

Demo on GitHub - Simplified Version We are currently in the process of migrating our create-react-app project from Flow to Typescript incrementally. As part of this migration, I had to disable some ESLint rules that were causing issues. To customize ESLin ...

Create a new project using Firebase Functions along with a Node.js backend and a React.js frontend

In the process of developing my application, I have chosen to utilize node.js, express.js, and Firebase with firebase functions, all coded in TypeScript. For the client side framework, I am interested in incorporating react.js. Currently, I have set up nod ...

Is there a way to verify if a user taps outside a component in react-native?

I have implemented a custom select feature, but I am facing an issue with closing it when clicking outside the select or options. The "button" is essentially a TouchableOpacity, and upon clicking on it, the list of options appears. Currently, I can only cl ...

Is it a common issue that sound.stop() doesn't seem to function properly, while sound.play() operates successfully within Howler

I am having trouble utilizing Howler.js in Reactjs with typescript. While I can successfully play the sound, pausing or stopping it seems to be an issue. Below is the code snippet: This component takes all the audio details as props. I used console.log() ...

What is the best way to ensure that all components can access and utilize the same instance of API

Is there a way to retrieve data from the database using an API when the application starts and then release it once the app is closed, ensuring that the same data instance is available for each component? ...

Setting up VSCode to run various tasks

My TypeScript project in Visual Studio Code has a specific task outlined as follows: { "version": "0.1.0", // The command is tsc. "command": "tsc", // Show the output window only if unrecognized errors occur. "showOutput": "silent", // Und ...

Determine if an object contains a specific key in Typescript and access the value associated with that

Here is a snippet of my code: let show = { createTag: false, updateFeature: false, createFeatureGroup: false, deleteFeature: false, deleteCycle: false, }; I am retrieving a value from the querystring that I want to compare against the ...

How can I set up unique values for a variable or constant in Angular 2 based on different environments?

Currently, I am working on a project that combines Angular 2/Ionic 2 with JEE 7. In this particular scenario: I have created an httpClient layer to handle all backend calls, and within this layer, there is a const variable called REST_BASE_PATH. During de ...

When using TypeScript with Jest or Mocha, an issue arises where the testing frameworks are unable to read JavaScript dependencies properly, resulting in an error message saying "unexpected token

Currently, I am conducting testing on a TypeScript file using Mocha. Within the file, there is a dependency that I access via the import statement, and the function I need to test resides within the same file as shown below: import { Foo } from 'foo- ...

Creating a custom NPM package that combines a unique React Hook with a powerful React Component

Having recently ventured into NPM Library Development, I am encountering challenges when trying to consume the library. The issue arises when attempting to export a React Hook and a React Component. While they function correctly within my Application, exp ...

Problem with uploading a zip file in Angular 2

Whenever I attempt to upload a zip file, unfortunately it fails to upload on the server and instead gives me an error message. Here is the code snippet: const event = this.fileEvent; console.log('FileEvent --> ', event); const fileList: FileL ...

Showing canvas lines while dragging (using only plain JavaScript, with React.JS if needed)

Is there a way to add lines with two clicks and have them visible while moving the mouse? The line should only be drawn when clicking the left mouse button. Any suggestions on how I can modify my code to achieve this functionality? Currently, the lines are ...

Creating a task management application using Vue 3 Composition API and Typescript with reactivity

I am in the process of creating a simple todo list application using Vue 3 Composition API and TypeScript. Initially, I set up the function for my component to utilize the ref method to manage the reactivity of user input inserted into the listItems array. ...

Is there a way to reset static data in a TypeScript subclass? (or alternative method for managing global data)

I have a particular set of static data that I would like to access through an API using basic logic. Specifically, this data pertains to metadata about Java classes. My approach involved incorporating the API into a few static methods within a class, alon ...