En mi suite de pruebas Cypress, tengo un comando que realiza una llamada API a un servicio de correo electrónico en busca de un correo electrónico con un asunto en particular y devuelve el contenido de ese correo electrónico.
Cypress.Commands.add('getMostRecentEmail', subject => { const requestUrl = new URL('api/mails', 'localhost') requestUrl.port = '3000' requestUrl.searchParams.append('subject', subject) // TODO: wait for the following request to return a non-empty response.body return cy.request('GET', requestUrl.toString()).then(response => { return response.body[0].content[0].value }) })Esto funciona bien cuando ejecuto la prueba localmente, pero cuando la prueba se ejecuta en CI, falla la primera vez, pero tiene éxito cuando Cypress vuelve a intentar la prueba automáticamente. Presumiblemente, esto se debe a que el correo electrónico aún no se ha recibido la primera vez que se intenta recuperarlo (el correo electrónico se envía inmediatamente antes de que se ejecute el código anterior).
response.body es el número de correos electrónicos coincidentes devueltos por el servicio, y la primera vez que se realiza una solicitud, está vacío, por lo que response.body[0] no está undefined .
Cypress informa que esta prueba es "inestable" porque no tiene éxito la primera vez que se intenta.
Para solucionar esto, me gustaría esperar a que la solicitud devuelva una respuesta no vacía antes de recuperar el contenido del primer correo electrónico.
Eche un vistazo a la presentación https://slides.com/bahmutov/email-testing . En particular, la publicación de blog https://www.cypress.io/blog/2021/05/24/full-testing-of-html-emails-using-ethereal-accounts/#retry-email-task habla sobre cómo reintentar recibir el correo electrónico, ya que puede suceder solo después de un tiempo desconocido.
Cree una función para su solicitud a la que pueda llamar recursivamente:
function makeRequestRecursively() { cy.request('GET', requestUrl.toString()).then(response => { let value = response.body[0].content[0].value; if (response.body[0].content[0].value != undefined) { return value; } else { // Recursively call the function after 0.5 seconds. You can adjust or remove this. setTimeout(function (){ return makeRequestRecursively(); }, 500); } } }Reemplazar:
return cy.request('GET', requestUrl.toString()).then(response => { return response.body[0].content[0].value })Con:
return makeRequestRecursively()