最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cypress intercept blocks the request when it's called several times in a test run - Stack Overflow

programmeradmin0浏览0评论

I've created some tests in Cypress to add and duplicate article in our Angular application. The code for test ArticlesTest.js

describe('Shop articles single station', () => {
const productManagementPage = new ProductManagementPage()
const shopArticlesPage = new ShopArticlesPage()

before(() => {
    var credentials = 
    {
        "username": "[email protected]",
        "password": "strongPassword!"
    }

    cy.navigateToProductManagement(credentials)
})

beforeEach(() => {
    productManagementPage.shopArticlesProgrammingButton().click()
    shopArticlesPage.WaitUntilPageLoaded('/productmanagement/api/v1/articles/get', 'GetArticles')
})

it('Add article', () => {
    var randomNumber = RandomDataGenerator.GenerateRandomInt(1000,4999)
    var randomName = RandomDataGenerator.GenerateRandomString(20)
    var randomPrice = RandomDataGenerator.GenerateRandomDecimal(1,99)

    shopArticlesPage.newArticleButton().click()
    shopArticlesPage.saveButton().should('be.disabled')
    shopArticlesPage.undoButton().should('be.disabled')
    shopArticlesPage.deleteButton().should('be.disabled')
    shopArticlesPage.articlesList().should('not.exist')
    shopArticlesPage.articleNumberTextBox().should('be.enabled')

    shopArticlesPage.articleNumberTextBox().type(randomNumber)
    shopArticlesPage.articleNameTextBox().type(randomName)
    shopArticlesPage.articleUnitPriceTextBox().type(randomPrice)

    shopArticlesPage.undoButton().should('be.enabled')

    shopArticlesPage.saveButton().click()

    shopArticlesPage.newArticleButton().should('exist')
    shopArticlesPage.articlesList().should('exist')
    shopArticlesPage.saveButton().should('be.disabled')
    shopArticlesPage.undoButton().should('be.disabled')

})

it('Duplicate article', () => {
    var articleNumber = RandomDataGenerator.GenerateRandomInt(51,65)
    var newArticleNumber = RandomDataGenerator.GenerateRandomInt(1000, 4999)
    var newArticleName = RandomDataGenerator.GenerateRandomString(20)
    
    shopArticlesPage.articlesList().selectFromList(articleNumber)

    const articleUnitPrice = shopArticlesPage.articleUnitPriceTextBox().invoke('text')
    const vatCodeValue = shopArticlesPage.vatCodeDropDown().invoke('text')
    const cardCodeValue = shopArticlesPage.cardCodeDropDown().invoke('text')

    shopArticlesPage.duplicateArticleButton().click()
    shopArticlesPage.WaitUntilPageLoaded()
    shopArticlesPage.articleNumberTextBox().type(newArticleNumber)
    shopArticlesPage.articleNameTextBox().type(newArticleName)
    shopArticlesPage.saveButton().click()

    shopArticlesPage.newArticleButton().should('be.enabled')
})

WaitUntilPageLoaded() method code is:

WaitUntilPageLoaded(path, alias) {
    return cy.waitForRequestToComplete(path, alias)
}

which, in turn, is custom Cypress mand:

Cypress.Commands.add('waitForRequestToComplete', (path, alias) => {
  cy.intercept('POST', path).as(alias)
  cy.wait('@' + alias).its('response.statusCode').should('be.ok')
})

In 1st beforeEach() run, there's no problem with intercepting GetArticles and waiting for it to plete. The problem starts in 2nd test, as it looks like GetArticles is not intercepted, it's not called at all, though it's supposed to be. The problem doesn't exist when clicking through the application manually, and /articles/get is always invoked. The test ends up with error message

Timed out retrying after 30000ms: cy.wait() timed out waiting 30000ms for the 1st request to the route: GetArticles. No request ever occurred.

I've also tried using other endpoint e.g. vatcodes/get, and it works perfectly. The problem occurs only for articles/get, but I don't see any trail that would tell my why this happens for articles endpoint.

What is the problem? Why Cypress "blocks" 2nd call to this endpoint? What's more interesting, the problem doesn't exist for GetFeatures alias, which is created in an identical way.

I've created some tests in Cypress to add and duplicate article in our Angular application. The code for test ArticlesTest.js

describe('Shop articles single station', () => {
const productManagementPage = new ProductManagementPage()
const shopArticlesPage = new ShopArticlesPage()

before(() => {
    var credentials = 
    {
        "username": "[email protected]",
        "password": "strongPassword!"
    }

    cy.navigateToProductManagement(credentials)
})

beforeEach(() => {
    productManagementPage.shopArticlesProgrammingButton().click()
    shopArticlesPage.WaitUntilPageLoaded('/productmanagement/api/v1/articles/get', 'GetArticles')
})

it('Add article', () => {
    var randomNumber = RandomDataGenerator.GenerateRandomInt(1000,4999)
    var randomName = RandomDataGenerator.GenerateRandomString(20)
    var randomPrice = RandomDataGenerator.GenerateRandomDecimal(1,99)

    shopArticlesPage.newArticleButton().click()
    shopArticlesPage.saveButton().should('be.disabled')
    shopArticlesPage.undoButton().should('be.disabled')
    shopArticlesPage.deleteButton().should('be.disabled')
    shopArticlesPage.articlesList().should('not.exist')
    shopArticlesPage.articleNumberTextBox().should('be.enabled')

    shopArticlesPage.articleNumberTextBox().type(randomNumber)
    shopArticlesPage.articleNameTextBox().type(randomName)
    shopArticlesPage.articleUnitPriceTextBox().type(randomPrice)

    shopArticlesPage.undoButton().should('be.enabled')

    shopArticlesPage.saveButton().click()

    shopArticlesPage.newArticleButton().should('exist')
    shopArticlesPage.articlesList().should('exist')
    shopArticlesPage.saveButton().should('be.disabled')
    shopArticlesPage.undoButton().should('be.disabled')

})

it('Duplicate article', () => {
    var articleNumber = RandomDataGenerator.GenerateRandomInt(51,65)
    var newArticleNumber = RandomDataGenerator.GenerateRandomInt(1000, 4999)
    var newArticleName = RandomDataGenerator.GenerateRandomString(20)
    
    shopArticlesPage.articlesList().selectFromList(articleNumber)

    const articleUnitPrice = shopArticlesPage.articleUnitPriceTextBox().invoke('text')
    const vatCodeValue = shopArticlesPage.vatCodeDropDown().invoke('text')
    const cardCodeValue = shopArticlesPage.cardCodeDropDown().invoke('text')

    shopArticlesPage.duplicateArticleButton().click()
    shopArticlesPage.WaitUntilPageLoaded()
    shopArticlesPage.articleNumberTextBox().type(newArticleNumber)
    shopArticlesPage.articleNameTextBox().type(newArticleName)
    shopArticlesPage.saveButton().click()

    shopArticlesPage.newArticleButton().should('be.enabled')
})

WaitUntilPageLoaded() method code is:

WaitUntilPageLoaded(path, alias) {
    return cy.waitForRequestToComplete(path, alias)
}

which, in turn, is custom Cypress mand:

Cypress.Commands.add('waitForRequestToComplete', (path, alias) => {
  cy.intercept('POST', path).as(alias)
  cy.wait('@' + alias).its('response.statusCode').should('be.ok')
})

In 1st beforeEach() run, there's no problem with intercepting GetArticles and waiting for it to plete. The problem starts in 2nd test, as it looks like GetArticles is not intercepted, it's not called at all, though it's supposed to be. The problem doesn't exist when clicking through the application manually, and /articles/get is always invoked. The test ends up with error message

Timed out retrying after 30000ms: cy.wait() timed out waiting 30000ms for the 1st request to the route: GetArticles. No request ever occurred.

I've also tried using other endpoint e.g. vatcodes/get, and it works perfectly. The problem occurs only for articles/get, but I don't see any trail that would tell my why this happens for articles endpoint.

What is the problem? Why Cypress "blocks" 2nd call to this endpoint? What's more interesting, the problem doesn't exist for GetFeatures alias, which is created in an identical way.

Share Improve this question edited Oct 1, 2024 at 19:45 Raglan 1477 bronze badges asked Sep 10, 2021 at 10:15 hubesalhubesal 1794 silver badges17 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

If I'm reading the situation correctly, the last log image is the failing test.

There is no (xhr) 200 /productmanagement/api/v1/articles/get showing there.

It goes straight from api/v1/subscriptionfeatures/get to api/v1/vatcodes/get, but in the first test the api/v1/articles/get was between those two calls.

If it occurs later in the screenshot, add an increased timeout to catch it (the same intercept can use the longer timeout in both tests, but it won't delay the first test).

This may mean you have found a bug in the app - it seems that a "Duplicate" action should have the same POSTs as an "Add" action.

Make sure the network intercept is registered before the application makes the call.

it('is registered too late', () => {
  cy.intercept('/todos').as('todos')
  cy.visit('/')
  cy.wait('@todos')
})

In our case, we need to register the intercept before visiting the page. Once the page is loaded, the application fetches the todo items, and everything is working as expected.

you can see this link: https://glebbahmutov./blog/cypress-intercept-problems/

Have you resolved this?

I'm using this config:

Given('a GraphQL service error is thrown', () => {
  cy.intercept({ method: 'POST', url: '/uat/graphql', times: 1 }, { forceNetworkError: true });
});

With times: 1. But the interception does not block the request now.

I found times in the docs.

发布评论

评论列表(0)

  1. 暂无评论