Estoy escribiendo un conjunto de pruebas en una lista de elementos (tabla HTML).
Dado que las pruebas aún son un trabajo en progreso, recibo una gran cantidad de datos no deseados que me gustaría limpiar antes de cada ejecución.
Por lo tanto, estoy tratando de eliminar todas las filas en el gancho before() . Me imagino que el proceso para eliminar debería ser:
2 hasta que no queden filas.Esta es la función que tengo hasta ahora a la que llamo después de escribir la entrada de búsqueda:
function deleteAllFoundProducts() { cy.get('tbody tr').then(rows => { if (rows.length < 1) return // if no rows remain, terminate recursion cy.get('span[title="Delete"]', {timeout: 10000}).first().click() cy.get('.tBtn[title="Yes"]').click().then(() => { cy.get('.loader', {timeout: 10000}).should('not.exist') // wait for list to reappear deleteAllFoundProducts() // try again }) }) } El problema es que la función continúa ejecutándose incluso después de eliminar la fila final y se produce un error porque no hay span[title="Delete"] .
[EDITAR]
En una inspección más cercana, me di cuenta de que una tabla vacía todavía tiene una fila, con el texto No se encontraron registros . Pensé que no era una pelea en absoluto. Por lo tanto, el error se debe a que una fila no contiene un icono de eliminación. Debería haberlo notado antes.
Este es HTML relevante con elementos angulares innecesarios eliminados:
<tbody class="p-element p-datatable-tbody" ng-reflect-value="" ng-reflect-template="[object Object]"> <tr> <td colspan="6"> <my-loader ng-reflect-loading="false"> </my-loader> <div class="p-2">No matching records found. </div> </td> </tr> </tbody>Supongo que la solución sería verificar si la fila contiene un elemento con el texto 'No se encontraron registros', y realizar la eliminación solo si no es así. Pero no estoy seguro de cómo hacerlo. Cualquier ayuda sería apreciada.
Con esta función recursiva, solo necesita pasar una variable que disminuya (o tal vez aumente hasta un máximo)
function deleteAllFoundProducts(rowCount) { if (rowCount < 1) return // if no rows remain, terminate recursion cy.get('span[title="Delete"]', {timeout: 10000}).first().click() cy.get('.tBtn[title="Yes"]').click().then(() => { cy.get('.loader', {timeout: 10000}).should('not.exist') // wait for list to reappear deleteAllFoundProducts(--rowCount) // try again }) } cy.get('tbody tr') .then(rows => deleteAllFoundProducts(rows.length)) // first call here Esto seguirá funcionando cuando se agregue una fila "No se encontraron registros coincidentes" después de eliminar todas las filas, ya que el número de rowCount se obtiene antes de que comiencen las eliminaciones.
La recursividad es la forma más segura de iterar, especialmente cuando se cambia el DOM durante el ciclo o hay una parte condicional en la prueba. El uso .each() puede generar errores de "separación del DOM".
Hay una biblioteca https://github.com/bahmutov/cypress-recurse que lo hace un poco más fácil.
Podrías aplicarlo así
import { recurse } from 'cypress-recurse' before(() => { recurse( () => { return cy.get('tbody tr').eq(0).then($row => { const $deleteButton = $row.find('button[title="Delete"]') if ($deleteButton.length) { $deleteButton[0].click() } return $deleteButton // return this to signal end of iteration }) }, ($deleteButton) => $deleteButton.length === 0 // end if no delete button ) })Entonces, esto es una suposición, si esto no funciona, necesitaría ver la tabla HTML. Entonces, lo que asumo es que en su tabla tiene diferentes filas y en cada fila tiene un botón Eliminar y una vez que elimina el botón se elimina la fila. Puede usar un comando de ciprés incorporado each() .
cy.get('tbody tr').each(($ele) => { cy.wrap($ele).within(() => { cy.get('span[title="Delete"]', {timeout: 10000}).first().click() }) cy.get('.tBtn[title="Yes"]').click() cy.get('.loader', {timeout: 10000}).should('not.exist') })O, cuando se muestra 'No se encontraron registros', simplemente salga del bucle.
cy.get('tbody tr').each(($ele) => { if ($ele.find('div.p-2').text().trim().includes('No records found')) { return false } else { cy.wrap($ele).within(() => { cy.get('span[title="Delete"]', {timeout: 10000}).first().click() }) cy.get('.tBtn[title="Yes"]').click() cy.get('.loader', {timeout: 10000}).should('not.exist') } })