Laravel dusk でブラウザテストを作成していて困った部分の対処法のメモです。
間違っている箇所があればご指摘いただければ幸いです。
dusk失敗時の画面スクリーンショット
app\tests\Browser\screenshots配下に失敗時の画面スクリーンショットが作成されます。
要素の表示をwaitで待つ
$browser->waitForText('検索', 30);
$browser->waitFor("#search", 30);
要素がクリックできないとき
素のjsで要素をクリックする(サービスプロバイダにマクロを登録する 参照)
//クリックする
$browser->clickToElement(".search_btn");
画面内に表示されていない要素がクリックできないとき
素のjsで要素にスクロールする(サービスプロバイダにマクロを登録する 参照)
//クリックする
$browser->scrollToElement(".search_btn");
サービスプロバイダにマクロを登録する
ブラウザマクロを作成し、サービスプロバイダにマクロを登録する。
[参考]
https://readouble.com/laravel/5.7/ja/dusk.html (ブラウザマクロ 部分参照)
https://readouble.com/laravel/5.3/ja/providers.html (プロバイダの登録 部分参照)
https://github.com/laravel/dusk/issues/203 (マクロ登録例)
<?php
namespace App\Providers;
use Laravel\Dusk\Browser;
use Illuminate\Support\ServiceProvider;
class DuskServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
Browser::macro('scrollToElement', function ($element = null) {
$this->script("$('html, body').animate({ scrollTop: $('$element').offset().top }, 0);");
return $this;
});
Browser::macro('clickToElement', function ($element = null) {
$this->script("document.querySelector('$element').click();");
return $this;
});
Browser::macro('switchFrame', function ($frame = null) {
if ($frame) {
$this->driver->switchTo()->defaultContent()->switchTo()->frame($frame);
} else {
// Main frame
$this->driver->switchTo()->defaultContent();
}
return $this;
});
}
}
config/app.php
'providers' => [
// Other Service Providers
App\Providers\DuskServiceProvider::class,
],
※Class 'App\Providers\DuskServiceProvider' not found
登録したマクロが見つからないというエラーが表示された場合、キャッシュファイルを削除すること。
artisan cache:clear
artisan config:clear
artisan route:clear
artisan view:clear
testの中断(Ctrl + c)でDB接続先がずれた?
.env / .env.dusk.local(.env.dusk.{environment}) の中身を確認する。
テスト中は.envの内容が一時backupファイルに退避され、.env.dusk.localの内容が.envに書き込まれるようですが、
中断により.envの内容が.env.dusk.localのまま、backupファイルが残った状態という現象が私のDockerテスト環境では起こりました。
.envを戻し、backupファイルを削除すると戻ります。
(そしてキャッシュファイルも削除)
chromeの設定ファイル (UAを変えたい 画面サイズを変更したいなどはここで)
DuskTestCase.php
protected function driver()
{
$options = (new ChromeOptions)->addArguments([
'--disable-gpu',
'--headless',
'--window-size=375,667',
'--no-sandbox',
'--lang=ja_JP',
'--disable-dev-shm-usage'
]);
$ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.91 Mobile/15E148 Safari/605.1';
$options->setExperimentalOption('mobileEmulation', ['userAgent' => $ua]);
return RemoteWebDriver::create(
'http://selenium:4444/wd/hub', DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY, $options
)
);
}
head部分のテスト
duskはcssセレクターで検証しようとすると先頭に'body'がつくため、bodyタグより上の要素の検証をしたい場合はこの書き方で
$browser->assertSourceHas("<meta name=\"description\" content=\"Qiitaは情報満載!\">");
xpathを使って要素の値を取り出すことも可能
use Laravel\Dusk\Browser;
use Facebook\WebDriver\WebDriverBy; //xpath用
略
$browser->driver->findElement(WebDriverBy::xpath("//link[@rel='canonical']"))->getAttribute('href')
Rspec の before after のようなものを実装したい
[参考]
https://cpoint-lab.co.jp/article/201812/7155/
public function setUp() :void
{
parent::setUp();
// テストデーターの準備などを行う
}
PHPUnitのアサーションも使えます
$this->assertEquals($element_count, 50);
セッションの破棄
$browser->driver->manage()->deleteAllCookies();
function日本語化(@testつける)
/**
* @test
*/
public function ステータステスト()
{
$res = $this->get("url");
$res->assertStatus(200);
}
テストをグループ化して実行 (@group アノテーションでグループ化)
php artisan dusk tests/Browser/ --group samplegroup
/**
* @group samplegroup
*/
public function sampleTest()
{
//処理
テストをファイル単位で実行
php artisan dusk tests/Browser/SampleTest.php
Factoryで作成したデーターをテスト実行前に書き換える方法
$this->test_data->fill(["time" => "9:00"])->save();
複数でもOK
$data = ["status" => 1, "time" => "9:00", "end_time" => "10:00"];
$this->test_data->fill($data)->save();
The MAC is invalid.
暗号化キーを再生成する → php artisan key:generate
※暗号化したパスワードが複号できなくなるので取り扱い注意
[引用]
https://error-search.com/error-post/detail/144/The%2BMAC%2Bis%2Binvalid.
APP_DEBUG=true のデバックモードにしたままでテストを実行するとfailする
デバックバーが邪魔をして要素が見えていないため
APP_DEBUG=true は.env.dusk.localに入れない
HTML5 Form Validation ブラウザに依存するエラーメッセージがテストの邪魔をする
問題なければ、ブラウザ自動バリデーションを無効化してしまう
<form action="test.php" method="post" novalidate="novalidate">