1

UseCase :

I want to automatically test all sitemap URLs (more than 1000) of our website after each new code release to see if we broke any of them.

My problem :

Test is done with no error even when a URL returns anything else than 200 but instead I need to save the results into sort of a callback function, check them and fail the test only at the end ( for both of my cy.request() ) if an error occurs in order to find all the broken links whithout stopping the test in the middle of test run.

This is my code

describe('Validate sitemaps files', () => {
let urls = []
let results = []
const failed = []

before(function () {
    cy.fixture('sitemaps.json').then((data) => {
        for (var index in data) {
            cy.log(data[index].url)
            cy.request({
                url: Cypress.config().baseUrl + data[index].url,
                failOnStatusCode: false,
                headers: {
                    "Content-Type": "text/xml; charset=utf-8",
                    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36",
                },
            }).as("parentSitemapPath").then((responseParent) => {
                urls = Cypress.$(responseParent.body)
                    .find("loc")
                    .toArray()
                    .map((el) => el.innerText)
                cy.log(JSON.stringify(responseParent.status))
                if (response.status !== 200) {
                    ????

                 }
            })
        }  
    })
})

it("Should succesfully load each url in the sitemap", () => {
    urls.forEach((url) => {
        cy.request({
            method: 'HEAD',
            url: url,
            failOnStatusCode: false,
        }).as("childSitemapPath").then(response => {
            if (response.status !== 200) {
                    ????

            }
        })
    })
})

})

I have already seen these answers ==> Cypress: Is it possible to complete a test after failure, Denial of Service (status code 429) when testing sitemap links in Cypress but no success so far.

Any help is much appreciated

1 Answers1

1

You can use cy.wrap and .each functions to pass the array of URLs into the Cypress command chain and iterate through them, similar to JavaScript's .forEach(). After we've finished sending requests to each URL, we can simply assert that the failed array has a length of 0.

it("Should succesfully load each url in the sitemap", () => {
    cy.wrap(urls).each((url) => {
        cy.request({
            method: 'HEAD',
            url: url,
            failOnStatusCode: false,
        }).as("childSitemapPath").then(response => {
            if (response.status !== 200) {
                // Add the url to the failed array - you can add other information if you'd prefer
                failed.push(url)
            }
        })
    }).then(() => {
        // Use a chai assertion to check the array is empty
        expect(failed).to.be.empty
        // Optionally, use cy.wrap to use a Cypress assertion
        cy.wrap(failed).should('have.length', 0)
    })
})

If you need to do this in your before hook as well, you can use the same logic of pushing the url/information to the failed array, and simply add a .then() after the .then() in which you are making the requests.

agoff
  • 5,818
  • 1
  • 7
  • 20