
在 Laravel Dusk 自动化测试中,处理浏览器权限(如剪贴板访问)是常见的挑战。本文将详细介绍如何通过扩展 `DuskTestCase` 类,利用 `ChromeDevToolsDriver` 执行 `Browser.grantPermissions` 命令,从而在测试运行时程序化地授予特定权限。这将使开发者能够更全面地测试依赖于浏览器权限的用户界面功能,确保测试流程的顺畅与完整性。
自动化测试中的浏览器权限挑战
在进行端到端(E2E)测试时,自动化工具如 Laravel Dusk 模拟用户与 Web 应用程序的交互。然而,现代浏览器为了安全和隐私,会对某些敏感操作(例如访问剪贴板、地理位置、摄像头或麦克风)进行权限提示。在无头(headless)模式或自动化测试环境中,这些权限提示会阻断测试流程,导致测试失败。传统的点击授权方式在自动化测试中往往不可行,因此需要一种程序化的方式来预先授予必要的权限。
通过 Chrome DevTools 协议授予权限
Laravel Dusk 基于 Selenium WebDriver,而 Chrome 浏览器提供了一套强大的 DevTools 协议,允许开发者工具或自动化脚本直接与浏览器进行低级别通信。Facebook/WebDriver/Chrome/ChromeDevToolsDriver 类正是连接 WebDriver 与 Chrome DevTools 协议的桥梁。我们可以利用这个类来执行 Browser.grantPermissions 命令,从而在测试开始前或特定测试步骤中授予所需的浏览器权限。
实现权限授予辅助方法
为了方便在多个测试用例中复用权限授予逻辑,建议在 tests/DuskTestCase.php 文件中添加一个辅助方法。
<?php
namespace Tests;
use Facebook/WebDriver/Chrome/ChromeDevToolsDriver;
use Laravel/Dusk/Browser;
use Laravel/Dusk/TestCase as BaseTestCase;
abstract class DuskTestCase extends BaseTestCase
{
use CreatesApplication;
/**
* 授予浏览器特定权限。
*
* @param Browser $browser 当前的 Dusk 浏览器实例。
* @param array $permissions 要授予的权限数组,例如 ["clipboardReadWrite", "clipboardSanitizedWrite"]。
* @return mixed DevTools 命令的执行结果,或 null(如果发生异常)。
*/
protected function grantPermission(Browser $browser, array $permissions)
{
try {
$driver = $browser->driver;
// 创建 ChromeDevToolsDriver 实例,用于执行 DevTools 命令
$devtools = new ChromeDevToolsDriver($driver);
// 执行 Browser.grantPermissions 命令
// "permissions" 参数是一个字符串数组,指定要授予的权限类型
// 更多权限类型请参考 Chrome DevTools 协议文档
$result = $devtools->execute('Browser.grantPermissions', [
"permissions" => $permissions,
// "origin" 参数可选,指定权限作用的源,
// 如果不指定,通常会作用于当前页面或默认源。
// 在多数 Dusk 测试场景中,通常无需显式指定。
]);
return $result;
} catch (/Exception $e) {
// 捕获异常,例如 DevTools 命令执行失败
// 可以在此处记录日志或根据需要处理错误
error_log("Failed to grant permissions: " . $e->getMessage());
return null;
}
}
}
代码解释:
- $browser->driver:获取当前 Dusk 浏览器实例底层的 WebDriver 实例。
- new ChromeDevToolsDriver($driver):使用 WebDriver 实例初始化 ChromeDevToolsDriver,这是与 Chrome DevTools 协议通信的关键。
- $devtools->execute(‘Browser.grantPermissions’, […]):调用 DevTools 协议中的 Browser.grantPermissions 命令。
- “permissions”:这是一个字符串数组,包含了需要授予的具体权限标识符。例如,clipboardReadWrite 和 clipboardSanitizedWrite 用于读写剪贴板。其他常见的权限还包括 geolocation (地理位置)、camera (摄像头) 和 microphone (麦克风) 等。
- “origin”:这是一个可选参数,用于指定权限生效的源。在大多数 Dusk 测试场景中,由于测试通常在当前页面进行,因此可以省略或让其默认。
在测试用例中使用权限授予方法
一旦 grantPermission 方法被添加到 DuskTestCase 中,你就可以在任何继承自 DuskTestCase 的 Dusk 测试用例中调用它。
<?php
namespace Tests/Browser;
use Laravel/Dusk/Browser;
use Tests/DuskTestCase;
class ExampleTest extends DuskTestCase
{
/**
* 测试剪贴板复制功能。
*
* @return void
*/
public function testClipboardFunctionality()
{
$this->browse(function (Browser $browser) {
// 在执行需要剪贴板权限的操作之前,授予权限
$this->grantPermission($browser, ["clipboardReadWrite", "clipboardSanitizedWrite"]);
// 模拟用户操作,例如点击复制按钮
$browser->visit('/some-page-with-copy-button')
->click('#copy-button');
// 验证剪贴板内容(可能需要额外的 JavaScript 来获取剪贴板内容并断言)
// 例如:
// $clipboardContent = $browser->script('return navigator.clipboard.readText()')[0];
// $this->assertEquals('Expected content', $clipboardContent);
// 注意:直接从浏览器获取剪贴板内容可能需要进一步的实现,
// 因为 Dusk 默认的 `script` 方法在某些情况下可能无法直接访问到
// 浏览器上下文的 `navigator.clipboard`。
// 更可靠的方法可能是让你的应用在复制后将内容存储在某个可访问的 DOM 元素或 JS 变量中。
});
}
/**
* 测试需要地理位置权限的功能。
*
* @return void
*/
public function testGeolocationFeature()
{
$this->browse(function (Browser $browser) {
// 授予地理位置权限
$this->grantPermission($browser, ["geolocation"]);
// 模拟访问需要地理位置的页面
$browser->visit('/map-page')
->assertSee('Your current location');
// 进一步的断言,例如检查地图是否正确显示或位置信息是否被获取
});
}
}
注意事项与最佳实践
- 浏览器兼容性: ChromeDevToolsDriver 和 Browser.grantPermissions 命令是 Chrome/Chromium 浏览器特有的。如果你的 Dusk 测试需要支持其他浏览器(如 Firefox),你需要寻找对应浏览器的权限管理机制或替代方案。
- 权限列表: 不同的权限有不同的字符串标识符。请查阅 Chrome DevTools 协议文档 以获取完整的权限列表和其对应的字符串。
- 测试隔离: 每次测试完成后,浏览器环境通常会重置,包括权限状态。但在某些复杂场景下,为了确保测试之间的完全隔离,你可能需要考虑在测试结束后显式地撤销权限(尽管 Browser.grantPermissions 协议中没有直接的 revokePermissions 命令,但通常每次测试运行都是一个新的浏览器上下文)。
- 错误处理: 在 grantPermission 方法中加入异常捕获和日志记录,可以帮助你调试权限授予失败的情况。
总结
通过利用 Laravel Dusk 的底层能力和 Chrome DevTools 协议,我们可以有效地在自动化测试中管理浏览器权限。这种方法不仅解决了因权限提示导致的测试中断问题,还使得对依赖敏感浏览器功能的应用程序进行端到端测试成为可能,从而提高了测试的覆盖率和可靠性。掌握这一技巧,将使你的 Laravel Dusk 测试套件更加健壮和全面。
以上就是Laravel Dusk:通过 DevTools 协议管理浏览器权限的详细内容,更多请关注php中文网其它相关文章!


