Версія фреймворка: 8.x

Dusk Laravel

Вступ

Laravel Dusk забезпечує виразний, простий у використанні API автоматизації та тестування браузера. За замовчуванням Dusk не вимагає встановлення JDK або Selenium на вашому комп'ютері. Натомість Dusk використовує автономнийChromeDriverвстановлення. Однак ви можете використовувати будь-який інший драйвер, сумісний із Selenium, який хочете.

Встановлення

Для початку слід додатиlaravel/duskЗалежність composer від вашого проекту:

composer require --dev laravel/dusk
Якщо ви реєструєте постачальника послуг Dusk вручну, вам слідніколизареєструйте його у своєму виробничому середовищі, оскільки це може призвести до того, що довільні користувачі зможуть пройти автентифікацію у вашій програмі.

Після встановлення пакунка Dusk запустітьdusk:installКоманда ремісників:

php artisan dusk:install

ABrowserкаталог буде створений у вашомуtestsкаталог і міститиме приклад тесту. Далі встановітьAPP_URLзмінної середовища у вашому.envфайл. Це значення має відповідати URL-адресі, яку ви використовуєте для доступу до своєї програми у браузері.

Для запуску тестів використовуйтеduskartisan командування.duskкоманда приймає будь-який аргумент, який також приймаєphpunitкоманда:

php artisan dusk

Якщо у вас були збої в тесті під час останнього запускуduskВи можете заощадити час, повторно запустивши невдалі тести, спочатку використовуючиdusk:failsкоманда:

php artisan dusk:fails

Керування встановленнями ChromeDriver

Якщо ви хочете встановити іншу версію ChromeDriver, відмінну від тієї, що входить до Laravel Dusk, ви можете використовуватиdusk:chrome-driverкоманда:

# Install the latest version of ChromeDriver for your OS...
php artisan dusk:chrome-driver

# Install a given version of ChromeDriver for your OS...
php artisan dusk:chrome-driver 86

# Install a given version of ChromeDriver for all supported OSs...
php artisan dusk:chrome-driver --all

# Install the version of ChromeDriver that matches the detected version of Chrome / Chromium for your OS...
php artisan dusk:chrome-driver --detect
Dusk вимагаютьchromedriverдвійкові файли для виконання. Якщо у вас виникли проблеми із запуском «Сутінків», слід переконатися, що двійкові файли виконуються за допомогою наступної команди:chmod -R 0755 vendor/laravel/dusk/bin/.

Використання інших браузерів

За замовчуванням Dusk використовує Google Chrome і автономнийChromeDriverвстановлення для запуску тестів браузера. Тим не менш, ви можете запустити власний сервер Selenium і запустити тести на будь-який браузер, який хочете.

Для початку відкрийтеtests/DuskTestCase.phpфайл, який є базовим тестовим кейсом для Вашої програми. У цьому файлі ви можете видалити виклик доstartChromeDriverметод. Це зупинить Dusk від автоматичного запуску ChromeDriver:

/**
 * Prepare for Dusk test execution.
 *
 * @beforeClass
 * @return void
 */
public static function prepare()
{
    // static::startChromeDriver();
}

Далі ви можете змінитиdriverспосіб підключення до обраної вами URL-адреси та порту. Крім того, ви можете змінити "бажані можливості", які повинні передаватися WebDriver:

/**
 * Create the RemoteWebDriver instance.
 *
 * @return \Facebook\WebDriver\Remote\RemoteWebDriver
 */
protected function driver()
{
    return RemoteWebDriver::create(
        'http://localhost:4444/wd/hub', DesiredCapabilities::phantomjs()
    );
}

Починаємо

Створення тестів

Щоб створити тест "Dusk", використовуйтеdusk:makeartisan командування. Створений тест буде розміщено вtests/Browserкаталог:

php artisan dusk:make LoginTest

Запуск тести

Для запуску тестів браузера використовуйтеduskКоманда ремісників:

php artisan dusk

Якщо у вас були збої в тесті під час останнього запускуduskВи можете заощадити час, повторно виконавши невдалі тести спочатку за допомогоюdusk:failsкоманда:

php artisan dusk:fails

duskкоманда приймає будь-який аргумент, який зазвичай приймається тестовим запуском PHPUnit, дозволяючи запускати тести лише для даногогрупи, тощо:

php artisan dusk --group=foo

Запуск ChromeDriver вручну

За замовчуванням Dusk автоматично спробує запустити ChromeDriver. Якщо це не працює для вашої конкретної системи, ви можете вручну запустити ChromeDriver перед запускомduskкоманди. Якщо ви вирішили запустити ChromeDriver вручну, вам слід прокоментувати наступний рядок вашогоtests/DuskTestCase.phpфайл:

/**
 * Prepare for Dusk test execution.
 *
 * @beforeClass
 * @return void
 */
public static function prepare()
{
    // static::startChromeDriver();
}

Крім того, якщо ви запускаєте ChromeDriver з порту, відмінного від 9515, вам слід змінитиdriverметод того ж класу:

/**
 * Create the RemoteWebDriver instance.
 *
 * @return \Facebook\WebDriver\Remote\RemoteWebDriver
 */
protected function driver()
{
    return RemoteWebDriver::create(
        'http://localhost:9515', DesiredCapabilities::chrome()
    );
}

Поводження з Environment

Щоб змусити Dusk використовувати власний файл середовища під час запуску тестів, створіть файл.env.dusk.{environment}файл у кореневій частині вашого проекту. Наприклад, якщо ви ініціюєтеduskкоманда від вашогоlocalEnvironment, вам слід створити a.env.dusk.localфайл.

Під час запуску тестів Dusk зробить резервну копію вашого.envфайл і перейменуйте ваше середовище Dusk на.env. Після завершення тестів ваш.envфайл буде відновлено.

Створення браузерів

Для початку давайте напишемо тест, який підтверджує, що ми можемо увійти в наш додаток. Після створення тесту ми можемо змінити його, щоб перейти на сторінку входу, ввести деякі облікові дані та натиснути кнопку «Вхід». Щоб створити екземпляр браузера, зателефонуйте доbrowseметод:

<?php

namespace Tests\Browser;

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;

    /**
     * A basic browser test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $user = User::factory()->create([
            'email' => 'taylor@laravel.com',
        ]);

        $this->browse(function ($browser) use ($user) {
            $browser->visit('/login')
                    ->type('email', $user->email)
                    ->type('password', 'password')
                    ->press('Login')
                    ->assertPathIs('/home');
        });
    }
}

Як ви можете бачити на прикладі вище, файлbrowseметод приймає зворотний дзвінок. Екземпляр браузера автоматично передається цьому зворотному виклику з боку Сутінків і є основним об’єктом, що використовується для взаємодії та твердження щодо вашої програми.

Створення декількох браузерів

Іноді вам може знадобитися кілька браузерів, щоб правильно провести тест. Наприклад, для перевірки екрана чату, який взаємодіє з веб-сокетами, може знадобитися кілька браузерів. Щоб створити декілька браузерів, "запитуйте" більше одного браузера в підписі зворотного дзвінка, наданомуbrowseметод:

$this->browse(function ($first, $second) {
    $first->loginAs(User::find(1))
          ->visit('/home')
          ->waitForText('Message');

    $second->loginAs(User::find(2))
           ->visit('/home')
           ->waitForText('Message')
           ->type('message', 'Hey Taylor')
           ->press('Send');

    $first->waitForText('Hey Taylor')
          ->assertSee('Jeffrey Way');
});

Зміна розміру браузера Windows

Ви можете використовуватиresizeспосіб регулювання розміру вікна браузера:

$browser->resize(1920, 1080);

maximizeметод може бути використаний для максимізації вікна браузера:

$browser->maximize();

fitContentметод змінить розмір вікна браузера відповідно до розміру вмісту:

$browser->fitContent();

Коли тест не вдається, Dusk автоматично змінює розмір браузера відповідно до вмісту, перш ніж робити знімок екрана. Ви можете вимкнути цю функцію, зателефонувавши доdisableFitOnFailureметод у вашому тесті:

$browser->disableFitOnFailure();

Ви можете використовуватиmoveспосіб переміщення вікна браузера в інше місце на екрані:

$browser->move(100, 100);

Макроси браузера

Якщо ви хочете визначити власний метод браузера, який ви зможете повторно використовувати в різних своїх тестах, ви можете використовуватиmacroметод наBrowserклас. Як правило, вам слід викликати цей метод ізпостачальника послугbootметод:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Browser;

class DuskServiceProvider extends ServiceProvider
{
    /**
     * Register the Dusk's browser macros.
     *
     * @return void
     */
    public function boot()
    {
        Browser::macro('scrollToElement', function ($element = null) {
            $this->script("$('html, body').animate({ scrollTop: $('$element').offset().top }, 0);");

            return $this;
        });
    }
}

macroФункція приймає ім'я як перший аргумент, а Закриття - як другий аргумент. Закриття макросу буде виконано під час виклику макросу як методу наBrowserреалізація:

$this->browse(function ($browser) use ($user) {
    $browser->visit('/pay')
            ->scrollToElement('#credit-card-details')
            ->assertSee('Enter Credit Card Details');
});

Аутентифікація

Часто ви будете тестувати сторінки, які потребують автентифікації. Ви можете використовувати DuskloginAsметод, щоб уникнути взаємодії з екраном входу під час кожного тесту.loginAsметод приймає ідентифікатор користувача або примірник моделі користувача:

$this->browse(function ($first, $second) {
    $first->loginAs(User::find(1))
          ->visit('/home');
});
Після використанняloginAsметод, сеанс користувача буде підтримуватися для всіх тестів у файлі.

Міграції баз даних

Коли ваш тест вимагає міграції, як, наприклад, приклад автентифікації вище, ви ніколи не повинні використовуватиRefreshDatabaseриса. ЧайRefreshDatabasetrait використовує транзакції бази даних, які не застосовуватимуться до запитів HTTP. Натомість використовуйтеDatabaseMigrationsриса:

<?php

namespace Tests\Browser;

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;
}
Бази даних SQLite в пам’яті не можна використовувати під час виконання Dusk-тестів. Оскільки браузер виконується в рамках власного процесу, він не зможе отримати доступ до баз даних інших процесів у пам'яті.

Cookies

Ви можете використовуватиcookieспосіб отримати або встановити значення зашифрованого файлу cookie:

$browser->cookie('name');

$browser->cookie('name', 'Taylor');

Ви можете використовуватиplainCookieспосіб отримати або встановити значення незашифрованого файлу cookie:

$browser->plainCookie('name');

$browser->plainCookie('name', 'Taylor');

Ви можете використовуватиdeleteCookieспосіб видалення даного файлу cookie:

$browser->deleteCookie('name');

Знімок екрана

Ви можете використовуватиscreenshotметод зробити знімок екрана та зберегти його із вказаною назвою файлу. Всі знімки екрана зберігатимуться вtests/Browser/screenshotsкаталог:

$browser->screenshot('filename');

Зберігання виводу консолі на диск

Ви можете використовуватиstoreConsoleLogметод запису виводу консолі на диск із заданою назвою файлу. Висновок консолі зберігатиметься вtests/Browser/consoleкаталог:

$browser->storeConsoleLog('filename');

Зберігання Source сторінки на диску

Ви можете використовуватиstoreSourceметод записати поточне джерело сторінки на диск із вказаною назвою файлу. Джерело сторінки буде зберігатися вtests/Browser/sourceкаталог:

$browser->storeSource('filename');

Взаємодія з елементами

Dusk селектори

Вибір хороших селекторів CSS для взаємодії з елементами є однією з найскладніших частин написання тестів Dusk. З часом зміни інтерфейсу можуть змусити селектори CSS, як показано нижче, порушити ваші тести:

// HTML...

<button>Login</button>

// Test...

$browser->click('.login-page .container div > button');

Dusk селектори дозволяють зосередитись на написанні ефективних тестів, а не запам'ятовуванні селекторів CSS. Щоб визначити селектор, додайте aduskатрибут для вашого елемента HTML. Потім префіксуйте селектор префіксом@для маніпулювання прикріпленим елементом в рамках тесту Dusk:

// HTML...

<button dusk="login-button">Login</button>

// Test...

$browser->click('@login-button');

Натискання посилання

Щоб натиснути посилання, ви можете використовуватиclickLinkв екземплярі браузера.clickLinkметод клацне посилання, що містить вказаний текст відображення:

$browser->clickLink($linkText);

Ви можете використовуватиseeLinkметод, щоб визначити, чи на сторінці видно посилання, що містить вказаний текст відображення:

if ($browser->seeLink($linkText)) {
    // ...
}
Ці методи взаємодіють з jQuery. Якщо jQuery недоступний на сторінці, Dusk автоматично вводить його на сторінку, щоб він був доступний протягом тривалості тесту.

Текст, значення та атрибути

Отримання та встановлення значень

Dusk надають кілька методів взаємодії з поточним відображуваним текстом, значенням та атрибутами елементів на сторінці. Наприклад, щоб отримати "значення" елемента, який відповідає даному селектору, використовуйтеvalueметод:

// Retrieve the value...
$value = $browser->value('selector');

// Set the value...
$browser->value('selector', 'value');

Ви можете використовуватиinputValueспосіб отримати "значення" вхідного елемента, який має задане ім'я поля:

// Retrieve the value of an input element...
$inputValue = $browser->inputValue('field');

Отримання тексту

textметод може бути використаний для отримання відображуваного тексту елемента, який відповідає заданому селектору:

$text = $browser->text('selector');

Отримання атрибутів

Нарешті,attributeметод може бути використаний для отримання атрибута елемента, що відповідає даному селектору:

$attribute = $browser->attribute('selector', 'value');

Використання форм

Введення значень

Dusk надають різноманітні методи взаємодії з формами та елементами введення. Спочатку розглянемо приклад введення тексту в поле введення:

$browser->type('email', 'taylor@laravel.com');

Зауважте, що, хоча метод і приймає такий, якщо це необхідно, нам не потрібно передавати селектор CSS вtypeметод. Якщо селектор CSS не передбачений, Dusk шукатимуть поле введення із заданимnameатрибут. Нарешті, Dusk спробують знайтиtextareaз данимnameатрибут.

Щоб додати текст до поля, не очищаючи його вміст, ви можете використовуватиappendметод:

$browser->type('tags', 'foo')
        ->append('tags', ', bar, baz');

Ви можете очистити значення введення за допомогоюclearметод:

$browser->clear('email');

Ви можете доручити Даску повільно набирати текст за допомогоюtypeSlowlyметод. За замовчуванням Dusk робить паузу на 100 мілісекунд між натисканнями клавіш. Щоб налаштувати проміжок часу між натисканнями клавіш, ви можете передати відповідну кількість мілісекунд як третій аргумент методу:

$browser->typeSlowly('mobile', '+1 (202) 555-5555');

$browser->typeSlowly('mobile', '+1 (202) 555-5555', 300);

Ви можете використовуватиappendSlowlyметод повільного додавання тексту:

$browser->type('tags', 'foo')
        ->appendSlowly('tags', ', bar, baz');

Випадаючі меню

Щоб вибрати значення у випадаючому вікні вибору, ви можете використовуватиselectметод. Подобаєтьсяtypeметод,selectметод не вимагає повного селектора CSS. При передачі значення вselectметоду, вам слід передати базове значення параметра замість відображуваного тексту:

$browser->select('size', 'Large');

Ви можете вибрати випадковий варіант, опустивши другий параметр:

$browser->select('size');

Прапорці

Щоб "позначити" поле прапорця, ви можете використовуватиcheckметод. Як і багато інших методів, пов'язаних із введенням, повний селектор CSS не потрібен. Якщо точної відповідності селектора не вдається знайти, Dusk знайдуть прапорець із відповідністюnameатрибут:

$browser->check('terms');

$browser->uncheck('terms');

Кнопки радіо

Щоб "вибрати" опцію перемикача, ви можете використовуватиradioметод. Як і багато інших методів, пов'язаних із введенням, повний селектор CSS не потрібен. Якщо не вдається знайти точну відповідність селектора, Dusk шукатимуть радіо з відповіднимиnameіvalueатрибути:

$browser->radio('version', 'php8');

Вкладання файлів

attachметод може бути використаний для вкладання файлу в файлfileвхідний елемент. Як і багато інших методів, пов'язаних із введенням, повний селектор CSS не потрібен. Якщо не вдається знайти точну відповідність селектора, Dusk шукатимуть файл, що відповідаєnameатрибут:

$browser->attach('photo', __DIR__.'/photos/me.png');
Функція приєднання вимагаєZipРозширення PHP, яке буде встановлено та увімкнено на вашому сервері.

Using The Keyboard

keysМетод дозволяє надати більш складні вхідні послідовності для даного елемента, ніж зазвичай дозволяєтьсяtypeметод. Наприклад, ви можете тримати модифікаційні клавіші, що вводять значення. У цьому прикладіshiftключ буде утримуватися в той час, якtaylorвводиться в елемент, що відповідає даному селектору. Післяtaylorнабирається,otwellбуде введено без будь-яких модифікаційних клавіш:

$browser->keys('selector', ['{shift}', 'taylor'], 'otwell');

Ви навіть можете надіслати "гарячу клавішу" до основного селектора CSS, що містить вашу програму:

$browser->keys('.app', ['{command}', 'j']);
Усі клавіші-модифікатори загорнуті{}символів і відповідають константам, визначеним уFacebook\WebDriver\WebDriverKeysклас, який може бутизнайдено на GitHub.

Використання миші

Клацання на елементах

clickметод може бути використаний для "клацання" на елементі, що відповідає даному селектору:

$browser->click('.selector');

clickAtXPathметод може бути використаний для "клацання" на елементі, що відповідає даному виразу XPath:

$browser->clickAtXPath('//div[@class = "selector"]');

clickAtPointметод може бути використаний для "клацання" на самому верхньому елементі за заданою Vapor координат щодо видимої області браузера:

$browser->clickAtPoint(0, 0);

doubleClickметод може бути використаний для імітації подвійного "клацання" миші:

$browser->doubleClick();

rightClickметод може бути використаний для імітації клацання правою кнопкою миші:

$browser->rightClick();

$browser->rightClick('.selector');

clickAndHoldметод може бути використаний для імітації натискання та утримування кнопки миші. Подальший дзвінок доreleaseMouseметод скасує таку поведінку та відпустить кнопку миші:

$browser->clickAndHold()
        ->pause(1000)
        ->releaseMouse();

Наведення миші

mouseoverметод може бути використаний, коли вам потрібно навести мишу на елемент, що відповідає даному селектору:

$browser->mouseover('.selector');

Перетягування

The dragметод може бути використаний для перетягування елемента, що відповідає даному селектору, до іншого елемента:

$browser->drag('.from-selector', '.to-selector');

Або ви можете перетягнути елемент в одному напрямку:

$browser->dragLeft('.selector', 10);
$browser->dragRight('.selector', 10);
$browser->dragUp('.selector', 10);
$browser->dragDown('.selector', 10);

Нарешті, ви можете перетягнути елемент на заданий зсув:

$browser->dragOffset('.selector', 10, 10);

Діалоги JavaScript

Dusk надають різні методи взаємодії з діалоговими вікнами JavaScript:

// Wait for a dialog to appear:
$browser->waitForDialog($seconds = null);

// Assert that a dialog has been displayed and that its message matches the given value:
$browser->assertDialogOpened('value');

// Type the given value in an open JavaScript prompt dialog:
$browser->typeInDialog('Hello World');

Щоб закрити відкрите діалогове вікно JavaScript, натисніть кнопку OK:

$browser->acceptDialog();

Щоб закрити відкрите діалогове вікно JavaScript, натисніть кнопку Скасувати (лише для діалогового вікна підтвердження):

$browser->dismissDialog();

Селектори масштабування

Іноді вам може знадобитися виконати кілька операцій, одночасно визначаючи обсяг усіх операцій у межах даного селектора. Наприклад, ви можете запевнити, що якийсь текст існує лише в таблиці, а потім натиснути кнопку в цій таблиці. Ви можете використовуватиwithметод досягнення цього. Всі операції, що виконуються в рамках зворотного виклику, наданогоwithметод буде обмежений до початкового селектора:

$browser->with('.table', function ($table) {
    $table->assertSee('Hello World')
          ->clickLink('Delete');
});

Можливо, вам іноді доведеться виконувати твердження поза поточною сферою. Ви можете використовуватиelsewhereметод для досягнення цього:

 $browser->with('.table', function ($table) {
    // Current scope is `body .table`...
    $browser->elsewhere('.page-title', function ($title) {
        // Current scope is `body .page-title`...
        $title->assertSee('Hello World');
    });
 });

Очікування елементів

При тестуванні додатків, які широко використовують JavaScript, часто виникає необхідність "почекати", поки певні елементи або дані стануть доступними, перш ніж продовжувати тест. Dusk роблять це важким явищем. Використовуючи різні методи, ви можете зачекати, поки елементи будуть видимими на сторінці, або навіть почекати, поки даний вираз JavaScript отримає значенняtrue.

Чекаю

Якщо вам потрібно призупинити тест на задану кількість мілісекунд, використовуйтеpauseметод:

$browser->pause(1000);

Очікування селекторів

waitForметод може бути використаний для призупинення виконання тесту, поки елемент, що відповідає даному селектору CSS, не відображається на сторінці. За замовчуванням це призупиняє тест максимум на п’ять секунд, перш ніж створювати виняток. За необхідності ви можете передати спеціальний поріг очікування як другий аргумент методу:

// Wait a maximum of five seconds for the selector...
$browser->waitFor('.selector');

// Wait a maximum of one second for the selector...
$browser->waitFor('.selector', 1);

Ви також можете почекати, поки селектор не містить заданий текст:

// Wait a maximum of five seconds for the selector to contain the given text...
$browser->waitForTextIn('.selector', 'Hello World');

// Wait a maximum of one second for the selector to contain the given text...
$browser->waitForTextIn('.selector', 'Hello World', 1);

Ви також можете почекати, поки вказаний селектор не буде відсутній на сторінці:

// Wait a maximum of five seconds until the selector is missing...
$browser->waitUntilMissing('.selector');

// Wait a maximum of one second until the selector is missing...
$browser->waitUntilMissing('.selector', 1);

Селектори масштабування, коли вони доступні

Іноді, можливо, ви захочете почекати на даний селектор, а потім взаємодіяти з елементом, що відповідає селектору. Наприклад, ви можете почекати, поки не з’явиться модальне вікно, а потім натиснути кнопку «ОК» у модальному режимі.whenAvailableу цьому випадку може бути використаний метод. Усі операції з елементами, що виконуються в рамках даного зворотного виклику, будуть масштабовані до початкового селектора:

$browser->whenAvailable('.modal', function ($modal) {
    $modal->assertSee('Hello World')
          ->press('OK');
});

Очікування тексту

waitForTextметод може бути використаний для того, щоб почекати, поки даний текст не відобразиться на сторінці:

// Wait a maximum of five seconds for the text...
$browser->waitForText('Hello World');

// Wait a maximum of one second for the text...
$browser->waitForText('Hello World', 1);

Ви можете використовуватиwaitUntilMissingTextметод почекати, поки відображений текст буде видалено зі сторінки:

// Wait a maximum of five seconds for the text to be removed...
$browser->waitUntilMissingText('Hello World');

// Wait a maximum of one second for the text to be removed...
$browser->waitUntilMissingText('Hello World', 1);

Чекаю посилань

waitForLinkметод може бути використаний, щоб зачекати, поки на сторінці відобразиться текст даного посилання:

// Wait a maximum of five seconds for the link...
$browser->waitForLink('Create');

// Wait a maximum of one second for the link...
$browser->waitForLink('Create', 1);

Очікування на сторінці Розташування

Коли робите Assertions про шлях, наприклад$browser->assertPathIs('/home'), Assertions може провалитися, якщоwindow.location.pathnameоновлюється асинхронно. Ви можете використовуватиwaitForLocationметод дочекатися, коли розташування має задане значення:

$browser->waitForLocation('/secret');

Ви також можете дочекатися місцезнаходження вказаного маршруту:

$browser->waitForRoute($routeName, $parameters);

Waiting for Page Reloads

Якщо вам потрібно зробити Assertions після перезавантаження сторінки, використовуйтеwaitForReloadметод:

$browser->click('.some-action')
        ->waitForReload()
        ->assertSee('something');

Очікування на вирази JavaScript

Іноді вам може знадобитися призупинити виконання тесту, поки заданий вираз JavaScript не отримає значенняtrue. Ви можете легко досягти цього за допомогоюwaitUntilметод. Передаючи вираз цьому методу, вам не потрібно включатиreturnключове слово або крапка з комою:

// Wait a maximum of five seconds for the expression to be true...
$browser->waitUntil('App.dataLoaded');

$browser->waitUntil('App.data.servers.length > 0');

// Wait a maximum of one second for the expression to be true...
$browser->waitUntil('App.data.servers.length > 0', 1);

Очікування на вирази Vue

Наступні методи можна використовувати для очікування, поки даний атрибут компонента Vue отримає задане значення:

// Wait until the component attribute contains the given value...
$browser->waitUntilVue('user.name', 'Taylor', '@user');

// Wait until the component attribute doesn't contain the given value...
$browser->waitUntilVueIsNot('user.name', null, '@user');

Очікування із зворотним дзвінком

Багато методів "очікування" в Сутінках покладаються на основніwaitUsingметод. Ви можете використовувати цей метод безпосередньо, щоб дочекатися повернення даного зворотного дзвінкаtrue.waitUsingметод приймає максимальну кількість секунд очікування, інтервал, за який слід оцінити Закриття, Закриття та необов’язкове повідомлення про помилку:

$browser->waitUsing(10, 1, function () use ($something) {
    return $something->isReady();
}, "Something wasn't ready in time.");

Прокрутка елемента Into View

Іноді ви не можете натиснути на елемент, оскільки він знаходиться поза зоною видимості браузера.scrollIntoViewметод буде прокручувати вікно браузера, поки елемент у даному селекторі не буде у вікні перегляду:

$browser->scrollIntoView('selector')
        ->click('selector');

Запуск JavaScript

Ви можете використовуватиscriptметод для виконання JavaScript у браузері:

$output = $browser->script('document.documentElement.scrollTop = 0');

$output = $browser->script([
    'document.body.scrollTop = 0',
    'document.documentElement.scrollTop = 0',
]);

Висловлення Assertions Vue

Dusk навіть дозволяють робити твердження про стан РосіїПереглянутидані компонентів. Наприклад, уявіть, що ваша програма містить такий компонент Vue:

// HTML...

<profile dusk="profile-component"></profile>

// Component Definition...

Vue.component('profile', {
    template: '<div>{{ user.name }}</div>',

    data: function () {
        return {
            user: {
                name: 'Taylor'
            }
        };
    }
});

Ви можете стверджувати про стан компонента Vue так:

/**
 * A basic Vue test example.
 *
 * @return void
 */
public function testVue()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/')
                ->assertVue('user.name', 'Taylor', '@profile-component');
    });
}

Доступні Assertions

Dusk містять різноманітні Assertions, які ви можете зробити проти своєї заявки. Усі наявні Assertions задокументовані у списку нижче:

[assertTitle](#assert-title) [assertTitleContains](#assert-title-contains) [assertUrlIs](#assert-url-is) [assertSchemeIs](#assert-scheme-is) [assertSchemeIsNot](#assert-scheme-is-not) [assertHostIs](#assert-host-is) [assertHostIsNot](#assert-host-is-not) [assertPortIs](#assert-port-is) [assertPortIsNot](#assert-port-is-not) [assertPathBeginsWith](#assert-path-begins-with) [assertPathIs](#assert-path-is) [assertPathIsNot](#assert-path-is-not) [assertRouteIs](#assert-route-is) [assertQueryStringHas](#assert-query-string-has) [assertQueryStringMissing](#assert-query-string-missing) [assertFragmentIs](#assert-fragment-is) [assertFragmentBeginsWith](#assert-fragment-begins-with) [assertFragmentIsNot](#assert-fragment-is-not) [assertHasCookie](#assert-has-cookie) [assertHasPlainCookie](#assert-has-plain-cookie) [assertCookieMissing](#assert-cookie-missing) [assertPlainCookieMissing](#assert-plain-cookie-missing) [assertCookieValue](#assert-cookie-value) [assertPlainCookieValue](#assert-plain-cookie-value) [assertSee](#assert-see) [assertDontSee](#assert-dont-see) [assertSeeIn](#assert-see-in) [assertDontSeeIn](#assert-dont-see-in) [assertScript](#assert-script) [assertSourceHas](#assert-source-has) [assertSourceMissing](#assert-source-missing) [assertSeeLink](#assert-see-link) [assertDontSeeLink](#assert-dont-see-link) [assertInputValue](#assert-input-value) [assertInputValueIsNot](#assert-input-value-is-not) [assertChecked](#assert-checked) [assertNotChecked](#assert-not-checked) [assertRadioSelected](#assert-radio-selected) [assertRadioNotSelected](#assert-radio-not-selected) [assertSelected](#assert-selected) [assertNotSelected](#assert-not-selected) [assertSelectHasOptions](#assert-select-has-options) [assertSelectMissingOption](#assert-select-missing-option) [assertSelectMissingOptions](#assert-select-missing-options) [assertSelectHasOption](#assert-select-has-option) [assertValue](#assert-value) [assertAttribute](#assert-attribute) [assertAriaAttribute](#assert-aria-attribute) [assertDataAttribute](#assert-data-attribute) [assertVisible](#assert-visible) [assertPresent](#assert-present) [assertMissing](#assert-missing) [assertDialogOpened](#assert-dialog-opened) [assertEnabled](#assert-enabled) [assertDisabled](#assert-disabled) [assertButtonEnabled](#assert-button-enabled) [assertButtonDisabled](#assert-button-disabled) [assertFocused](#assert-focused) [assertNotFocused](#assert-not-focused) [assertAuthenticated](#assert-authenticated) [assertGuest](#assert-guest) [assertAuthenticatedAs](#assert-authenticated-as) [assertVue](#assert-vue) [assertVueIsNot](#assert-vue-is-not) [assertVueContains](#assert-vue-contains) [assertVueDoesNotContain](#assert-vue-does-not-contain)

assertTitle

Стверджуйте, що заголовок сторінки відповідає даному тексту:

$browser->assertTitle($title);

assertTitleContains

Стверджуйте, що заголовок сторінки містить поданий текст:

$browser->assertTitleContains($title);

стверджувати

Запевнити, що поточна URL-адреса (без рядка запиту) відповідає заданому рядку:

$browser->assertUrlIs($url);

assertSchemeIs

Стверджуємо, що поточна схема URL відповідає заданій схемі:

$browser->assertSchemeIs($scheme);

assertSchemeIsNot

Стверджуємо, що поточна схема URL-адреси не відповідає заданій схемі:

$browser->assertSchemeIsNot($scheme);

assertHostIs

Запевнити, що поточний хост URL-адреси відповідає даному хосту:

$browser->assertHostIs($host);

assertHostIsNot

Запевнити, що поточний хост URL-адреси не відповідає даному хосту:

$browser->assertHostIsNot($host);

assertPortIs

Запевнити, що поточний порт URL відповідає даному порту:

$browser->assertPortIs($port);

assertPortIsNot

Запевнити, що поточний порт URL-адреси не відповідає даному порту:

$browser->assertPortIsNot($port);

assertPathBeginsWith

Запевнити, що поточний шлях до URL починається з заданого шляху:

$browser->assertPathBeginsWith($path);

assertPathIs

Запевнити, що поточний шлях відповідає даному шляху:

$browser->assertPathIs('/home');

assertPathIsNot

Запевнити, що поточний шлях не відповідає заданому шляху:

$browser->assertPathIsNot('/home');

assertRouteIs

Запевнити, що поточна URL-адреса збігається із вказаною URL-адресою із вказаним маршрутом:

$browser->assertRouteIs($name, $parameters);

assertQueryStringHas

Стверджуємо, що вказаний параметр рядка запиту присутній:

$browser->assertQueryStringHas($name);

Стверджуємо, що заданий параметр рядка запиту присутній і має задане значення:

$browser->assertQueryStringHas($name, $value);

assertQueryStringMissing

Стверджуємо, що заданий параметр рядка запиту відсутній:

$browser->assertQueryStringMissing($name);

assertFragmentIs

Стверджуємо, що поточний фрагмент відповідає даному фрагменту:

$browser->assertFragmentIs('anchor');

assertFragmentBeginsWith

Стверджуємо, що поточний фрагмент починається з даного фрагмента:

$browser->assertFragmentBeginsWith('anchor');

assertFragmentIsNot

Стверджуємо, що поточний фрагмент не відповідає даному фрагменту:

$browser->assertFragmentIsNot('anchor');

assertHasCookie

Стверджуємо, що вказаний зашифрований файл cookie присутній:

$browser->assertHasCookie($name);

assertHasPlainCookie

Стверджуємо, що даний незашифрований файл cookie присутній:

$browser->assertHasPlainCookie($name);

assertCookieMissing

Стверджуємо, що вказаного зашифрованого файлу cookie немає:

$browser->assertCookieMissing($name);

assertPlainCookieMissing

Стверджуємо, що даного незашифрованого файлу cookie немає:

$browser->assertPlainCookieMissing($name);

assertCookieValue

Стверджуємо, що зашифрований файл cookie має задане значення:

$browser->assertCookieValue($name, $value);

assertPlainCookieValue

Стверджуємо, що незашифрований файл cookie має задане значення:

$browser->assertPlainCookieValue($name, $value);

затвердитиДив

Стверджуйте, що даний текст присутній на сторінці:

$browser->assertSee($text);

assertDontSee

Стверджуйте, що наведеного тексту немає на сторінці:

$browser->assertDontSee($text);

assertSeeIn

Стверджуйте, що даний текст присутній у селекторі:

$browser->assertSeeIn($selector, $text);

assertDontSeeIn

Стверджуйте, що вказаний текст відсутній у селекторі:

$browser->assertDontSeeIn($selector, $text);

assertScript

Стверджуємо, що вказаний вираз JavaScript має значення:

$browser->assertScript('window.isLoaded')
        ->assertScript('document.readyState', 'complete');

assertSourceHas

Стверджуйте, що даний вихідний код присутній на сторінці:

$browser->assertSourceHas($code);

assertSourceMissing

Стверджуйте, що даного вихідного коду немає на сторінці:

$browser->assertSourceMissing($code);

assertSeeLink

Стверджуйте, що дане посилання присутнє на сторінці:

$browser->assertSeeLink($linkText);

assertDontSeeLink

Стверджуйте, що даного посилання немає на сторінці:

$browser->assertDontSeeLink($linkText);

assertInputValue

Стверджуємо, що дане поле введення має вказане значення:

$browser->assertInputValue($field, $value);

assertInputValueIsNot

Стверджуємо, що дане поле введення не має заданого значення:

$browser->assertInputValueIsNot($field, $value);

assertChecked

Стверджуємо, що вказаний прапорець встановлений:

$browser->assertChecked($field);

assertNotChecked

Стверджуйте, що вказаний прапорець не встановлений:

$browser->assertNotChecked($field);

assertRadioSelected

Стверджуйте, що вибрано дане радіополе:

$browser->assertRadioSelected($field, $value);

assertRadioNotSelected

Стверджуйте, що дане радіополе не вибрано:

$browser->assertRadioNotSelected($field, $value);

assertSelected

Стверджуємо, що в даному випадаючому списку вибрано вказане значення:

$browser->assertSelected($field, $value);

assertNotSelected

Стверджуємо, що в даному випадаючому списку не вибрано вказане значення:

$browser->assertNotSelected($field, $value);

assertSelectHasOptions

Стверджуємо, що даний масив значень доступний для вибору:

$browser->assertSelectHasOptions($field, $values);

assertSelectMissingOption

Стверджуйте, що вказане значення недоступне для вибору:

$browser->assertSelectMissingOption($field, $value);

assertSelectMissingOptions

Стверджуємо, що даний масив значень недоступний для вибору:

$browser->assertSelectMissingOptions($field, $values);

assertSelectHasOption

Стверджуйте, що вказане значення доступне для вибору у даному полі:

$browser->assertSelectHasOption($field, $value);

assertValue

Стверджуємо, що елемент, що відповідає даному селектору, має вказане значення:

$browser->assertValue($selector, $value);

assertAttribute

Стверджуємо, що елемент, що відповідає даному селектору, має задане значення у наданому атрибуті:

$browser->assertAttribute($selector, $attribute, $value);

assertAriaAttribute

Стверджуємо, що елемент, що відповідає даному селектору, має задане значення в наданому атрибуті aria:

$browser->assertAriaAttribute($selector, $attribute, $value);

Наприклад, враховуючи розмітку<button aria-label="Add"></button>, ви можете стверджувати протиaria-labelатрибут так:

$browser->assertAriaAttribute('button', 'label', 'Add')

стверджувати атрибут даних

Запевнити, що елемент, що відповідає даному селектору, має задане значення в наданому атрибуті даних:

$browser->assertDataAttribute($selector, $attribute, $value);

Наприклад, враховуючи розмітку<tr id="row-1" data-content="attendees"></tr>, ви можете стверджувати протиdata-labelатрибут так:

$browser->assertDataAttribute('#row-1', 'content', 'attendees')

assertVisible

Запевнити, що видно елемент, що відповідає даному селектору:

$browser->assertVisible($selector);

assertPresent

Стверджуємо, що присутній елемент, що відповідає даному селектору:

$browser->assertPresent($selector);

assertMissing

Стверджуємо, що елемент, що відповідає даному селектору, не видно:

$browser->assertMissing($selector);

assertDialogOpened

Стверджуємо, що відкрито діалогове вікно JavaScript із даним повідомленням:

$browser->assertDialogOpened($message);

assertEnabled

Стверджуємо, що дане поле ввімкнено:

$browser->assertEnabled($field);

assertDisabled

Стверджуємо, що дане поле вимкнено:

$browser->assertDisabled($field);

assertButtonEnabled

Стверджуємо, що дана кнопка ввімкнена:

$browser->assertButtonEnabled($button);

Кнопка затвердження відключена

Стверджуйте, що дана кнопка відключена:

$browser->assertButtonDisabled($button);

assertFocused

Стверджуйте, що дане поле зосереджене:

$browser->assertFocused($field);

assertNotFocused

Стверджуйте, що дане поле не сфокусовано:

$browser->assertNotFocused($field);

затвердити Аутентифіковано

Стверджуємо, що автентифікація користувача:

$browser->assertAuthenticated();

assertGuest

Стверджуйте, що користувач не пройшов аутентифікацію:

$browser->assertGuest();

assertAuthenticatedAs

Стверджуємо, що користувач аутентифікується як даний користувач:

$browser->assertAuthenticatedAs($user);

assertVue

Стверджуємо, що дана властивість даних компонента Vue відповідає заданому значенню:

$browser->assertVue($property, $value, $componentSelector = null);

assertVueIsNot

Стверджуємо, що дана властивість даних компонента Vue не відповідає заданому значенню:

$browser->assertVueIsNot($property, $value, $componentSelector = null);

assertVueContens

Стверджуємо, що дана властивість даних компонента Vue є масивом і містить задане значення:

$browser->assertVueContains($property, $value, $componentSelector = null);

assertVueDoesNotContain

Стверджуємо, що дана властивість даних компонента Vue є масивом і не містить заданого значення:

$browser->assertVueDoesNotContain($property, $value, $componentSelector = null);

Сторінки

Іноді тести вимагають декількох складних дій, які слід виконувати послідовно. Це може ускладнити читання та розуміння ваших тестів. Сторінки дозволяють визначити виразні дії, які потім можна виконати на даній сторінці за допомогою одного методу. Сторінки також дозволяють визначати ярлики до загальних селекторів для вашої програми або однієї сторінки.

Генерування сторінок

Щоб створити об'єкт сторінки, використовуйтеdusk:pageartisan командування. Усі об'єкти сторінки будуть розміщені вtests/Browser/Pagesкаталог:

php artisan dusk:page Login

Налаштування сторінок

За замовчуванням сторінки мають три методи:url,assert, іelements. Ми обговоримоurlіassertметоди зараз.elementsметод будедокладніше обговорюється нижче.

urlМетод

urlметод повинен повертати шлях до URL-адреси, що представляє сторінку. Dusk використовуватимуть цю URL-адресу під час переходу на сторінку в браузері:

/**
 * Get the URL for the page.
 *
 * @return string
 */
public function url()
{
    return '/login';
}

assertМетод

assertметод може робити будь-які Assertions, необхідні для перевірки того, що браузер насправді знаходиться на даній сторінці. Завершувати цей метод не потрібно; однак ви можете вільно робити ці Assertions, якщо хочете. Ці Assertions будуть запускатися автоматично під час переходу на сторінку:

/**
 * Assert that the browser is on the page.
 *
 * @return void
 */
public function assert(Browser $browser)
{
    $browser->assertPathIs($this->url());
}

Перехід до сторінок

Після налаштування сторінки ви можете перейти до неї за допомогоюvisitметод:

use Tests\Browser\Pages\Login;

$browser->visit(new Login);

Ви можете використовуватиvisitRouteспосіб переходу до названого маршруту:

$browser->visitRoute('login');

Ви можете переходити "назад" і "вперед", використовуючиbackіforwardметоди:

$browser->back();

$browser->forward();

Ви можете використовуватиrefreshспосіб оновити сторінку:

$browser->refresh();

Іноді ви вже можете бути на певній сторінці і вам потрібно "завантажити" селектори та методи сторінки в поточний контекст тесту. Це характерно для натискання кнопки та перенаправлення на дану сторінку без явного переходу до неї. У цій ситуації ви можете використовуватиonспосіб завантаження сторінки:

use Tests\Browser\Pages\CreatePlaylist;

$browser->visit('/dashboard')
        ->clickLink('Create Playlist')
        ->on(new CreatePlaylist)
        ->assertSee('@create');

Shorthand селектори

elementsМетод сторінок дозволяє визначити швидкі, легко запам'ятовуються ярлики для будь-якого селектора CSS на вашій сторінці. Наприклад, визначимо ярлик для поля введення "електронна пошта" сторінки входу в програму:

/**
 * Get the element shortcuts for the page.
 *
 * @return array
 */
public function elements()
{
    return [
        '@email' => 'input[name=email]',
    ];
}

Тепер ви можете використовувати цей скорочений селектор у будь-якому місці, де ви б використовували повний селектор CSS:

$browser->type('@email', 'taylor@laravel.com');

Глобальні Shorthand селектори

Після встановлення Dusk, основиPageклас буде розміщений у вашомуtests/Browser/Pagesкаталог. Цей клас міститьsiteElementsметод, який може бути використаний для визначення глобальних скорочувальних селекторів, які повинні бути доступні на кожній сторінці у вашій програмі:

/**
 * Get the global element shortcuts for the site.
 *
 * @return array
 */
public static function siteElements()
{
    return [
        '@element' => '#selector',
    ];
}

Методи сторінок

На додаток до методів за замовчуванням, визначених на сторінках, ви можете визначити додаткові методи, які можна використовувати під час ваших тестів. Наприклад, уявімо, що ми створюємо програму управління музикою. Поширеною дією для однієї сторінки програми може бути створення списку відтворення. Замість того, щоб переписувати логіку для створення списку відтворення в кожному тесті, ви можете визначити acreatePlaylistметод на класі сторінки:

<?php

namespace Tests\Browser\Pages;

use Laravel\Dusk\Browser;

class Dashboard extends Page
{
    // Other page methods...

    /**
     * Create a new playlist.
     *
     * @param  \Laravel\Dusk\Browser  $browser
     * @param  string  $name
     * @return void
     */
    public function createPlaylist(Browser $browser, $name)
    {
        $browser->type('name', $name)
                ->check('share')
                ->press('Create Playlist');
    }
}

Після визначення методу ви можете використовувати його в будь-якому тесті, який використовує сторінку. Екземпляр браузера буде автоматично переданий методу сторінки:

use Tests\Browser\Pages\Dashboard;

$browser->visit(new Dashboard)
        ->createPlaylist('My Playlist')
        ->assertSee('My Playlist');

Компоненти

Компоненти схожі на «об'єкти сторінки» Dusk, але призначені для частин інтерфейсу та функціональних можливостей, які повторно використовуються у всій програмі, наприклад, панелі навігації або вікна сповіщень. Як такі, компоненти не прив’язані до певних URL-адрес.

Генерування компонентів

Щоб створити компонент, використовуйтеdusk:componentartisan командування. Нові компоненти розміщуються вtests/Browser/Componentsкаталог:

php artisan dusk:component DatePicker

Як показано вище, "засіб вибору дати" - це приклад компонента, який може існувати у всій програмі на різних сторінках. Вручну писати логіку автоматизації браузера для вибору дати в десятках тестів у вашому наборі тестів може стати важко. Натомість ми можемо визначити компонент «Dusk» для представлення пункту вибору дати, що дозволяє нам інкапсулювати цю логіку в компоненті:

<?php

namespace Tests\Browser\Components;

use Laravel\Dusk\Browser;
use Laravel\Dusk\Component as BaseComponent;

class DatePicker extends BaseComponent
{
    /**
     * Get the root selector for the component.
     *
     * @return string
     */
    public function selector()
    {
        return '.date-picker';
    }

    /**
     * Assert that the browser page contains the component.
     *
     * @param  Browser  $browser
     * @return void
     */
    public function assert(Browser $browser)
    {
        $browser->assertVisible($this->selector());
    }

    /**
     * Get the element shortcuts for the component.
     *
     * @return array
     */
    public function elements()
    {
        return [
            '@date-field' => 'input.datepicker-input',
            '@year-list' => 'div > div.datepicker-years',
            '@month-list' => 'div > div.datepicker-months',
            '@day-list' => 'div > div.datepicker-days',
        ];
    }

    /**
     * Select the given date.
     *
     * @param  \Laravel\Dusk\Browser  $browser
     * @param  int  $year
     * @param  int  $month
     * @param  int  $day
     * @return void
     */
    public function selectDate($browser, $year, $month, $day)
    {
        $browser->click('@date-field')
                ->within('@year-list', function ($browser) use ($year) {
                    $browser->click($year);
                })
                ->within('@month-list', function ($browser) use ($month) {
                    $browser->click($month);
                })
                ->within('@day-list', function ($browser) use ($day) {
                    $browser->click($day);
                });
    }
}

Використання компонентів

Після того, як компонент визначений, ми можемо легко вибрати дату в засобі вибору дати з будь-якого тесту. І якщо логіка, необхідна для вибору дати, змінюється, нам потрібно лише оновити компонент:

<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Components\DatePicker;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    /**
     * A basic component test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->within(new DatePicker, function ($browser) {
                        $browser->selectDate(2019, 1, 30);
                    })
                    ->assertSee('January');
        });
    }
}

Постійна інтеграція

Перш ніж додавати файл конфігурації безперервної інтеграції, переконайтеся, що ваш.env.testingфайл містить файлAPP_URLзапис зі значеннямhttp://127.0.0.1:8000.

CircleCI

Якщо ви використовуєте CircleCI для запуску своїх сутінкових тестів, ви можете використовувати цей файл конфігурації як вихідну точку. Як і TravisCI, ми будемо використовуватиphp artisan serveкоманда для запуску вбудованого веб-сервера PHP:

version: 2
jobs:
    build:
        steps:
            - run: sudo apt-get install -y libsqlite3-dev
            - run: cp .env.testing .env
            - run: composer install -n --ignore-platform-reqs
            - run: php artisan key:generate
            - run: php artisan dusk:chrome-driver
            - run: npm install
            - run: npm run production
            - run: vendor/bin/phpunit

            - run:
                name: Start Chrome Driver
                command: ./vendor/laravel/dusk/bin/chromedriver-linux
                background: true

            - run:
                name: Run Laravel Server
                command: php artisan serve
                background: true

            - run:
                name: Run Laravel Dusk Tests
                command: php artisan dusk

            - store_artifacts:
                path: tests/Browser/screenshots

            - store_artifacts:
                path: tests/Browser/console

            - store_artifacts:
                path: storage/logs

Кодування

Для запуску тестів "Dusk"Кодування, додайте наступні команди до свого проекту Codeship. Ці команди є лише відправною точкою, і ви можете додавати додаткові команди за потреби:

phpenv local 7.3
cp .env.testing .env
mkdir -p ./bootstrap/cache
composer install --no-interaction --prefer-dist
php artisan key:generate
php artisan dusk:chrome-driver
nohup bash -c "php artisan serve 2>&1 &" && sleep 5
php artisan dusk

Heroku К.І.

Для запуску тестів "Dusk"Heroku К.І., додайте наступний пакет збірки Google Chrome та сценарії до вашого Herokuapp.jsonфайл:

{
  "environments": {
    "test": {
      "buildpacks": [
        { "url": "heroku/php" },
        { "url": "https://github.com/heroku/heroku-buildpack-google-chrome" }
      ],
      "scripts": {
        "test-setup": "cp .env.testing .env",
        "test": "nohup bash -c './vendor/laravel/dusk/bin/chromedriver-linux > /dev/null 2>&1 &' && nohup bash -c 'php artisan serve > /dev/null 2>&1 &' && php artisan dusk"
      }
    }
  }
}

Travis К.І.

Для запуску тестів "Dusk" наTravis К.І., скористайтеся наступним.travis.ymlконфігурації. Оскільки Travis CI не є графічним середовищем, нам потрібно буде зробити кілька додаткових кроків, щоб запустити браузер Chrome. Крім того, ми будемо використовуватиphp artisan serveдля запуску вбудованого веб-сервера PHP:

language: php

php:
  - 7.3

addons:
  chrome: stable

install:
  - cp .env.testing .env
  - travis_retry composer install --no-interaction --prefer-dist --no-suggest
  - php artisan key:generate
  - php artisan dusk:chrome-driver

before_script:
  - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
  - php artisan serve &

script:
  - php artisan dusk

Дії GitHub

Якщо ви використовуєтеДії Githubдля запуску Ваших сутінкових тестів ви можете використовувати цей файл конфігурації як початкову точку. Як і TravisCI, ми будемо використовуватиphp artisan serveкоманда для запуску вбудованого веб-сервера PHP:

name: CI
on: [push]
jobs:

  dusk-php:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Prepare The Environment
        run: cp .env.example .env
      - name: Create Database
        run: |
          sudo systemctl start mysql
          mysql --user="root" --password="root" -e "CREATE DATABASE 'my-database' character set UTF8mb4 collate utf8mb4_bin;"
      - name: Install Composer Dependencies
        run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
      - name: Generate Application Key
        run: php artisan key:generate
      - name: Upgrade Chrome Driver
        run: php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
      - name: Start Chrome Driver
        run: ./vendor/laravel/dusk/bin/chromedriver-linux &
      - name: Run Laravel Server
        run: php artisan serve &
      - name: Run Dusk Tests
        env:
          APP_URL: "http://127.0.0.1:8000"
        run: php artisan dusk
      - name: Upload Screenshots
        if: failure()
        uses: actions/upload-artifact@v2
        with:
          name: screenshots
          path: tests/Browser/screenshots
      - name: Upload Console Logs
        if: failure()
        uses: actions/upload-artifact@v2
        with:
          name: console
          path: tests/Browser/console