Как получить элемент вложенный элемент - PullRequest
0 голосов
/ 22 марта 2020

Друзья! Несколько дней go Я начал свои тесты по автоматизации с Cypress. У меня проблемы с получением элемента.

Как, например, я предоставляю этот HTML макет:

Первый блок

<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 1</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button>Button</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>

Второй блок

<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 2</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button>Button</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>

Я хочу нажать на кнопку, но можно найти только <div class="label_1">Some text 1</div>. Я использую этот код:

 cy.get('.label_1').contains('Some text 1').parents().find('button').click()

или этот:

cy.get('.label_1').contains('Some text 1').parent(). ... .parent().find('button').click()

enter image description here

Но у меня есть свое решение, но оно проблема, чтобы получить счет этого: <div class="class_0"> блок.

1 Ответ

1 голос
/ 22 марта 2020

Вы можете итеративно искать родителя с помощью кнопки child. Если кнопка в конце концов найдена, нажмите ее.

Вот рекурсивная функция для поиска родителя с дочерним элементом кнопки.

function findCousin(node, childSelector) {
  while (node != null & node.length > 0 && node.find(childSelector).length < 1) {
    node = node.parent();
  }
  return node ? node.find(childSelector) : null;
}

Редактировать: Итак, это похоже, что Cypress использует jQuery за кулисами. Я создал простую прокладку для эмуляции существующей функциональности без ее изменения.

// *** IGNORE: BEGIN SHIM ***
$.fn.findByContentText = function(text) {
  return this.contents().filter((i, c) => $(c).text().trim() == text.trim());
};
class CyElement {
  constructor(selector) { this.ref = $(selector); }
  contains(text) { return this.ref.findByContentText(text); }
  parent() { return new CyElement(this.ref.parent()); }
  find(selector) { return new CyElement($(this.ref.find())); }
  click() { this.ref.trigger('click'); }
}
const cy = {};
cy.get = (selector) => new CyElement(selector);
// *** IGNORE: END SHIM ***

let target, button;

target = cy.get('.label_1').contains('Some text 1');
button = findCousin(target, 'button');
if (button != null) {
  button.click();
}

target = cy.get('.label_1').contains('Some text 2');
button = findCousin(target, 'button');
if (button != null) {
  button.click();
}

function findCousin(node, childSelector) {
  while (node != null & node.length > 0 && node.find(childSelector).length < 1) {
    node = node.parent();
  }
  return node ? node.find(childSelector) : null;
}

function handleClickEvent(button) {
  console.log(`Clicked on ${button.textContent}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 1</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button onclick="handleClickEvent(this); return false;">Button 1</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>

<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 2</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button onclick="handleClickEvent(this); return false;">Button 2</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>

Вот только версия jQuery

// *** IGNORE: BEGIN SHIM ***
(($) => {
  $.fn.findByContent = function(text) {
    return this.contents().filter((i, c) => $(c).text().trim() == text.trim());
  };
  $.fn.cousin = function(childSelector) {
    let node = this;
    while (node != null & node.length > 0 && node.find(childSelector).length < 1) {
      node = node.parent();
    }
    return node ? node.find(childSelector) : null;
  }
})(jQuery);

$('button').on('click', (e) => {
  console.log(`Clicked on ${$(e.target).text()}`);
  e.preventDefault();
})

let button1 = $('.label_1').findByContent('Some text 1').cousin('button');
if (button1 != null) {
  button1.click();
}

let button2 = $('.label_1').findByContent('Some text 2').cousin('button');
if (button2 != null) {
  button2.click();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 1</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button>Button 1</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>

<div class="class_0">
  <div class="class_1"></div>
  <div class="class_2">
    <div class="label_0">
      <div class="label_1">Some text 2</div>
    </div>
  </div>
  <div class="class_3">
    <div class="tooltip_0"></div>
    <div class="tooltip_1">
      <form>
        <button>Button 2</button>
      </form>
    </div>
    <div class="tooltip_2"></div>
  </div>
</div>
...