cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.02k stars 3.19k forks source link

Add feature to "wait" until checks triggered by URL or DOM change completed ( or improve cy.wait() ) #28095

Open ZakharDolozhevskiy opened 1 year ago

ZakharDolozhevskiy commented 1 year ago

What would you like?

Hello Cypress team, I'm writing a plugin that runs checks of some company-specific information on the testing pages and I would like to have the ability to "stop" the Cypress process until all checks that are caused by DOM change or browser URL change are done.

Request

  1. Have cy.stop() that stops the process ( means no commands from the test suite are executed ) until some cy.resume() command is called.

  2. Wait until all internal promises are resolved before stopping the process. ( see Issue bellow for explanation )

Context

I have a custom command that performer such analysis and for convenience the requirements are:

1 - Listen to any DOM change and run the analysis 2 - Listen to any URL change, wait until the page loads, and run analysis ( redirect to a new page after clicking on the link ) 3 - Call listeners at the beginning of the test and then call report after testing is done

Here is an example of what it looks like:

it("test suite", () => {
  // Under the hood it has a listener to "url:change" and DOM observer
  cy.startListenForChangesAndRunAnalisy()

  cy.visit("page 1")

  // Some checks on page 1

  cy.contains("link to page 2").click()

  // Some checks on page 2

  cy.contains('button that change DOM').click()

  // Some checks on page 2 after DOM change

  // Saves artifacts
  cy.createReportAndStopListeners()
})

Please note that plugin developers don't have access to the test suite and can impact only plugin code.

Issues

  1. Plugins code is running after some async action ( an event that URL change, DOM mutation ), and there is no way to stop Cypress and wait until checks are done ( I've used Cypress promises, chaining with cy.window, etc ) it leads to a problem when analysis that triggered on "page 1" actually executed on "page 2" because page already changed due to click on the test suite

  2. Cypress doesn't wait for all internal promises. I would expect that if Cypress has an internal implementation of Promises it can detect that some of them are still pending and wait for it. In my case, I've got an issue that Cypress finished with test suite commands but analyses caused by the plugin logic weren't finished

Why is this needed?

Stop / Resume

I think there are many cases when due to the async nature of Cypress testing flow developers want to stop/resume that process to perform some background checks at the DOM

Promises

Would be nice to handle pending promises in a way when "all of them should be resolved" until test is stoped to make custom logic more stable

Other

Thank you for considering my request, besides that, i checked the official documentation and other sources to find a solution for my case i hope that community can help me out to resolve my issue

ZakharDolozhevskiy commented 1 year ago

Here is a sample project for debugging

https://github.com/ZakharDolozhevskiy/cypress-async-plugin