问题
Does cypress support soft assertion? For example - I am navigating through 'n' number of elements and want to verify their values. If value of any element is mismatched then it fails the test. It doesn't continue to verify the value of next elements. Is there a way to verify all elements values and show the failed ones at the end?
回答1:
EDIT: I probably misunderstood.. if you meant soft assertions of cy commands (not chai's expect/assert), then this answer is not for you.
WTBS, you could use the below solution and do something like:
describe('test', () => {
    const { softExpect } = chai;
    it('test', () => {
        cy.document().then( doc => {
            doc.body.innerHTML = `
                <div class="test">1</div>
                <div class="test">2</div>
                <div class="test">3</div>
            `;
        });
        cy.get('.test').each( $elem => {
            softExpect($elem[0].textContent).to.eq('2');
        });
    });
});
You could do something like this.
support/index.js
let isSoftAssertion = false;
let errors = [];
chai.softExpect = function ( ...args ) {
    isSoftAssertion = true;
    return chai.expect(...args);
},
chai.softAssert = function ( ...args ) {
    isSoftAssertion = true;
    return chai.assert(...args);
}
const origAssert = chai.Assertion.prototype.assert;
chai.Assertion.prototype.assert = function (...args) {
    if ( isSoftAssertion ) {
        try {
            origAssert.call(this, ...args)
        } catch ( error ) {
            errors.push(error);
        }
        isSoftAssertion = false;
    } else {
        origAssert.call(this, ...args)
    }
};
// monkey-patch `Cypress.log` so that the last `cy.then()` isn't logged to command log
const origLog = Cypress.log;
Cypress.log = function ( data ) {
    if ( data && data.error && /soft assertions/i.test(data.error.message) ) {
        data.error.message = '\n\n\t' + data.error.message + '\n\n';
        throw data.error;
    }
    return origLog.call(Cypress, ...arguments);
};
// monkey-patch `it` callback so we insert `cy.then()` as a last command 
// to each test case where we'll assert if there are any soft assertion errors
function itCallback ( func ) {
    func();
    cy.then(() => {
        if ( errors.length ) {
            const _ = Cypress._;
            let msg = '';
            if ( Cypress.browser.isHeaded ) {
                msg = 'Failed soft assertions... check log above ↑';
            } else {
                _.each( errors, error => {
                    msg += '\n' + error;
                });
                msg = msg.replace(/^/gm, '\t');
            }
            throw new Error(msg);
        }
    });
}
const origIt = window.it;
window.it = (title, func) => {
    origIt(title, func && (() => itCallback(func)));
};
window.it.only = (title, func) => {
    origIt.only(title, func && (() => itCallback(func)));
};
window.it.skip = (title, func) => {
    origIt.skip(title, func);
};
beforeEach(() => {
    errors = [];
});
afterEach(() => {
    errors = [];
    isSoftAssertion = false;
});
And in your spec:
describe('test', () => {
    const { softAssert, softExpect } = chai;
    it('test', () => {
        cy.wrap([1, 42, 3]).then( vals => {
            vals.forEach( val => {
                softAssert(val === 42, `${val} should equal 42`);
            });
        });
    });
    it('test2', () => {
        cy.wrap([2, 5, 4]).then( vals => {
            vals.forEach( val => {
                softExpect(val).to.eq(42);
            });
        });
    });
});
Cypress log:
Terminal (headless run):
来源:https://stackoverflow.com/questions/55868107/does-cypress-support-soft-assertion