Laravel - порядок заказа элементов на странице

87
8

Я хочу проверить, правильно ли работает сортировка с Laravel TestCase. У меня простая тестовая страница:

<div id="values">
@foreach(['Value1', 'Value2'] as $value)
<div class="test-class">{{$value}}</div>
@endforeach
</div>

И теперь я хочу проверить, содержит ли первый элемент .test-класс 'Value1'. Я пробовал разные подходы и не имел успеха. Вот первый:

 public function testSorting()
{
$this->visit(route('dummy'));
$this->see('Value1');
$this->seeInElement('.test-class:first-of-type', 'Value2');
}

Это привело к исключению:

Symfony\Component\CssSelector\Exception\ExpressionErrorException: "*:first-of-type" is not implemented.

Затем я попробовал

$this->seeInElement('#values:first-child', 'Value2');

и мой тест, когда зеленый. Но он должен быть красным, потому что первым ребенком является "Value1". Он полностью игнорировал "часть первого ребенка".

Затем я попробовал

$this->seeInElement('#values:nth-child(1)', 'Value2');

и тоже стал зеленым. Таким образом, этот подход тоже не работает.

Я что-то пропустил? Или нет способа проверить порядок элементов на странице с помощью тестов Laravel?

спросил(а) 2021-01-19T15:05:28+03:00 2 месяца, 3 недели назад
1
Решение
62

Не решение для вашего конкретного вопроса, но обходной путь для вашей проблемы: вы можете перечислить свои $loop->iteration test-class с помощью $loop->iteration переменной $loop->iteration, которая содержит номер текущей итерации цикла.

<div id="values">
@foreach(['Value1', 'Value2'] as $value)
<div class="test-class" id="value_{{$loop->iteration}}">{{$value}}</div>
@endforeach
</div>

Теперь ваши классы div имеют нумерованный идентификатор, начинающийся с 1, и вы можете использовать селектор #value_1 в своем тесте, чтобы выбрать первый div:

$this->seeInElement('#value_1', 'Value2');

ответил(а) 2021-01-19T15:05:28+03:00 2 месяца, 3 недели назад
45

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

Внедрите приведенный ниже метод в базовый класс TestCase.

/**
* Given a CSS selector string, check if the elements matching the query
* contain the values provided, in the order they are provided.
*
* @param string $selector
* @param array $contents
* @return $this
*/
public function seeInOrder($selector, Array $contents)
{
$matches = $this->crawler->filter($selector);

try {
foreach ($matches as $index => $domElement) {
$needle = $contents[$index];
$this->assertContains($needle, trim($domElement->textContent));
}
} catch (PHPUnit_Framework_ExpectationFailedException $e) {
$this->fail('Failed asserting that the element at index ' . $index . ' contains the string "' . $contents[$index] . '"');
}

return $this;
}

Применение:

/**
* Test that the /books route returns a list of books in explicit order.
*
* @test
* @return void
*/
public function books_index_page_lists_books_in_explicit_order()
{
$book_1 = factory(App\Book::class)->create([
'order' => 0
]);

$book_2 = factory(App\Book::class)->create([
'order' => 1
]);

$this->visit('/books')
->see($book_1->title)
->see($book_2->title)
->seeInOrder('.books .book', [
$book_1->title,
$book_2->title
]);
}

ответил(а) 2021-01-19T15:05:28+03:00 2 месяца, 3 недели назад
44

Итак, я решил это. Ключ должен был заглянуть в класс \ Symfony\Component\DomCrawler\Crawler. Он имеет много полезных методов, таких как first(), last() или eq ($ number). Я создал этот метод в своем классе TestCase:

public function seeInFirstElement($selector, $text)
{
$this->assertContains($text, trim($this->crawler->filter($selector)->first()->text()));

return $this;
}

Вы можете избавиться от функции trim(), но при этом результат выглядит лучше в случае неудачного теста. Поэтому в моих тестах я использую такие конструкции для проверки порядка:

$this->seeInFirstElement('.test-class', 'Value1');

ответил(а) 2021-01-19T15:05:28+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема