首页 > 解决方案 > 如何在柏树中停止循环

问题描述

我有一个循环检查 40 个项目。当我找到第一个元素时,我想停止我的循环,它 > 0 这是我的代码

var genArr = Array.from({ 长度: 40 }, (v, k) => k + 1);

cy.wrap(genArr).each((index) => {
    cy.get('.list-item').eq(index - 1).find('.number')
        .invoke('text')
        .then(text => {
            const pendingCount = text;
            cy.get('.list-item').eq(index - 1).click();
            cy.get('.list-table').find('.list-table-list-item')
                .should('have.length', pendingCount);
            if (text > 0) break
         });
    });

});

但我有一个语法错误。请帮帮我,我怎样才能打破我的循环

标签: loopsautomated-testsbreakcypress

解决方案


break仅适用于本机for/while循环。

要从.each循环中提前退出(如评论中所建议的那样),false必须从您传递给它的同一个回调中返回,因此false从嵌套then回调中返回不会有任何效果。

您甚至不能在回调中设置标志并在then回调中检查它each,因为.each()命令在深处只是一个jQuery.fn.each--- 它是同步的,当您设置标志时,所有迭代都将运行(并入队嵌套命令)。

因此,唯一的选择是不使用.each(),而使用某种递归命令。让我们建造一个。

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);
});

用法:

describe('test', () => {
    it('test', () => {
        cy.document().then(doc => {
            doc.body.innerHTML = `
                <div class="list-item">0</div>
                <div class="list-item">1</div>
                <div class="list-item">2</div>
                <div class="list-item">3</div>
            `;
        });

        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;
        });
    });
});

在上面的前两个示例中,只有前 3 个项目被循环通过,然后循环提前退出。


推荐阅读