Reputation: 179
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 command:
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 complete.
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.
Upvotes: 3
Views: 3529
Reputation: 449
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.com/blog/cypress-intercept-problems/
Upvotes: 3
Reputation: 7525
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.
Upvotes: 0
Reputation: 1108
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.
Upvotes: 6