Наскрізне тестування

Дата оновлення перекладу 2024-06-08

Наскрізне тестування

Компонент 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 також надає доступ до інших реалізацій Client та Crawler на основі BrowserKit.
На відміну від вбудованого клієнта 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([]); // load your fixtures
        $client = self::createPantherClient(); // create your panther client

        $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 може зробити паузу у ваших пакетах тестів після невдачі. Завдяки цій перерві ви можете дослідити проблему, що виникла, через веб-браузер. Щоб увімкнути цей режим, вам потрібна опція PHPUnit --debug без режиму headless:

1
2
3
4
5
6
$ PANTHER_NO_HEADLESS=1 bin/phpunit --debug

Test 'App\AdminTest::testLogin' started
Error: something is wrong.

Press enter to continue...

Для використання інтерактивного режиму необхідно зареєструвати
розширення 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 (optional)
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 geckod

Потім ви можете побудувати та запустити ваш образ:

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)
  • Вибір невалідних варіантів у виборі

Також існує відома проблема, якщо ви використовуєте Bootstrap 5. Він реалізує ефект прокрутки, який може ввести Panther в оману. Щоб виправити це, ми радимо вам вимкнути цей ефект, встановивши змінну Bootstrap 5 $enable-smooth-scroll у вашому файлі стилів у значення false:

1
$enable-smooth-scroll: false;

Додаткова документвція

Оскільки Panther реалізує API популярних бібліотек, ви можете знайти ще більше документації: