Search code examples
javascriptasp.netweb-applicationsfunctional-testingcypress

Error when testing webapp with multiple sequential pages


I'm testing an ASP.NET webapp (to the code of which I do not have access) with multiple sequential pages with the following relevant parts in a Cypress script:

describe("Calculation", function() {

  // ...

  context("Pages", function() {

    // ... 

    // Page 1
    it("With all inputs", function() {
      cy.visit(url)
      // ... setting input fields ...
      cy.get(next).click()
      cy.get('.stg-error-mark').should('have.length', 0)
    })
  
    // Page 2
    it("No selection", function() {
      cy.get(next).click()
      cy.get('.stg-error-mark').should('have.length', 2)
    })
  })
})

Page 2 it(...)'s Command Log contains:

...
- CLICK
(FORM SUB)   --submitting form--   ← Page 2 looks fine in Cypress' App Preview.
(PAGE LOAD)   --page loaded--   ← The webapp shows the error below in the App Preview.
...

 

Error

The input transaction was automatically cancelled because it was not continued for too long. Please start again.

It seems that the webapp lacks some internal state if Page 1 hasn't been visit()ed in the it(...) of Page 2.

I know that putting all relevant page code parts into (describe-global) functions and calling them increasingly and such always starting at Page 1 in each test works. But, since this app has 33 different functional paths with 5 to 6 sequential pages (depending on user input on a previous page) I'd like to avoid this code-bloating, confusing, error-prone and time-consuming function chaining–and globals are of the devil.

UPDATE

From theory to practice, this is the functional paths chart:

  +------ Seite 1 -------+----- Seite 2 -----+------ Seite 3 ------+------ Seite 4 ------+- Seite 5.1 -+- Seite 5.2 -+
  |    Wohneinheiten     |   Fördermodell    |   1. Wohneinheit    |   2. Wohneinheit    | Berechnung  | Berechnung  |
  |         2/4          |        8/2        |        12/10        |         6/5         |   Input     |   Output    |
  |                      |                   |                     |                     |             |             |
  |    Wohneinheiten:    |   ▼ Modell        |  Heizwärmebedarf:   |                     |             |             |
  |  +- <no> --->(X)     |  +-▼ Passiv ------>-- HWB: ----------------------------------->------------->             |
  |  |                   |  |                |   +- !]0..10]       |                     |             |             |
  |  +- WE1: --->(X)     |  |                |      +--->(X)       |                     |             |             |
  |  |                   |  |                |                     |                     |             |             |
  |  +- WE2: --->(X)     |  +-▼ Punkte ------>-- HWB: ----------------------------------->------------->             |
  |  |                   |  |                |   +- !]10..49]      |                     |             |             |
  |  +- WE1:             |  |                |      +--->(X)       |                     |             |             |
  |  |  +- AV-V: -------->--+                |                     |                     |             |             |
  |  |                   |  |                |  +-▼ PV ---------------------------------->------------->             |
  >--+                   |  |                |  +-▼ Solar ------------------------------->------------->             |
  |  |                   |  +-▼ Niedrig ----->--+-x WRL --------------------------------->------------->             |
  |  |                   |  |                |  +- <no> --->(X)    |                     |             |             |
  |  +- WE2:             |  |                |                     |                     |             |             |
  |  |  +- AV-V: --->(X) |  +-▼ Niedrigst --->--▼ Heizsystem ---------------------------->------------->             |
  |  |                   |  |                |    +-▼ Elektrisch   |                     |             |             |
  |  |                   |  +-▼ <no> --->(X) |        +-▼ PV2kWp   |                     |             |             |
  |  |                   |                   |        |   +--->(X) |                     |             |             |
  |  |                   |                   |        +-o WRL      |                     |             |             |
  |  |                   |                   |            +--->(X) |                     |             |             |
  |  +- WE1:             |                   |                     |                     |             |             |
  |     +- WE2:          |   ▼ Modell        |  Heizwärmebedarf:   |  Heizwärmebedarf:   |             |             |
  |        +- AV-V: ----->--+-▼ Passiv ------>-- HWB: ------------->-- HWB: ------------->------------->             |
  |                      |  |                |   +- !]0..10]       |   +- !]0..10]       |             |             |
  +----------------------+  |                |      +--->(X)       |      +--->(X)       |             |             |
                         |  |                |                     |                     |             |             |
                         |  +-▼ Punkte ------>-- HWB: ------------->-- HWB: ------------->------------->             |
                         |  |                |   +- !]10..49]      |   +- !]10..49]      |             |             |
                         |  |                |      +--->(X)       |      +--->(X)       |             |             |
                         |  |                |                     |                     |             |             |
                         |  +-▼ Niedrig ----->--+-▼ PV  ----------->--+-▼ PV  ----------->------------->             |
                         |  |                |  +-▼ Solar --------->  +-▼ Solar --------->------------->             |
                         |  |                |  +-x WRL ----------->  +-x WRL ----------->------------->             |
                         |  |                |  +- <no> --->(X)    |  +- <no> --->(X)    |             |             |
                         |  |                |                     |                     |             |             |
                         |  +-▼ Niedrigst --->--▼ Heizsystem ------>--▼ Heizsystem ------>------------->             |
                         |  |                |    +-▼ Elektrisch   |    +-▼ Elektrisch   |             |             |
                         |  +-▼ <no> --->(X) |        +-▼ PV2kWp   |        +-▼ PV2kWp   |             |             |
                         |                   |        |   +--->(X) |        |   +--->(X) |             |             |
                         |                   |        +-x WRL      |        +-x WRL      |             |             |
                         |                   |            +--->(X) |            +--->(X) |             |             |
                         +-------------------+---------------------+---------------------+-------------+-------------+
Legend:
  : ...... Textbox
  .. ..... Interval
  ▼ ...... Dropdown-Listbox or selection
  x,o .... Checkbox (checked, unchecked)
  <no> ... No input or selection
  ! ...... Not
  (X) .... Error
  > ...... Proceed to page or error

Everything's clear now, isn't it? (: OK, it looks a bit less overwhelming in green and a higher and wider view in an editor.)

It's Seite 3 and Seite 4 in the lower part that are identical and duplicated in case of WE2 input on Seite 1.


Solution

  • I solved this by what I mentioned trying to avoid in my question: Externalizing relevant code to describe-global functions. That's all what I mentioned above but it's DRY, at least.

    describe("Calculation", function() {
    
      let P1withAllInputs = function() {
        cy.visit(url)
        // ... setting input fields ...
        cy.get(next).click()
        cy.get('.stg-error-mark').should('have.length', 0)
      }
    
      context("Page 1", function() {
    
        // ... 
    
        it("With all inputs", function() {
          P1withAllInputs()
        })
      })
    
      context("Page 2", function() {
    
        P1withAllInputs()
    
        // ... 
    
        it("No selection", function() {
          cy.get(next).click()
          cy.get('.stg-error-mark').should('have.length', 2)
        })
      })
    })