Функциональные селекторы TestCafe

Я пытаюсь понять, как сделать селекторы, которые мне нужны, но я немного озадачен. Моя DOM выглядит так:

<div class="project index_list__item_container">
  <div class="index_item__header">
    <h3 class="index_item__title">
      <a class="index_item__title_link" href="/foo_bar_link">
        foo bar title
      </a>
    </h3>
    <div class="index_list__item_detail index_list__item_detail--light">
      <span data-test="progress-p">
        In Progress / Started about 1 month ago
      </span>
    </div>
  </div>
  <div class="index_item__stats_and_actions">
    <a class="index_item__stat_indicator" href="/foo_bar_link">
      <span class="stat_indicator__stat_total">23</span>
      <span class="index_item__stat_description">views</span>
    </a>
    <a class="index_item__stat_indicator" href="/foo_bar_link">
      <span class="stat_indicator__stat_total">25</span>
      <span class="index_item__stat_description">plays</span>
    </a>
  </div>
</div>

На странице есть множество таких «контейнеров с предметами», все они представлены списком. Проще говоря, я пытаюсь «найти конкретный элемент, в котором есть« заголовок панели foo », а затем убедиться, что в деталях элемента есть текст« Выполняется »».

Я пробовал использовать .filter (а ранее .find) вот так:

test('Verify states', async (t) => {
  const draftItemDetail = await 
    indexPage.indexItemContainer.withText('foo bar title')
      .filter(indexPage.indexItemDetail);

  await t
    .expect(draftItemDetail.textContent).contains('In Progress');
});

// Page Object
import { Selector } from 'testcafe';

export default class IndexPage {
  constructor() {
    this.indexItemContainer = Selector('.index_list__item_container');
    this.indexItemDetail = Selector('.index_list__item_detail');
  }
}

Я получаю следующее сообщение об ошибке:

 1) filter code is expected to be specified as a function, but string was passed.

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


person Samantha Blasbalg    schedule 26.09.2018    source источник


Ответы (1)


Фильтр функция принимает predicate или cssSelector. Однако вы передаете Selector (indexPage.indexItemDetail).

Например, следующий функция find правильно находит нужный элемент, и проверка пройдена:

test('Verify states', async (t) => {
  const draftItemDetail = await indexPage.indexItemContainer
    .withText('foo bar title')
    .find(".index_list__item_detail")

  await t.expect(draftItemDetail.textContent).contains('In Progress');
});

В качестве альтернативы вы можете передать второй селектор как зависимость от дочернего / родительского предиката:

test('Verify states', async (t) => {
  const indexItemDetail = indexPage.indexItemDetail;
  const draftItemDetail = await indexPage.indexItemContainer
    .withText('foo bar title')
    .child((node, idx, originNode) => {
        const itemDetail = indexItemDetail();
        if (node.contains(itemDetail))
            return true;
    }, { indexItemDetail });

  await t.expect(draftItemDetail.textContent).contains('In Progress');
});
person Alex Skorkin    schedule 27.09.2018
comment
Ооо, это имеет смысл. Хм. Я передавал Selector, потому что хотел передать что-то из объекта страницы, вместо того, чтобы иметь cssSelector в моем тестовом файле. Вы бы порекомендовали сохранить только строку в объекте страницы? Это кажется ... немного странным. Или, может быть, метод в объекте страницы, который принимает заголовок и возвращает draftItemDetail? Я пытаюсь понять лучшие практики, я еще новичок в этом. Спасибо! - person Samantha Blasbalg; 27.09.2018
comment
Благодарим Вас за разъяснения. В этом случае вы можете передать второй селектор как зависимость от дочернего / родительского предиката, как я проиллюстрировал в своем обновленном ответе. - person Alex Skorkin; 28.09.2018