How to stop loop in cypress

后端 未结 2 1079

I have a loop checking 40 items. I want to stop my loop, when I am finding the first element, which > 0 This is my code

var genArr = Array.from({ length: 40 }, (v,

2条回答
  •  攒了一身酷
    2021-01-12 15:21

    break works only for native for/while loops.

    To exit early from an .each loop (as was suggested in the comments), the false must be returned from the same callback you pass to it, so returning false from the nested then callback won't have an effect.

    You can't even set a flag in the then callback and check it in the each callback, because .each() command is deep down just a jQuery.fn.each --- it's synchronous and by the time you'd set up the flag, all iterations will have run (and enqueued the nested commands).

    Thus, the only option is not to use .each(), and use some kind of recursive command. Let's build one.

    function walk ( arr, cb, index = 0 ) {
        if ( !arr.length ) return;
        arr = arr.slice();
        const ret = cb(index, arr.shift());
        ((ret && ret.chainerId) ? ret : cy.wrap(ret))
            .then( ret => {
                if ( ret === false ) return;
                return walk(arr, cb, index + 1);
            });
    }
    
    /**
     * Your callback should return/yield `false` if the loop is to exit early.
     */
    Cypress.Commands.add('eachSeries', { prevSubject: 'optional' }, (subject, arr, cb) => {
    
        return subject
            // assume `arr` to be `cb`
            ? walk(subject, arr)
            : walk(arr, cb);
    });
    

    usage:

    describe('test', () => {
        it('test', () => {
            cy.document().then(doc => {
                doc.body.innerHTML = `
                    
    0
    1
    2
    3
    `; }); var genArr = Array.from({ length: 40 }, (v, k) => k + 1); // the command can be chained on an existing subject cy.wrap(genArr).eachSeries((index) => { return cy.get('.list-item').eq(index) .invoke('text') .then(text => { if (text > 1) return false; }); }); // or it can start the chain (the array is passed as 1st arg) cy.eachSeries(genArr, (index) => { return cy.get('.list-item').eq(index) .invoke('text') .then(text => { if (text > 1) return false; }); }); // you can also return a promise cy.eachSeries(['a', 'b', 'c'], (index, value) => { return new Promise(resolve => { setTimeout(() => { resolve(value === 'b' ? false : true); }, 500); }); }); // non-thenable callbacks work too cy.eachSeries(['a', 'b', 'c'], (index, value) => { return value === 'b' ? false : true; }); }); });

    In the first two examples above, only the first 3 items are looped through and then the loop exits early.

提交回复
热议问题