Cypress: каждый с внутренним циклом прерывания обещания

#javascript #loops #promise #each #cypress

#javascript #циклы #обещание #каждый #cypress

Вопрос:

Я использую Cypress и хочу выйти из каждого цикла, который содержит обещание.

 cy.get('div').find('div.myclass').each(el => {
    cy.get(el).find('span#myclass').then(span => {
        const myText = Cypress.$(span).clone().children().remove().end().text().trim();
        if (myText === 'somethings') {                
            cy.get(el).as('mySection');
            // ### HERE I WANT TO EXIT ###
        }
    });
});
  

Кто-нибудь может мне помочь?

Ответ №1:

Вы можете return false прерваться раньше, см. Документы.

Досрочный возврат
Вы можете досрочно остановить цикл .each(), вернув false в функции обратного вызова.

Протестировано с cypress fiddle

 const selectMySection = {
  html: `
    <div class="myclass">
      <span id="myid">
        <p>child of span1</p>
        <p>child of span2</p>
        span text - find this
      </span>
    </div>
    <div class="myclass">
      <span id="myid">
        <p>child of span3</p>
        <p>child of span4</p>
        span text - ignore this
      </span>
    </div>
  `,
  test: `
    cy.get('div.myclass span#myid')
      .each(($span, i) => {
        console.log('processing span #', i); // only logs 'processing span # 0'
        const text = Cypress.$($span).text()
        if (text.includes('span text - find this')) {
          cy.wrap($span)
            .parent('div.myclass')  // move to parent
            .as('mySection')
          return false;
        }
      })

    cy.get('@mySection')
      .then(x => console.log(x))
  `
}
it('test selectMySection', () => {
  cy.runExample(selectMySection)
})
  

Альтернативой циклическому использованию является использование .contains('my text') для таргетинга нужного текста.
Обратите внимание, что .contains() это приводит к частичному совпадению, поэтому вы можете игнорировать дочерние тексты.

 cy.get('div.myclass span#myid')
  .contains('span text - find this')
  .as('mySection')
  

Комментарии:

1. Технически, вам нужно использовать псевдоним div.myclass , а не диапазон.

2. Может cy.wrap($span).parent().as('mySection') быть?

3. Спасибо @MarionMorrison, я этого не заметил.

Ответ №2:

Просто добавьте return false в конце, и вы выйдете из функции.

 cy.get('div').find('div.myclass').each(el => {
  cy.get(el).find('span#myclass').then(span => {
    const myText = Cypress.$(span).clone().children().remove().end().text().trim();
    if (myText === 'somethings') {
      cy.get(el).as('mySection')
      return false
    }
  })
})
  

Комментарии:

1. Привет, с возвратом я выхожу только из обещания, но я хочу выйти из каждого! Я хочу разорвать цикл! Спасибо!

2. return false Будет работать только при выполнении if инструкции.

3. Оператор if выполняется, потому что был установлен псевдоним.

4. Он по-прежнему повторяется несколько раз. Зачем удалять псевдоним, который, похоже, является целью кода?

5. Единственный способ, которым я вижу, что это работает, — это если вы «перевернете назад». т.е. Установите переменную, определенную в области каждого блока, и верните ее после if .