Вступление

Laravel Dusk предоставляет выразительный и простой в использовании API для автоматизации и тестирования браузеров. По умолчанию Dusk не требует от вас установки JDK или Selenium на ваш компьютер. Вместо этого Dusk использует автономную установку ChromeDriver . Тем не менее, вы можете использовать любой другой драйвер, совместимый с Selenium.

 

Монтаж

Чтобы начать, вы должны добавить зависимость Composer в ваш проект:laravel/dusk

composer require --dev laravel/dusk

Если вы вручную регистрируете поставщика услуг Dusk, вы никогда не должны регистрировать его в своей производственной среде, так как это может привести к тому, что произвольные пользователи смогут аутентифицироваться в вашем приложении.

После установки пакета Dusk выполните команду Artisan:dusk:install

php artisan dusk:install

BrowserКаталог будет создан в вашем 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 74

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

Сумерки требуют, чтобы chromedriverдвоичные файлы были исполняемыми. Если у вас возникли проблемы с запуском Dusk, вы должны убедиться , что исполняемые файлы являются исполняемыми с помощью следующей команды: .chmod -R 0755 vendor/laravel/dusk/bin/

 

Использование других браузеров

По умолчанию Dusk использует Google Chrome и отдельную установку ChromeDriver для запуска тестов браузера. Тем не менее, вы можете запустить свой собственный сервер Selenium и запускать свои тесты на любом браузере, который пожелаете.

Для начала откройте файл, который является базовым тестовым сценарием Dusk для вашего приложения. В этом файле вы можете удалить вызов метода. Это остановит Dusk от автоматического запуска ChromeDriver:tests/DuskTestCase.phpstartChromeDriver

/**
 * 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, используйте команду Artisan. Сгенерированный тест будет помещен в каталог:dusk:maketests/Browser

php artisan dusk:make LoginTest

 

Запуск тестов

Чтобы запустить тесты браузера, используйте команду duskArtisan:

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()
    );
}

 

Обработка окружающей среды

Чтобы заставить Dusk использовать собственный файл среды при запуске тестов, создайте файл в корневом каталоге вашего проекта. Например, если вы будете инициировать команду из своего окружения, вам следует создать файл..env.dusk.{environment}dusklocal.env.dusk.local

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

 

Создание браузеров

Для начала давайте напишем тест, который проверяет, что мы можем войти в наше приложение. После создания теста мы можем изменить его, чтобы перейти на страницу входа в систему, ввести некоторые учетные данные и нажать кнопку «Войти». Чтобы создать экземпляр браузера, вызовите browseметод:

<?php

namespace Tests\Browser;

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

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;

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

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

Как вы можете видеть в приведенном выше примере, browseметод принимает обратный вызов. Экземпляр браузера будет автоматически передан этому обратному вызову Dusk и является основным объектом, используемым для взаимодействия и утверждения против вашего приложения.

Этот тест можно использовать для проверки экрана входа в систему, созданного командой Artisan.make:auth

Создание нескольких браузеров

Иногда вам может понадобиться несколько браузеров, чтобы правильно выполнить тест. Например, для проверки экрана чата, взаимодействующего с веб-сокетами, может потребоваться несколько браузеров. Чтобы создать несколько браузеров, «попросите» более одного браузера в сигнатуре обратного вызова, данного 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');
});

Изменение размера окна браузера

Вы можете использовать resizeметод для настройки размера окна браузера:

$browser->resize(1920, 1080);

maximizeМетод может быть использован , чтобы максимизировать окно браузера:

$browser->maximize();

 

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

Если вы хотите определить пользовательский метод браузера, который вы можете повторно использовать в различных тестах, вы можете использовать этот macroметод в Browserклассе. Как правило, вы должны вызывать этот метод из метода поставщика услуг boot :

<?php

namespace App\Providers;

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

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');
});

 

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

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

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

После использования loginAsметода сеанс пользователя будет поддерживаться для всех тестов в файле.

 

Миграция базы данных

Когда ваш тест требует миграций, как в приведенном выше примере аутентификации, вы никогда не должны использовать эту RefreshDatabaseчерту. Эта RefreshDatabaseчерта использует транзакции базы данных, которые не будут применяться к HTTP-запросам. Вместо этого используйте DatabaseMigrationsчерту:

<?php

namespace Tests\Browser;

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

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;
}

 

Взаимодействие с элементами

Dusk Selectors

Выбор хороших CSS-селекторов для взаимодействия с элементами - одна из самых сложных частей написания тестов Dusk. Со временем изменения внешнего интерфейса могут привести к тому, что CSS-селекторы, подобные следующему, будут нарушать ваши тесты:

// HTML...

<button>Login</button>

// Test...

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

Селекторы Dusk позволяют вам сосредоточиться на написании эффективных тестов, а не вспоминать селекторы CSS. Чтобы определить селектор, добавьте duskатрибут к вашему HTML-элементу. Затем добавьте префикс селектора, @чтобы управлять вложенным элементом в тесте Dusk:

// HTML...

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

// Test...

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

 

Нажатие на ссылки

Чтобы перейти по ссылке, вы можете использовать clickLinkметод в экземпляре браузера. clickLinkМетод будет нажать на ссылку , которая имеет данный текст дисплея:

$browser->clickLink($linkText);

Этот метод взаимодействует с jQuery. Если jQuery недоступен на странице, Dusk автоматически вставит его на страницу, чтобы он был доступен на протяжении всего теста.

 

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

Получение и установка значений

Dusk предоставляет несколько методов взаимодействия с текущим отображаемым текстом, значением и атрибутами элементов на странице. Например, чтобы получить «значение» элемента, соответствующего данному селектору, используйте valueметод:

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

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

Получение текста

Этот 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');

Dropdowns

Чтобы выбрать значение в раскрывающемся списке, вы можете использовать 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', 'php7');

 

Вложение файлов

Этот attachметод может использоваться для прикрепления файла к fileэлементу ввода. Как и многие другие методы, связанные с вводом, полный селектор CSS не требуется. Если точное совпадение селектора не может быть найдено, Dusk будет искать входной файл с соответствующим nameатрибутом:

$browser->attach('photo', __DIR__.'/photos/me.png');

Функция присоединения требует, чтобы Zipрасширение PHP было установлено и включено на вашем сервере.

 

Использование клавиатуры

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

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

Вы даже можете отправить «горячую клавишу» первичному селектору CSS, который содержит ваше приложение:

$browser->keys('.app', ['{command}', 'j']);

Все ключи-модификаторы заключены в символы и соответствуют константам, определенным в классе, который можно найти на GitHub.{}Facebook\WebDriver\WebDriverKeys

 

Используя мышь

Нажав на элементы

clickМетод может быть использован для «щелчка» на элементе , соответствующий заданный селектор:

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

Mouseover

mouseoverМетод может быть использован , когда нужно переместить курсор элемента , соответствующий заданный селектор:

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

Перетаскивания

dragМетод может быть использован , чтобы перетащить элемент , соответствующий заданный селектор к другому элементу:

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

Или вы можете перетащить элемент в одном направлении:

$browser->dragLeft('.selector', 10);
$browser->dragRight('.selector', 10);
$browser->dragUp('.selector', 10);
$browser->dragDown('.selector', 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, нажмите кнопку ОК:

$browser->acceptDialog();

Чтобы закрыть открытый диалог JavaScript, нажмите кнопку «Отмена» (только для диалогового окна подтверждения):

$browser->dismissDialog();

 

Выбор области видимости

Иногда вам может потребоваться выполнить несколько операций при определении объема всех операций в данном селекторе. Например, вы можете утверждать, что некоторый текст существует только внутри таблицы, а затем нажать кнопку в этой таблице. Вы можете использовать withметод для достижения этой цели. Все операции, выполняемые в рамках обратного вызова, переданного withметоду, будут ограничены исходным селектором:

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

 

В ожидании стихии

При тестировании приложений, которые широко используют JavaScript, часто возникает необходимость «дождаться» доступности определенных элементов или данных, прежде чем приступить к тестированию. Сумерки делают это подпоркой. Используя различные методы, вы можете подождать, пока элементы будут видны на странице, или даже подождать, пока определенное выражение 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);

Вы также можете подождать, пока данный селектор отсутствует на странице:

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

$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);

В ожидании ссылок

Этот 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);

Ожидание на странице Расположение

При создании утверждения пути, такого как , утверждение может потерпеть неудачу, если обновляется асинхронно. Вы можете использовать метод, чтобы дождаться, пока местоположение будет заданным значением:$browser->assertPathIs('/home')window.location.pathnamewaitForLocation

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

Вы также можете подождать, пока название маршрута не найдется:

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

Ожидание перезагрузки страницы

Если вам нужно сделать утверждения после перезагрузки страницы, используйте 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');

Ожидание с обратным вызовом

Многие из методов ожидания в Dusk полагаются на базовый waitUsingметод. Вы можете использовать этот метод напрямую, чтобы дождаться возврата данного обратного вызова truewaitUsingМетод принимает максимальное количество секунд ожидания, интервал , при котором закрытие должно быть оценено, закрытие и дополнительное сообщение отказа:

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

 

Делать Vue Утверждения

Даже в сумерках можно делать утверждения о состоянии данных компонента Vue . Например, представьте, что ваше приложение содержит следующий компонент 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');
    });
}

 

Доступные утверждения

Dusk предлагает множество утверждений, которые вы можете сделать против своего заявления. Все доступные утверждения документированы в списке ниже:

  • assertTitle
  • assertTitleContains
  • assertUrlIs
  • assertSchemeIs
  • assertSchemeIsNot
  • assertHostIs
  • assertHostIsNot
  • assertPortIs
  • assertPortIsNot
  • assertPathBeginsWith
  • assertPathIs
  • assertPathIsNot
  • assertRouteIs
  • assertQueryStringHas
  • assertQueryStringMissing
  • assertFragmentIs
  • assertFragmentBeginsWith
  • assertFragmentIsNot
  • assertHasCookie
  • assertCookieMissing
  • assertCookieValue
  • assertPlainCookieValue
  • assertSee
  • assertDontSee
  • assertSeeIn
  • assertDontSeeIn
  • assertSourceHas
  • assertSourceMissing
  • assertSeeLink
  • assertDontSeeLink
  • assertInputValue
  • assertInputValueIsNot
  • assertChecked
  • assertNotChecked
  • assertRadioSelected
  • assertRadioNotSelected
  • assertSelected
  • assertNotSelected
  • assertSelectHasOptions
  • assertSelectMissingOptions
  • assertSelectHasOption
  • assertValue
  • assertVisible
  • assertPresent
  • assertMissing
  • assertDialogOpened
  • assertEnabled
  • assertDisabled
  • assertFocused
  • assertNotFocused
  • assertVue
  • assertVueIsNot
  • assertVueContains
  • assertVueDoesNotContain

 

assertTitle

Утверждают, что заголовок страницы соответствует заданному тексту:

$browser->assertTitle($title);

 

assertTitleContains

Утверждают, что заголовок страницы содержит заданный текст:

$browser->assertTitleContains($title);

 

assertUrlIs

Утвердите, что текущий 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);

 

assertCookieMissing

Утверждают, что данного cookie нет:

$browser->assertCookieMissing($name);

 

assertCookieValue

Утверждают, что cookie имеет заданное значение:

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

 

assertPlainCookieValue

Утверждают, что незашифрованный файл cookie имеет заданное значение:

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

 

assertSee

Утверждают, что данный текст присутствует на странице:

$browser->assertSee($text);

 

assertDontSee

Утверждают, что данного текста нет на странице:

$browser->assertDontSee($text);

 

assertSeeIn

Утверждают, что данный текст присутствует в селекторе:

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

 

assertDontSeeIn

Утверждают, что данный текст отсутствует в селекторе:

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

 

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);

 

assertSelectMissingOptions

Утверждают, что данный массив значений недоступен для выбора:

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

 

assertSelectHasOption

Утверждают, что данное значение доступно для выбора в данном поле:

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

 

assertValue

Утверждают, что элемент, соответствующий данному селектору, имеет заданное значение:

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

 

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);

 

assertFocused

Утверждают, что данное поле ориентировано:

$browser->assertFocused($field);

 

assertNotFocused

Утверждают, что данное поле не ориентировано:

$browser->assertNotFocused($field);

 

assertVue

Утвердите, что данное свойство данных компонента Vue соответствует данному значению:

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

 

assertVueIsNot

Утвердите, что данное свойство данных компонента Vue не соответствует данному значению:

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

 

assertVueContains

Утвердите, что данное свойство данных компонента Vue является массивом и содержит заданное значение:

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

 

assertVueDoesNotContain

Утвердите, что данное свойство данных компонента Vue является массивом и не содержит заданного значения:

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

 

Страницы

Иногда тесты требуют выполнения нескольких сложных действий в последовательности. Это может затруднить чтение и понимание ваших тестов. Страницы позволяют вам определять выразительные действия, которые затем могут быть выполнены на данной странице, используя один метод. Страницы также позволяют определять ярлыки для общих селекторов для вашего приложения или отдельной страницы.

 

Создание страниц

Чтобы сгенерировать объект страницы, используйте команду Artisan. Все объекты страницы будут размещены в каталоге:dusk:pagetests/Browser/Pages

php artisan dusk:page Login

 

Конфигурирование страниц

По умолчанию, страницы имеют три метода: urlassert, и elements. Мы обсудим urlи assertметоды сейчас. elementsМетод будет обсуждаться более подробно ниже .

urlМетод

urlМетод должен возвращать путь к URL , который представляет страницу. Dusk будет использовать этот URL при переходе на страницу в браузере:

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

assertМетод

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

/**
 * 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);

Иногда вы уже можете быть на данной странице и вам необходимо «загрузить» селекторы и методы страницы в текущий контекст теста. Это часто происходит при нажатии кнопки и перенаправлении на заданную страницу без явного перехода к ней. В этой ситуации вы можете использовать onметод для загрузки страницы:

use Tests\Browser\Pages\CreatePlaylist;

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

 

Сокращенные селекторы

elementsМетод страниц позволяет определить быстро, легко запоминающиеся ярлыки для любого селектора CSS на вашей странице. Например, давайте определим ярлык для поля ввода «email» на странице входа приложения:

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

Теперь вы можете использовать этот сокращенный селектор везде, где вы бы использовали полный селектор CSS:

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

Глобальные сокращенные отборщики

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

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

 

Методы страницы

В дополнение к методам по умолчанию, определенным на страницах, вы можете определить дополнительные методы, которые могут использоваться в ваших тестах. Например, давайте представим, что мы создаем приложение для управления музыкой. Обычным действием для одной страницы приложения может быть создание списка воспроизведения. Вместо того, чтобы переписывать логику для создания списка воспроизведения в каждом тесте, вы можете определить createPlaylistметод для класса страницы:

<?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-адресам.

Генерация компонентов

Для создания компонента используйте команду Artisan. Новые компоненты размещены в каталоге:dusk:componenttest/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',
            '@month-list' => 'div > div.datepicker-months',
            '@day-list' => 'div > div.datepicker-days',
        ];
    }

    /**
     * Select the given date.
     *
     * @param  \Laravel\Dusk\Browser  $browser
     * @param  int  $month
     * @param  int  $day
     * @return void
     */
    public function selectDate($browser, $month, $day)
    {
        $browser->click('@date-field')
                ->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 Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Tests\Browser\Components\DatePicker;
use Illuminate\Foundation\Testing\DatabaseMigrations;

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(1, 2018);
                    })
                    ->assertSee('January');
        });
    }
}

 

Непрерывная интеграция

CircleCI

Если вы используете CircleCI для запуска тестов Dusk, вы можете использовать этот файл конфигурации в качестве отправной точки. Как и 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: 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

 

Codeship

Чтобы запустить Dusk тесты на Codeship , добавьте следующие команды в ваш проект Codeship. Эти команды являются только отправной точкой, и вы можете добавлять дополнительные команды по мере необходимости:

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

 

Heroku CI

Чтобы запустить тесты Dusk на Heroku CI , добавьте в свой файл Heroku следующий пакет сборки Google Chrome и сценарии :app.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"
      }
    }
  }
}

 

Трэвис CI

Чтобы запустить тесты Dusk на Travis CI , используйте следующую конфигурацию. Поскольку Travis CI не является графической средой, нам нужно предпринять некоторые дополнительные шаги для запуска браузера Chrome. Кроме того, мы будем использовать для запуска встроенного веб-сервера PHP:.travis.ymlphp artisan serve

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

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

script:
  - php artisan dusk

В вашем файле настройте значение :.env.testingAPP_URL

APP_URL=http://127.0.0.1:8000