# Laravel 測試之 - 瀏覽器測試 (Laravel Dusk)
- [簡介](#introduction)
- [安裝](#installation)
- [使用其他瀏覽器](#using-other-browsers)
- [開始](#getting-started)
- [創建測試](#generating-tests)
- [運行測試](#running-tests)
- [環境處理](#environment-handling)
- [創建瀏覽器](#creating-browsers)
- [認證](#authentication)
- [與元素交互](#interacting-with-elements)
- [點擊鏈接](#clicking-links)
- [文本、值和屬性](#text-values-and-attributes)
- [使用表單](#using-forms)
- [附加文件](#attaching-files)
- [使用鍵盤](#using-the-keyboard)
- [使用鼠標](#using-the-mouse)
- [元素作用域](#scoping-selectors)
- [等待元素](#waiting-for-elements)
- [可用的斷言](#available-assertions)
- [頁面](#pages)
- [創建頁面](#generating-pages)
- [配置頁面](#configuring-pages)
- [導航至頁面](#navigating-to-pages)
- [選擇器簡寫](#shorthand-selectors)
- [頁面方法](#page-methods)
- [持續集成](#continuous-integration)
- [Travis CI](#running-tests-on-travis-ci)
- [CircleCI](#running-tests-on-circle-ci)
<a name="introduction"></a>
## 簡介
Laravel Dusk 提供了富有表現力、簡單易用的瀏覽器自動化以及相應的測試 API。Dusk 只需要使用一個單獨的 [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/home),不再需要在你的機器中安裝 JDK 或者 Selenium。不過,依然可以按照你自己的需要安裝其他 Selenium 兼容的驅動引擎。
<a name="installation"></a>
## 安裝
將 `laravel/dusk` 添加到你的項目 Composer 依賴中:
composer require --dev laravel/dusk
> {note} 永遠不要在生產環境安裝 Dusk。否則,任何人都可以未經授權地訪問你的應用。
安裝了 Dusk 之后,你需要注冊 `Laravel\Dusk\DuskServiceProvider` 服務提供者。通常,這將通過 Laravel 的服務提供者自動發現機制去自動完成。
接下來運行 `dusk:install` Artisan 命令:
php artisan dusk:install
這將會在你的 `tests` 目錄下創建一個 `Browser` 目錄,同時包含了一個測試用例模版。然后在你的 `.env` 文件中設置 `APP_URL` 環境變量。這個變量值要與你在瀏覽器訪問你應用的 URL 一致。
使用 `dusk` Artisan 命令來運行你的測試。`dusk` 命令可以接受任何 `phpunit` 能接受的參數:
php artisan dusk
<a name="using-other-browsers"></a>
### 使用其他瀏覽器
Dusk 默認使用 Google Chrome 和 [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/home) 來運行你的瀏覽器測試。當然,你也可以運行你的 Selenium 服務器,然后對任何你想要的瀏覽器運行測試。
打開你的 `tests/DuskTestCase.php` 文件,這個文件是你應用中最基礎的 Dusk 測試用例。你可以在這個文件中移除 `startChromeDriver` 方法。這樣 Dusk 就不會自動運行 ChromeDriver:
/**
* 為 Dusk 的測試做準備。
*
* @beforeClass
* @return void
*/
public static function prepare()
{
// static::startChromeDriver();
}
然后,你可以通過簡單地修改 `driver` 方法來連接到你指定的 URL 和端口。同時,你要修改傳遞給 WebDriver 的「desired capabilities」:
/**
* 創建 RemoteWebDriver 實例。
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
return RemoteWebDriver::create(
'http://localhost:4444/wd/hub', DesiredCapabilities::phantomjs()
);
}
<a name="getting-started"></a>
## 開始
<a name="generating-tests"></a>
### 創建測試
使用 `dusk:make` Artisan 命令來創建 Dusk 測試。創建好的測試類會放在 `tests/Browser` 目錄:
php artisan dusk:make LoginTest
<a name="running-tests"></a>
### 運行測試
使用 `dusk` Artisan 命令來運行你的瀏覽器測試:
php artisan dusk
`dusk` 命令可以接受任何 PHPUnit 能接受的參數。例如,讓你可以只在指定 [分組](https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group) 中運行測試:
php artisan dusk --group=foo
#### 手動運行 ChromeDriver
Dusk 默認會嘗試自動運行 ChromeDriver。如果在你特定的系統中不能正常運行,你可以在運行 `dusk` 命令之前通過手動的方式來運行 ChromeDriver。如果你選擇手動運行 ChromeDriver,你需要在你的 `tests/DuskTestCase.php` 文件中注釋掉下面這行:
/**
* 為 Dusk 的測試做準備。
*
* @beforeClass
* @return void
*/
public static function prepare()
{
// static::startChromeDriver();
}
另外,如果你是在非 9515 端口運行 ChromeDriver,你需要在 `tests/DuskTestCase.php` 修改 `driver` 方法:
/**
* 創建 RemoteWebDriver 實例。
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
return RemoteWebDriver::create(
'http://localhost:9515', DesiredCapabilities::chrome()
);
}
<a name="environment-handling"></a>
### 環境處理
在你項目的根目錄創建 `.env.dusk.{environment}` 文件來強制 Dusk 使用自己的的環境文件來運行測試。簡單來說,如果你想要以 `local` 環境來運行 `dusk` 命令,你需要創建一個 `.env.dusk.local` 文件。
運行測試的時候,Dusk 會備份你的 `.env` 文件,然后重命名你的 Dusk 環境文件為 `.env`。一旦測試結束之后,將會恢復你的 `.env` 文件。
<a name="creating-browsers"></a>
### 創建瀏覽器
讓我們來寫一個測試用例,這個測試用例可以驗證我們是否能夠登錄系統。生成測試類之后,我們修改這個類,讓它可以跳轉到登錄頁面,輸入某些登錄信息,點擊「登錄」按鈕。使用 `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;
/**
* 一個基本的瀏覽器測試示例。
*
* @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 會自動將這個瀏覽器實例注入到回調當中,而這個瀏覽器實例可以讓你與你的應用之間進行交互和斷言。
> {tip} 這個測試用例可以測試由 `make:auth` Artisan 命令來生成的登錄頁面。
#### 創建多個瀏覽器
有時你可能需要多個瀏覽器才能正確地進行測試。例如,你可能需要使用多個瀏覽器測試通過 websockets 通訊的在線聊天頁面。要想創建多個瀏覽器,你只需要簡單地在 `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');
});
<a name="authentication"></a>
### 認證
你可能經常會測試一些需要認證的頁面。你可以使用 Dusk 的 `loginAs` 方法來避免每個測試都去登錄頁面登錄一次。`loginAs` 方法可以使用用戶 ID 或者用戶模型實例:
$this->browse(function ($first, $second) {
$first->loginAs(User::find(1))
->visit('/home');
});
> {note} 使用 `loginAs` 方法后, 該用戶的 session 將會持久化供其他測試用例使用。
<a name="interacting-with-elements"></a>
## 與元素交互
<a name="clicking-links"></a>
### 點擊鏈接
你可以在你的瀏覽器實例中使用 `clickLink` 方法來模擬點擊一個鏈接。`clickLink` 方法會點擊傳入的顯示文本:
$browser->clickLink($linkText);
> {note} 這方法基于 JQuery 來進行交互。如果頁面中沒有可用的 jQuery,Dusk 會自動將 jQuery 注入到頁面中。所以他可能會增加測試的時間。
<a name="text-values-and-attributes"></a>
### 文本、值和屬性
#### 獲取和設置值
Dusk 提供了幾種方法讓你和當前頁面元素中的顯示文本、值和屬性進行交互。例如,想獲得某個指定選擇器對應元素的「值」,你可以使用 `value` 方法:
// 獲取值...
$value = $browser->value('selector');
// 設置值...
$browser->value('selector', 'value');
#### 獲取文本
`text` 方法用來獲取匹配指定選擇器的元素的顯示文本:
$text = $browser->text('selector');
#### 獲取屬性
`attribute` 方法用來獲取匹配指定選擇器的元素的屬性:
$attribute = $browser->attribute('selector', 'value');
<a name="using-forms"></a>
### 使用表單
#### 輸入值
Dusk 提供了與表單和 input 元素交互的各種方法。首先,讓我們來看看一個在 input 框中輸入文本的示例:
$browser->type('email', 'taylor@laravel.com');
注意:雖然 `type` 方法可以傳遞 CSS 選擇器作為第一個參數,但這并不是強制要求。如果傳入的不是 CSS 選擇器,Dusk 會嘗試匹配傳入值與 `name` 屬性相符的 input 框,如果沒找到,最后 Dusk 會嘗試查找匹配傳入值與 `name` 屬性相符的 `textarea`。
你可以使用 `clear` 方法來 「清除」 輸入值。
$browser->clear('email');
#### 下拉菜單
你可以使用 `select` 方法來選擇下來菜單中的某個選項。類似于 `type` 方法,`select` 方法并不是一定要傳入 CSS 選擇器。當你使用 `select` 方法的時候應該注意,你傳的值應該是選項實際的值,而不是顯示的值:
$browser->select('size', 'Large');
你也可以通過省略第二個參數來隨機選擇一個選項:
$browser->select('size');
#### 復選框
你可以使用 `check` 方法來選中某個復選框。像其他 input 相關的方法一樣,并不是必須傳入 CSS 選擇器。如果準確的選擇器沒法找到的時候,Dusk 會搜索與 `name` 屬性匹配的復選框:
$browser->check('terms');
$browser->uncheck('terms');
#### 單選按鈕
你可以使用 `radio` 方法來選擇某個單選選項。同樣的,并不是必須傳入 CSS 選擇器。如果準確的選擇器沒法找到的時候,Dusk 會搜索與 `name` 屬性或者 `value` 屬性匹配的單選按鈕:
$browser->radio('version', 'php7');
<a name="attaching-files"></a>
### 附加文件
`attach` 方法可以用來附加一個文件到 `file` input 框中。同樣的,并不是必須傳入 CSS 選擇器。如果準確的選擇器沒法找到的時候,Dusk 會搜索與 `name` 屬性匹配的文件輸入框:
$browser->attach('photo', __DIR__.'/photos/me.png');
<a name="using-the-keyboard"></a>
### 使用鍵盤
`keys` 方法讓你可以在指定元素中輸入比 `type` 方法更加復雜的輸入序列。例如,你可以在輸入值的同時按下按鍵。在本例中,在輸入 `taylor` 時,`shift` 按鍵也同時被按下,當 `taylor` 輸入完之后,`otwell` 則會正常輸入,不會按下任何按鍵:
$browser->keys('selector', ['{shift}', 'taylor'], 'otwell');
甚至你可以在你應用中選中某個元素之后按下 「快捷鍵」:
$browser->keys('.app', ['{command}', 'j']);
> {tip} 所有包在 `{}` 中的修飾按鍵,都應該與 `Facebook\WebDriver\WebDriverKeys` 類中定義的常量一致。你可以在 [GitHub 中找到這個類](https://github.com/facebook/php-webdriver/blob/community/lib/WebDriverKeys.php)。
<a name="using-the-mouse"></a>
### 使用鼠標
#### 點擊元素
`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);
<a name="scoping-selectors"></a>
### 元素作用域
有時候你可能希望在某個與選擇器匹配的元素中執行一系列的操作。例如,你可能希望在某個 table 中斷言有某些文本,然后在同一個 table 中點擊按鈕。你可以使用 `with` 方法來達到這個目的。`with` 方法的回調參數中,所有的操作都作用在同一個原始選擇器上:
$browser->with('.table', function ($table) {
$table->assertSee('Hello World')
->clickLink('Delete');
});
<a name="waiting-for-elements"></a>
### 等待元素
在測試應用的時候,由于經常會用到 JavaScript。所以經常需要在開始之前「等待」某些元素或者數據,以確保在測試中是有效可用的。Dusk 讓這變得簡單。使用一系列的方法,讓你可以等待頁面元素完全顯示,甚至是指定的 JavaScript 表達式返回 `true` 的時候才繼續執行測試:
#### 等待
如果你需要暫停指定毫秒數,你可以使用 `pause` 方法:
$browser->pause(1000);
#### 等待選擇器元素
`waitFor` 方法用來暫停測試的執行,直到與 CSS 選擇器匹配的元素顯示在頁面中。在拋出異常之前,默認最多暫停 5 秒。如果需要,你也可以自定義超時時間作為第二個參數傳給這個方法:
// 最多為這個元素的顯示等待 5 秒...
$browser->waitFor('.selector');
// 最多為這個元素的顯示等待 1 秒...
$browser->waitFor('.selector', 1);
你也可以等待指定元素直到超時都還在頁面中找不到:
$browser->waitUntilMissing('.selector');
$browser->waitUntilMissing('.selector', 1);
#### 可用元素的作用域
有時候,你可能想要等待與指定選擇器匹配的元素,然后與這元素進行交互。例如,你可能需要等待某個模態窗口可用,然后在模態窗口中點擊「OK」按鈕。在這種情況下,可以使用 `whenAvailable` 方法。所有閉包中的操作都針對這個原始的元素:
$browser->whenAvailable('.modal', function ($modal) {
$modal->assertSee('Hello World')
->press('OK');
});
#### 等待文本
`waitForText` 方法用于等待指定文本,直到顯示在頁面中為止:
// 最多為這個文本的顯示等待 5 秒...
$browser->waitForText('Hello World');
// 最多為這個文本的顯示等待 1 秒...
$browser->waitForText('Hello World', 1);
#### 等待超鏈接
`waitForLink` 方法用來等待指定鏈接文本,直到鏈接文本顯示在頁面中為止:
// 最多為這個鏈接的顯示等待 5 秒...
$browser->waitForLink('Create');
// 最多為這個鏈接的顯示等待 1 秒...
$browser->waitForLink('Create', 1);
#### 等待頁面跳轉
在進行例如 `$browser->assertPathIs('/home')`的路徑斷言時,如果 `window.location.pathname` 為異步完成,斷言就會失敗。你需要使用 `waitForLocation` 方法去等待指定的跳轉:
$browser->waitForLocation('/secret');
#### 等待頁面重載
如果你需要在頁面重載后進行斷言,你可以使用 `waitForReload` 方法:
$browser->click('.some-action')
->waitForReload()
->assertSee('something');
#### 等待 JavaScript 表達式
有時候你可能想要暫停測試用例的執行,直到指定的 JavaScript 表達式計算結果為 `true`。使用 `waitUntil` 方法可以讓你很容易做到這一點。傳遞表達式給方法的時候,你不需要包括 `return` 關鍵詞或者結束分號:
// 最多為表達式的成立等待 5 秒...
$browser->waitUntil('App.dataLoaded');
$browser->waitUntil('App.data.servers.length > 0');
// 最多為表達式的成立等待 1 秒...
$browser->waitUntil('App.data.servers.length > 0', 1);
#### 等待回調
Dusk 中的許多「等待」方法依賴于 `waitUsing` 方法。該方法可以等待一個回調返回 `true`。`waitUsing` 接受的參數為最大等待秒數、閉包的執行間隔、閉包以及一個可選的錯誤信息。
$browser->waitUsing(10, 1, function () use ($something) {
return $something->isReady();
}, "Something wasn't ready in time.");
<a name="available-assertions"></a>
## 可用的斷言
Dusk 為你的應用提供了一系列的斷言方法。所有的斷言方法都記錄在下面的表格中:
Assertion | Description
------------- | -------------
`$browser->assertTitle($title)` | 斷言頁面標題符合指定文本。
`$browser->assertTitleContains($title)` | 斷言頁面標題包含指定文本。
`$browser->assertPathBeginsWith($path)` | 斷言當前 URL 開始于指定的值。
`$browser->assertPathIs('/home')` | 斷言當前 URL 為指定的值。
`$browser->assertPathIsNot('/home')` | 斷言當前 URL 不是指定的值。
`$browser->assertRouteIs($name, $parameters)` | 斷言當前 URL 為指定的路由生成。
`$browser->assertQueryStringHas($name, $value)` | 斷言指定的查詢條件為指定的值。
`$browser->assertQueryStringMissing($name)` | 斷言不存在指定的查詢條件。
`$browser->assertHasQueryStringParameter($name)` | 斷言存在指定的查詢條件。
`$browser->assertHasCookie($name)` | 斷言存在指定 Cookie。
`$browser->assertCookieValue($name, $value)` | 斷言指定 Cookie 為指定值。
`$browser->assertPlainCookieValue($name, $value)` | 斷言一個未加密的 Cookie 為指定值。
`$browser->assertSee($text)` | 斷言頁面中存在指定文本。
`$browser->assertDontSee($text)` | 斷言頁面中不存在指定文本。
`$browser->assertSeeIn($selector, $text)` | 斷言匹配指定選擇器中存在指定文本。
`$browser->assertDontSeeIn($selector, $text)` | 斷言匹配指定選擇器中不存在指定文本。
`$browser->assertSourceHas($code)` | 斷言頁面的源碼中存在指定的值。
`$browser->assertSourceMissing($code)` | 斷言頁面的源碼中不存在指定的值。
`$browser->assertSeeLink($linkText)` | 斷言頁面中存在指定鏈接。
`$browser->assertDontSeeLink($linkText)` | 斷言頁面中不存在指定鏈接。
`$browser->assertInputValue($field, $value)` | 斷言指定的 input 輸入框為指定的值。
`$browser->assertInputValueIsNot($field, $value)` | 斷言指定的 input 輸入框不為指定的值。
`$browser->assertChecked($field)` | 斷言指定的復選框已被選中。
`$browser->assertNotChecked($field)` | 斷言指定的復選框未被選中。
`$browser->assertRadioSelected($field, $value)` | 斷言指定的單選框已被選中。
`$browser->assertRadioNotSelected($field, $value)` | 斷言指定的單選框未被選中。
`$browser->assertSelected($field, $value)` | 斷言指定的下拉列表指定的值被選中。
`$browser->assertNotSelected($field, $value)` | 斷言指定的下拉列表指定的值未被選中
`$browser->assertSelectHasOptions($field, $values)` | 斷言指定數組中的值存在于指定的下拉列表的選項中。
`$browser->assertSelectMissingOptions($field, $values)` | 斷言指定數組中的值不存在于指定的下拉列表的選項中。
`$browser->assertSelectHasOption($field, $value)` | 斷言指定的值存在于指定的下拉列表的選項中。
`$browser->assertValue($selector, $value)` | 斷言匹配指定選擇器的元素為指定值。
`$browser->assertVisible($selector)` | 斷言匹配指定選擇器的元素是可見的。
`$browser->assertMissing($selector)` | 斷言匹配指定選擇器的元素是不可見的。
`$browser->assertDialogOpened($message)` | 斷言消息為指定值的對話框已被打開。
<a name="pages"></a>
## Pages
有時候,測試有一些復雜的動作需要順序執行。 這很容易讓你的測試代碼變得難讀,并且難以理解。頁面允許你定義語義化的動作行為,然后你可以在指定頁面中使用單個方法。頁面也允許你為你的應用或者單個頁面定義簡寫的公共選擇器。
<a name="generating-pages"></a>
### 創建頁面
使用 `dusk:page` Artisan 命令來創建頁面對象。所有的頁面對象會存放在 `tests/Browser/Pages` 目錄中:
php artisan dusk:page Login
<a name="configuring-pages"></a>
### 配置頁面
頁面默認擁有 3 個方法: `url`, `assert` 和 `elements`。 在這里我們先詳述 `url` 和 `assert` 方法。`elements` 方法將會 [在下面詳細描述](#shorthand-selectors)。
#### `url` 方法
`url` 方法應該返回表示頁面 URL 的路徑。 Dusk 將會在瀏覽器中使用這個 URL 來導航到具體頁面:
/**
* Get the URL for the page.
*
* @return string
*/
public function url()
{
return '/login';
}
#### The `assert` Method
`assert` 方法可以作出任何斷言來驗證瀏覽器是否在指定頁面上。這個方法并不是必須的。你可以根據你自己的需求來做出這些斷言。這些斷言會在你瀏覽到這個頁面的時候自動執行:
/**
* 斷言瀏覽器是否正在指定頁面。
*
* @return void
*/
public function assert(Browser $browser)
{
$browser->assertPathIs($this->url());
}
<a name="navigating-to-pages"></a>
### 導航至頁面
一旦頁面配置好之后,你可以使用 `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');
<a name="shorthand-selectors"></a>
### 選擇器簡寫
`elements` 方法允許你為頁面中的任何 CSS 選擇器定義簡單易記的簡寫。例如,讓我們為應用登錄頁中的 `email` 輸入框定義一個簡寫:
/**
* 獲取頁面的元素簡寫。
*
* @return array
*/
public function elements()
{
return [
'@email' => 'input[name=email]',
];
}
現在你可以用這個簡寫來代替之前在頁面中使用的完整 CSS 選擇器:
$browser->type('@email', 'taylor@laravel.com');
#### 全局的選擇器簡寫
安裝 Dusk 之后,`Page` 基類存放在你的 `tests/Browser/Pages` 目錄。該類中包含一個 `siteElements` 方法,這個方法可以用來定義全局的選擇器簡寫,這樣在你應用中每個頁面都可以使用這些全局選擇器簡寫了:
/**
* 獲取站點全局的選擇器簡寫。
*
* @return array
*/
public static function siteElements()
{
return [
'@element' => '#selector',
];
}
<a name="page-methods"></a>
### 頁面方法
處理頁面中已經定義的默認方法之外,你還可以定義在整個測試過程中會使用到的其他方法。例如,讓我們假設一下我們正在開發一個音樂管理應用,在應用中都可能需要一個公共的方法來創建列表,而不是在每一頁、每一個測試類中都重寫一遍創建播放列表的邏輯,這時候你可以在你的頁面類中定義一個 `createPlaylist` 方法:
<?php
namespace Tests\Browser\Pages;
use Laravel\Dusk\Browser;
class Dashboard extends Page
{
// 其他頁面方法...
/**
* 創建一個新的播放列表。
*
* @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');
<a name="continuous-integration"></a>
## 持續集成
<a name="running-tests-on-travis-ci"></a>
### Travis CI
在 Travis CI 中運行 Dusk 時需要「sudo-enabled」的 Ubuntu 14.04 (Trusty) 環境。由于 Travis CI 不是圖形環境,我們需要一些額外的步驟去啟動 Chrome 瀏覽器,另外,我們需要使用 `php artisan serve` 命令去啟動 PHP 的內置服務器。
sudo: required
dist: trusty
addons:
chrome: stable
install:
- cp .env.testing .env
- travis_retry composer install --no-interaction --prefer-dist --no-suggest
before_script:
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
- php artisan serve &
script:
- php artisan dusk
<a name="running-tests-on-circle-ci"></a>
### CircleCI
#### CircleCI 1.0
在 CircleCI 1.0 中運行 Dusk 時需要使用以下配置進行啟動。與 TravisCI 相同,我們需要使用 `php artisan serve` 命令去啟動 PHP 的內置服務器。
dependencies:
pre:
- curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- sudo dpkg -i google-chrome.deb
- sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome
- rm google-chrome.deb
test:
pre:
- "./vendor/laravel/dusk/bin/chromedriver-linux":
background: true
- cp .env.testing .env
- "php artisan serve":
background: true
override:
- php artisan dusk
#### CircleCI 2.0
在 CircleCI 2.0 中運行 Dusk 時需要將以下 steps 添加至 build:
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
## 譯者署名
| 用戶名 | 頭像 | 職能 | 簽名 |
| --- | --- | --- | --- |
| [@springjk](https://laravel-china.org/users/4550) | <img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/4550_1464580958.png?imageView2/1/w/100/h/100"> | 翻譯 | 再怎么說我也是我西北一匹狼 |
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明