Сквозное тестирование
Дата обновления перевода 2024-07-29
Сквозное тестирование
Компонент Panther позволяет управлять реальным веб-браузером с помощью PHP для создания сквозных тестов.
Установка
1
$ composer require symfony/panther
Note
Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно
подключить файл vendor/autoload.php
в вашем коде для включения механизма
автозагрузки классов, предоставляемых Composer. Детальнее читайте в
этой статье.
Вступление
Сквозные тесты - это особый тип тестов приложения, которые имитируют взаимодействие реального пользователя с вашим приложением. Они обычно используются для тестирования пользовательского интерфейса (UI) вашего приложения и эффектов этих взаимодействий (например, когда я нажимаю на эту кнопку, должно быть отправлено письмо). Разница с функциональными тестами, описанными выше, заключается в том. что сквозные тесты используют реальный браузер, а не симуляцию. Этот браузер может работать как в режиме headless (без графического интерфейса), так и без него. Первый вариант удобен для запуска тестов в системе непрерывной интеграции (CI), а второй - для отладки.
Именно для этого предназначен Panther, компонент, который предоставляет настоящий браузер для выполнения ваших тестов. Вот несколько вещей, которые делают Panther особенной по сравнению с другими инструментами тестирования, предоставляемыми Symfony:
- Возможность делать скриншоты браузера в любое время во время тестирования.
- Выполнение JavaScript-кода, содержащегося на веб-страницах
- Panther поддерживает все, что реализовано в Chrome (или Firefox)
- Удобный способ тестирования приложений в реальном времени (например, WebSockets, Server-Sent Events с Mercure и т. д.)
Установка веб-драйверов
Panther использует протокол WebDriver для управления браузером, используемым для сканирования веб-сайтов. Во всех системах вы можете использовать dbrekelmans/browser-driver-installer, чтобы установить ChromeDriver и geckodriver локально:
1 2 3
$ composer require --dev dbrekelmans/bdi
$ vendor/bin/bdi detect drivers
Panther автоматически обнаружит и использует драйверы, хранящиеся в каталоге drivers/
.
вашего проекта при установке их вручную. Вы можете скачать ChromeDriver для Chromium
или Chrome и GeckoDriver для Firefox и поместить их в любое место в вашем PATH
или в каталоге drivers/
вашего проекта.
Также вы можете использовать менеджер пакетов вашей операционной системы для их установки:
1 2 3 4 5 6 7 8
# Ubuntu
$ apt-get install chromium-chromedriver firefox-geckodriver
# MacOS, используя Homebrew
$ brew install chromedriver geckodriver
# Windows, исползуя Chocolatey
$ choco install chromedriver selenium-gecko-driver
Регистрация расширения PHPUnit
Если вы собираетесь использовать Panther для тестирования вашего приложения, настоятельно рекомендуется зарегистрировать расширение Panther PHPUnit. Хотя это и не является строго обязательным, это расширение значительно улучшает качество тестирования, повышая производительность и позволяет использовать интерактивный режим отладки .
При использовании расширения в сочетании с переменной окружения PANTHER_ERROR_SCREENSHOT_DIR
,
тесты, использующие клиент Panther, которые терпят неудачу или ошибку (после
создания клиента), автоматически будет сделан снимок экрана для помощи в отладке.
Чтобы зарегистрировать расширение Panther, добавьте следующие строки в phpunit.xml.dist
:
1 2 3 4
<!-- phpunit.xml.dist -->
<extensions>
<extension class="Symfony\Component\Panther\ServerExtension"/>
</extensions>
Без этого расширения веб-сервер, используемый Panther для обслуживания тестируемого приложения,
запускается по требованию и останавливается при вызове tearDownAfterClass()
.
С другой стороны, если расширение зарегистрировано, веб-сервер будет остановлен
только после последнего теста.
Использование
Вот пример фрагмента, в котором Panther используется для тестирования приложения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use Symfony\Component\Panther\Client;
$client = Client::createChromeClient();
// в качестве альтернативы создайте клиент Firefox
$client = Client::createFirefoxClient();
$client->request('GET', 'https://api-platform.com');
$client->clickLink('Getting started');
// ожидать присутствия элемента в DOM, даже если он скрыт
$crawler = $client->waitFor('#installing-the-framework');
// вы также можете подождать, пока элемент станет видимым
$crawler = $client->waitForVisibility('#installing-the-framework');
// получить текст элемента благодаря синтаксису селектора запросов
echo $crawler->filter('#installing-the-framework')->text();
// сделать снимок экрана текущей страницы
$client->takeScreenshot('screen.png');
Note
Согласно спецификации, реализаций WebDriver по умолчанию возвращают только
отображаемый текст по умолчанию. При фильтрации по тегу head
(например,
title
), метод text()
возвращает пустую строку. Используйте
метод html()
для получения полного содержания тега, включая сам тег.
Создание TestCase
Класс PantherTestCase
позволяет писать сквозные тесты. Он
автоматически запускает ваше приложение с помощью встроенного веб-сервера PHP
и позволяет вам сканировать его с помощью Panther. Для обеспечения всех привычных
инструментов тестирования он расширяет TestCase
от PHPUnit.
Если вы тестируете приложение Symfony, PantherTestCase
автоматически
расширяет класс WebTestCase.
Это означает, что вы можете создавать функциональные тесты, которые могут напрямую выполнять
ядро вашего приложения и получать доступ ко всем существующим сервисам.
В этом случае вы можете использовать
все тестовые утверждения краулера ,
предоставляемые Symfony вместе с Panther.
Вот пример PantherTestCase
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class HomepageTest extends PantherTestCase
{
public function testMyApp(): void
{
// ваше приложение автоматически запускается с использованием встроенного веб-сервера
$client = static::createPantherClient();
$client->request('GET', '/home');
// использовать любое утверждение PHPUnit, включая те, которые предоставлены Symfony...
$this->assertPageTitleContains('My Title');
$this->assertSelectorTextContains('#main', 'My body');
// ... или предоставленное Panther
$this->assertSelectorIsEnabled('.search');
$this->assertSelectorIsDisabled('[type="submit"]');
$this->assertSelectorIsVisible('.errors');
$this->assertSelectorIsNotVisible('.loading');
$this->assertSelectorAttributeContains('.price', 'data-old-price', '42');
$this->assertSelectorAttributeNotContains('.price', 'data-old-price', '36');
// ...
}
}
Клиент Panther поставляется с методами, которые ждут, пока какой-либо асинхронный процесс завершается:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class HomepageTest extends PantherTestCase
{
public function testMyApp(): void
{
// ...
// подождать, чтобы элемент был прикреплен к DOM
$client->waitFor('.popin');
// подождать, чтобы элемент был удален из DOM
$client->waitForStaleness('.popin');
// подождать, чтобы элемент DOM стал видимым
$client->waitForVisibility('.loader');
// подождать, чтобы элемент DOM стал невидимым
$client->waitForInvisibility('.loader');
// подождать, чтобы текст был вставлен в содержание элемента
$client->waitForElementToContain('.total', '25 €');
// подождать, чтобы текст был удален из содержания элемента
$client->waitForElementToNotContain('.promotion', '5%');
// подождать, чтобы кнопка стала активной
$client->waitForEnabled('[type="submit"]');
// подождать, чтобы кнопка стала неактивной
$client->waitForDisabled('[type="submit"]');
// подождать, чтобы атрибут включал в себя содержание
$client->waitForAttributeToContain('.price', 'data-old-price', '25 €');
// подождать, чтобы атрибут не включал в себя содержание
$client->waitForAttributeToNotContain('.price', 'data-old-price', '25 €');
}
}
Наконец, вы также можете делать утверждения о вещах, которые произойдут в будущем:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class HomepageTest extends PantherTestCase
{
public function testMyApp(): void
{
// ...
// элемент будет прикреплен к DOM
$this->assertSelectorWillExist('.popin');
// элемент будет удален из DOM
$this->assertSelectorWillNotExist('.popin');
// элемент будет видимым
$this->assertSelectorWillBeVisible('.loader');
// элемент будет невидимым
$this->assertSelectorWillNotBeVisible('.loader');
// текст будет вставлен в содержание элемента
$this->assertSelectorWillContain('.total', '€25');
// текст будет удален из содержания элемента
$this->assertSelectorWillNotContain('.promotion', '5%');
// кнопка будет активной
$this->assertSelectorWillBeEnabled('[type="submit"]');
// кнопка будет неактивной
$this->assertSelectorWillBeDisabled('[type="submit"]');
// атрибут будет иметь содержание
$this->assertSelectorAttributeWillContain('.price', 'data-old-price', '€25');
// атрибут не будет иметь содержания
$this->assertSelectorAttributeWillNotContain('.price', 'data-old-price', '€25');
}
}
Затем вы можете запустить этот тест с помощью PHPUnit, как вы бы сделали это для любого другого теста:
1
$ ./vendor/bin/phpunit tests/HomepageTest.php
При написании сквозных тестов следует помнить, что они
медленнее, чем другие тесты. Если вам нужно проверить, что соединение WebDriver
остается активным во время длительного выполнения тестов, вы можете использовать
метод Client::ping()
, который возвращает булево число в зависимости от
статуса соединения.
Продвинутое использование
Изменение имени хоста и порта веб-сервера
Если вы хотите изменить хост и/или порт, используемые встроенным веб-сервером,
передайте hostname
и port
в параметр $options
метода
createPantherClient()
:
1 2 3 4
$client = self::createPantherClient([
'hostname' => 'example.com', // defaults to 127.0.0.1
'port' => 8080, // defaults to 9080
]);
Использование клиентов Browser-Kit
Panther также предоставляет доступ к другим реализациям на базе BrowserKit, таким как
Client
и Crawler
. В отличие от встроенного клиента Panther, эти альтернативные
клиенты не поддерживают JavaScript, CSS и захват скриншотов, но они намного
быстрее. Доступны два альтернативных клиента:
- Первый напрямую манипулирует ядром Symfony, предоставляемым
WebTestCase
. Это самый быстрый из доступных клиентов, но он доступен только для приложений Symfony. - Второй использует HttpBrowser.
Он является промежуточным звеном между ядром Symfony и тестовыми клиентами Panther.
HttpBrowser
отправляет реальные HTTP-запросы, используя компонент HttpClient. Он работает быстро и способен просматривать любые веб-страницы, а не только те, что принадлежат тестируемому приложению. Однако HttpBrowser не поддерживает JavaScript и другие дополнительные функции, потому что он полностью написан на PHP. Его можно использовать в любом PHP приложении.
Поскольку все клиенты реализуют один и тот же API, вы можете переключаться с одного на другой просто вызвав соответствующий метод фабрики, в результате чего получается хороший компромисс для каждого отдельного случая тестирования: нужен ли JavaScript, нужна ли аутентификация по внешнему SSO и т. д.
Вот как получить экземпляры этих клиентов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
namespace App\Tests;
use Symfony\Component\Panther\Client;
use Symfony\Component\Panther\PantherTestCase;
class AppTest extends PantherTestCase
{
public function testMyApp(): void
{
// извлечь существующего клиента
$symfonyClient = static::createClient();
$httpBrowserClient = static::createHttpBrowserClient();
$pantherClient = static::createPantherClient();
$firefoxClient = static::createPantherClient(['browser' => static::FIREFOX]);
// создать пользовательского клиента
$customChromeClient = Client::createChromeClient(null, null, [], 'https://example.com');
$customFirefoxClient = Client::createFirefoxClient(null, null, [], 'https://example.com');
$customSeleniumClient = Client::createSeleniumClient('http://127.0.0.1:4444/wd/hub', null, 'https://example.com');
// если вы тестируете приложение Symfony, вы также имеете доступ к ядру
$kernel = static::createKernel();
// ...
}
}
Note
При инициализации пользовательского клиента интегрированный веб-сервер не запускается
автоматически. Используйте PantherTestCase::startWebServer()
или класс WebServerManager
,
если вы хотите запустить его вручную.
Тестирование приложений в реальном времени
Panther предоставляет удобный способ тестирования приложений с возможностями реального времени, которые используют Mercure, WebSocket и похожие технологии.
Метод PantherTestCase::createAdditionalPantherClient()
позволяет создать
дополнительные, изолированные браузеры, которые могут взаимодействовать с другими браузерами. Например,
это может быть полезно для тестирования чат-приложения с несколькими пользователями,
подключенными одновременно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
use Symfony\Component\Panther\PantherTestCase;
class ChatTest extends PantherTestCase
{
public function testChat(): void
{
$client1 = self::createPantherClient();
$client1->request('GET', '/chat');
// подсоединить 2го пользователя, используя изолированный браузер
$client2 = self::createAdditionalPantherClient();
$client2->request('GET', '/chat');
$client2->submitForm('Post message', ['message' => 'Hi folks !']);
// подождать, чтобы сообщение было получено первым клиентом
$client1->waitFor('.message');
// Утверждения Symfony *всегда* выполняются в основном браузере
$this->assertSelectorTextContains('.message', 'Hi folks !');
}
}
Доступ к логам консоли браузера
При необходимости вы можете использовать Panther для доступа к содержанию консоли:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
use Symfony\Component\Panther\PantherTestCase;
class ConsoleTest extends PantherTestCase
{
public function testConsole(): void
{
$client = self::createPantherClient(
[],
[],
[
'capabilities' => [
'goog:loggingPrefs' => [
'browser' => 'ALL', // вызов к методам console.*
'performance' => 'ALL', // данные производительности
],
],
]
);
$client->request('GET', '/');
$consoleLogs = $client->getWebDriver()->manage()->getLog('browser');
$performanceLogs = $client->getWebDriver()->manage()->getLog('performance'); // performance logs
}
}
Передача аргументов в ChromeDriver
При необходимости вы можете сконфгиурировать аргументы для передачи бинарному файлу chromedriver
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
use Symfony\Component\Panther\PantherTestCase;
class MyTest extends PantherTestCase
{
public function testLogging(): void
{
$client = self::createPantherClient(
[],
[],
[
'chromedriver_arguments' => [
'--log-path=myfile.log',
'--log-level=DEBUG'
],
]
);
$client->request('GET', '/');
}
}
Использование прокси
Чтобы использовать прокси-сервер, необходимо установить PANTHER_CHROME_ARGUMENTS
:
1 2
# .env.test
PANTHER_CHROME_ARGUMENTS='--proxy-server=socks://127.0.0.1:9050'
Принятие самоподписанных сертификатов SSL
Чтобы заставить Chrome принимать невалидные и самоподписанные сертификаты, вы можете установить
следующую переменную окружения: PANTHER_CHROME_ARGUMENTS='--ignore-certificate-errors'
.
Caution
Эта опция небезопасна, используйте ее только для тестирования в окружениях разработки, никогда в производстве (например, для веб-краулеров).
Для Firefox инстанцируйте клиент следующим образом, это можно сделать при создании клиента:
1
$client = Client::createFirefoxClient(null, null, ['capabilities' => ['acceptInsecureCerts' => true]]);
Использование внешнего веб-сервера
Бывает удобно использовать существующую конфигурацию веб-сервера
вместо того, чтобы запускать встроенную конфигурацию PHP. Для этого установите опцию
external_base_uri
при создании клиента:
1 2 3 4 5 6 7 8 9 10 11 12 13
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class E2eTest extends PantherTestCase
{
public function testMyApp(): void
{
$pantherClient = static::createPantherClient(['external_base_uri' => 'https://localhost']);
// ...
}
}
Note
При использовании внешнего веб-сервера Panther не будет запускать встроенный PHP веб-сервер.
Приложение с несколькими доменами
Бывает так, что ваше приложение на PHP/Symfony может обслуживать несколько различных доменных имен. Поскольку Panther сохраняет клиента в памяти между тестами для повышения производительности, вам придется запускать свои тесты в отдельных процесах, если вы пишете несколько тестов с использованием Panther для разных доменных имен.
Для этого вы можете использовать встроенную аннотацию PHPUnit @runInSeparateProcess
.
Вот пример использования опции external_base_uri
для определения
доменного имени, используемого клиентом при использовании отдельных процессов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
// tests/FirstDomainTest.php
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class FirstDomainTest extends PantherTestCase
{
/**
* @runInSeparateProcess
*/
public function testMyApp(): void
{
$pantherClient = static::createPantherClient([
'external_base_uri' => 'http://mydomain.localhost:8000',
]);
// ...
}
}
// tests/SecondDomainTest.php
namespace App\Tests;
use Symfony\Component\Panther\PantherTestCase;
class SecondDomainTest extends PantherTestCase
{
/**
* @runInSeparateProcess
*/
public function testMyApp(): void
{
$pantherClient = static::createPantherClient([
'external_base_uri' => 'http://anotherdomain.localhost:8000',
]);
// ...
}
}
Использование с другими инструментами тестирования
Если вы хотите использовать Panther с другими инструментами тестирования, такими как LiipFunctionalTestBundle.
или если вам просто нужно использовать другой базовый класс, вы можете использовать
Symfony\Component\Panther\PantherTestCaseTrait
для расширения существующей
тестовой инфраструктуры с некоторыми механизмами Panther:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
namespace App\Tests\Controller;
use Liip\FunctionalTestBundle\Test\WebTestCase;
use Symfony\Component\Panther\PantherTestCaseTrait;
class DefaultControllerTest extends WebTestCase
{
use PantherTestCaseTrait;
public function testWithFixtures(): void
{
$this->loadFixtures([]); // загрузить ваши фикстуры
$client = self::createPantherClient(); // создать вашего клиента panther
$client->request('GET', '/');
// ...
}
}
Конфигурирование Panther через переменные окружения
Следующие переменные окружения могут быть установлены для изменения некоторого поведения Panther:
PANTHER_NO_HEADLESS
- Отключить headless-режим браузера (будет отображаться окно тестирования, полезное для отладки)
PANTHER_WEB_SERVER_DIR
-
Изменить корень документа проекта (по умолчанию
./public/
, относительные пути должны начинаться с./
) PANTHER_WEB_SERVER_PORT
-
Изменить порт веб-сервера (по умолчанию
9080
) PANTHER_WEB_SERVER_ROUTER
- Использовать скрипт маршрутизатора веб-сервера, который запускается в начале каждого HTTP-запроса
PANTHER_EXTERNAL_BASE_URI
- Использовать внешний веб-сервер (встроенный в PHP веб-сервер не будет запущен)
PANTHER_APP_ENV
-
Переопределить переменную
APP_ENV
, передаваемую веб-серверу, на котором запущено приложение PHP PANTHER_ERROR_SCREENSHOT_DIR
-
Установить базовый каталог для скриншотов неудач/ошибок (например,
./var/error-screenshots
) PANTHER_DEVTOOLS
-
Переключать инструменты разработчика браузера (по умолчанию
enabled
, полезно для отладки) PANTHER_ERROR_SCREENSHOT_ATTACH
- Добавить скриншоты, упомянутые выше, в тестовый вывод в формате приложения junit
Переменные окружения, специфические для Chrome
PANTHER_NO_SANDBOX
- Отключить песочницу Chrome (небезопасно, но позволяет использовать Panther в контейнерах)
PANTHER_CHROME_ARGUMENTS
-
Настройте аргументы Chrome. Для полной настройки необходимо установить
PANTHER_NO_HEADLESS
PANTHER_CHROME_BINARY
-
Чтобы использовать другую бинарность
google-chrome
Переменные окружения, специфические для Firefox
PANTHER_FIREFOX_ARGUMENTS
-
Настроить аргументы Firefox. Вам необходимо установить
PANTHER_NO_HEADLESS
, чтобы настроить полностью PANTHER_FIREFOX_BINARY
-
Чтобы использовать другую бинарность
firefox
Интерактивный режим
Panther может сделать паузу в ваших наборах тестов после ошибки.
Благодаря этой паузе вы можете исследовать возникшую проблему через веб-браузер. Чтобы
включить этот режим, вам понадобится опция --debug
PHPUnit без режима headless:
1 2 3 4 5 6
$ PANTHER_NO_HEADLESS=1 bin/phpunit --debug
Test 'App\AdminTest::testLogin' started
Error: something is wrong.
Нажмите ввод, чтобы продолжить...
Чтобы использовать интерактивный режим, необходимо зарегистрировать расширение PHPUnit .
Интеграция Docker
Вот минимальный образ Docker, который позволяет запускать Panther с Chrome и Firefox:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
FROM php:alpine
# Chromium и ChromeDriver
ENV PANTHER_NO_SANDBOX 1
# Не обязательно, но рекомендовано
ENV PANTHER_CHROME_ARGUMENTS='--disable-dev-shm-usage'
RUN apk add --no-cache chromium chromium-chromedriver
# Firefox и GeckoDriver (опционально)
ARG GECKODRIVER_VERSION=0.28.0
RUN apk add --no-cache firefox libzip-dev; \
docker-php-ext-install zip
RUN wget -q https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER_VERSION/geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz; \
tar -zxf geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz -C /usr/bin; \
rm geckodriver-v$GECKODRIVER_VERSION-linux64.tar.gz
Затем вы можете создать и запустить свой образ:
1 2
$ docker build . -t myproject
$ docker run -it -v "$PWD":/srv/myproject -w /srv/myproject myproject bin/phpunit
Интегрирование Panther в вашем CI
Действия Github
Panther работает сразу после установки с Действиями GitHub.
Вот минимальный файл .github/workflows/panther.yaml
для запуска тестов Panther:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
name: Run Panther tests
on: [ push, pull_request ]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: "ramsey/composer-install@v2"
- name: Install dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Run test suite
run: bin/phpunit
Travis CI
Panther будет работать с `Travis CI` сразу после установки, если вы добавите аддон Chrome.
Вот минимальный файл .travis.yaml
для запуска тестов Panther:
1 2 3 4 5 6 7 8 9 10 11
language: php
addons:
# Если вы не используете Chrome или Firefox, удалите соответствующую строку
chrome: stable
firefox: latest
php:
- 8.0
script:
- bin/phpunit
Gitlab CI
Вот минимальный файл .gitlab-ci.yaml
для запуска тестов Panther
с помощью Gitlab CI
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
image: ubuntu
before_script:
- apt-get update
- apt-get install software-properties-common -y
- ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime
- apt-get install curl wget php php-cli php8.1 php8.1-common php8.1-curl php8.1-intl php8.1-xml php8.1-opcache php8.1-mbstring php8.1-zip libfontconfig1 fontconfig libxrender-dev libfreetype6 libxrender1 zlib1g-dev xvfb chromium-chromedriver firefox-geckodriver -y -qq
- export PANTHER_NO_SANDBOX=1
- export PANTHER_WEB_SERVER_PORT=9080
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php --install-dir=/usr/local/bin --filename=composer
- php -r "unlink('composer-setup.php');"
- composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
test:
script:
- bin/phpunit
AppVeyor
Panther будет работать сразу после установки с AppVeyor при условии, что установлен
Google Chrome. Вот минимальный файл appveyor.yaml
для запуска тестов Panther:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
build: false
platform: x86
clone_folder: c:\projects\myproject
cache:
- '%LOCALAPPDATA%\Composer\files'
install:
- ps: Set-Service wuauserv -StartupType Manual
- cinst -y php composer googlechrome chromedriver firfox selenium-gecko-driver
- refreshenv
- cd c:\tools\php80
- copy php.ini-production php.ini /Y
- echo date.timezone="UTC" >> php.ini
- echo extension_dir=ext >> php.ini
- echo extension=php_openssl.dll >> php.ini
- echo extension=php_mbstring.dll >> php.ini
- echo extension=php_curl.dll >> php.ini
- echo memory_limit=3G >> php.ini
- cd %APPVEYOR_BUILD_FOLDER%
- composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
test_script:
- cd %APPVEYOR_BUILD_FOLDER%
- php bin\phpunit
Известные ограничения и устранение неполадок
В настоящее время не поддерживаются следующие функции:
- Сканирование XML-документов (поддерживается только HTML)
- Обновление существующих документов (браузеры в основном используются для потребления данных, а не для создания веб-страниц)
- Установка значений формы с использованием синтаксиса многомерных массивов PHP
- Методы, возвращающие экземпляр
\DOMElement
(потому что эта библиотека внутренне используетWebDriverElement
) - Выбор невалидных вариантов в select
Также известна проблема, если вы используете Bootstrap 5. В нем реализован
эффект прокрутки, который может вводить Panther в заблуждение. Чтобы решить эту проблему, мы советуем вам
отключить этот эффект, установив переменную Bootstrap 5 $enable-smooth-scroll
как false
в вашем файле стилей:
1
$enable-smooth-scroll: false;
Дополнительная документация
Поскольку Panther реализует API популярных библиотек, вы можете найти еще больше документации:
- Для класса
Client
, прочтите страницу компонент BrowserKit - Для класса
Crawler
, прочтите страницу компонент DomCrawler - Для WebDriver, прочтите `документацию PHP WebDriver`.