Новое в Symfony 4.4: Новые методы DomCrawler

Компонент DomCrawler в основном используется в приложениях Symfony для помощи в функциональных тестов для фильтрации узлов DOM документов HTML/XML. Методы, предоставляемые DomCrawler, изначально были вдохновлены jQuery, такие как eq(), first(), children(), nextAll() и т. д.

В Symfony 4.4 добавили три новых метода, часто запрашиваемых сообществом: match(), closest() и outerHtml(). Рассмотрим следующий фрагмент HTML:

<html lang="en">
<body>
    <div class="class-1">
        <h1 class="class-1">Lorem Ipsum</h1>

        <ul class="class-2 class-3" id="id-1">
            <li>1</li>
            <li class="class-4">2</li>
            <li>3</li>
        </ul>
    </div>
</body>
</html>

Метод match(string $selector) возвращает true, если узел соответствует данному селектору CSS:

$crawler->filter('#id-1')->matches('.class-3');  // true
$crawler->filter('#id-1')->matches('.class-4');  // false

Метод closest(string $selector) возвращает первого предка узла, который соответствует данному селектору CSS:

// returns the div.class-1 node and NOT the h1.class-1 node because h1 is
// a sibling and not an ancestor of ul#id-1
$crawler->filter('#id-1')->closest('.class-1');

Метод outerHtml() возвращает все содержимое HTML узла, включая его собственные теги:

// returns '<ul class="class-2 class-3" id="id-1"><li>1</li><li class="class-4">2</li><li>3</li></ul>'
$crawler->filter('#id-1')->outerHtml();

// returns '<li>1</li><li class="class-4">2</li><li>3</li>'
$crawler->filter('#id-1')->html();

Удаление лишних пробелов

Работа с пробелами довольно раздражает при проверке содержимого некоторых тегов HTML. Например, со следующим фрагментом HTML:

<div class="class-1">
    <h2>
        Some Title Text
    </h2>
</div>

Следующий тест не пройдет из-за всех «n» и пробелов, окружающих текст заголовка:

// this fails because of the extra white spaces
$this->assertSame('Some Title Text', $crawler->filter('.class-1')->text());

В Symfony 4.3 ввели метод assertSelectorTextContains(), чтобы помочь в этих ситуациях, но начиная с Symfony 4.4, вы также можете передать true в качестве второго необязательного аргумента text(), чтобы удалить все лишние пробелы:

// this passes because all extra white spaces are removed
$this->assertSame('Some Title Text', $crawler->filter('.class-1')->text(null, true));

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