Laravel Sail+Dusk运行测试报错net::ERR_CONNECTION_REFUSED求助
Laravel Sail + Dusk + Selenium 连接拒绝问题排查与解决
问题概述
基于Laravel Sail搭建Docker本地开发环境,环境自带selenium/standalone-chrome容器。安装Dusk后,在sail-8.3/app容器内执行php artisan dusk时触发net::ERR_CONNECTION_REFUSED错误,尝试启动php artisan serve后问题未解决。
报错信息
FAILED Tests\Browser\HomePageTest > example UnknownErrorException unknown error: net::ERR_CONNECTION_REFUSED (Session info: chrome=126.0.6478.114) at vendor/php-webdriver/webdriver/lib/Exception/WebDriverException.php:146 142▕ throw new UnexpectedAlertOpenException($message, $results); 143▕ case 'unknown command': 144▕ throw new UnknownCommandException($message, $results); 145▕ case 'unknown error': ➜ 146▕ throw new UnknownErrorException($message, $results); 147▕ case 'unknown method': 148▕ throw new UnknownMethodException($message, $results); 149▕ case 'unsupported operation': 150▕ throw new UnsupportedOperationException($message, $results); +5 vendor frames 6 tests/Browser/HomePageTest.php:18 7 tests/Browser/HomePageTest.php:17
相关配置与代码
DuskTestCase.php
abstract class DuskTestCase extends BaseTestCase { /** * Prepare for Dusk test execution. */ #[BeforeClass] public static function prepare(): void { if (! static::runningInSail()) { static::startChromeDriver(); } } /** * Create the RemoteWebDriver instance. */ protected function driver(): RemoteWebDriver { $options = (new ChromeOptions)->addArguments(collect([ $this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080', ])->unless($this->hasHeadlessDisabled(), function (Collection $items) { return $items->merge([ '--disable-gpu', '--headless=new', ]); })->all()); return RemoteWebDriver::create( $_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515', DesiredCapabilities::chrome()->setCapability( ChromeOptions::CAPABILITY, $options ) ); } }
HomePageTest.php
class HomePageTest extends DuskTestCase { use DatabaseMigrations; /** * A Dusk test example. */ public function testExample(): void { $this->browse(function (Browser $browser) { $browser->visit('/') ->assertSee('Login'); }); } }
.env配置
已添加:
DUSK_DRIVER_URL=http://selenium:4444
Selenium容器日志
07:43:16.595 INFO [LocalSessionMap.lambda$new$0] - Deleted session from local Session Map, Id: d6234a0ba83b4ac0de1e5c6b70fb616b 07:43:16.595 INFO [GridModel.release] - Releasing slot for session id d6234a0ba83b4ac0de1e5c6b70fb616b 07:43:16.596 INFO [SessionSlot.stop] - Stopping session d6234a0ba83b4ac0de1e5c6b70fb616b 07:43:17.150 INFO [LocalDistributor.newSession] - Session request received by the Distributor: [Capabilities {browserName: chrome, goog:chromeOptions: {args: [--window-size=1920,1080, --disable-gpu, --headless=new]}}] 07:43:17.312 INFO [LocalNode.newSession] - Session created by the Node. Id: 8b9c90b80c4e711d8781e204ab55331f, Caps: Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 126.0.6478.114, chrome: {chromedriverVersion: 126.0.6478.63 (df799988fdc9..., userDataDir: /tmp/.org.chromium.Chromium...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:45535}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: linux, proxy: Proxy(), se:bidiEnabled: false, se:cdp: ws://172.22.0.6:4444/sessio..., se:cdpVersion: 126.0.6478.114, se:vnc: ws://172.22.0.6:4444/sessio..., se:vncEnabled: true, se:vncLocalAddress: ws://172.22.0.6:7900, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true} 07:43:17.315 INFO [LocalDistributor.newSession] - Session created by the Distributor. Id: 8b9c90b80c4e711d8781e204ab55331f Caps: Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 126.0.6478.114, chrome: {chromedriverVersion: 126.0.6478.63 (df799988fdc9..., userDataDir: /tmp/.org.chromium.Chromium...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:45535}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: linux, proxy: Proxy(), se:bidiEnabled: false, se:cdp: ws://172.22.0.6:4444/sessio..., se:cdpVersion: 126.0.6478.114, se:vnc: ws://172.22.0.6:4444/sessio..., se:vncEnabled: true, se:vncLocalAddress: ws://172.22.0.6:7900, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true} 07:43:17.441 WARN [SeleniumSpanExporter$1.lambda$export$3] - {"traceId": "a9a833dc373529e36ebc4b22b4b6b57d","eventTime": 1721893397440430947,"eventName": "HTTP request execution complete","attributes": {"http.flavor": 1,"http.handler_class": "org.openqa.selenium.remote.http.Route$PredicatedRoute","http.host": "selenium:4444","http.method": "POST","http.request_content_length": "35","http.scheme": "HTTP","http.status_code": 500,"http.target": "\u002fsession\u002f8b9c90b80c4e711d8781e204ab55331f\u002furl"}} 07:43:17.869 INFO [LocalSessionMap.lambda$new$0] - Deleted session from local Session Map, Id: 8b9c90b80c4e711d8781e204ab55331f 07:43:17.870 INFO [GridModel.release] - Releasing slot for session id 8b9c90b80c4e711d8781e204ab55331f 07:43:17.872 INFO [SessionSlot.stop] - Stopping session 8b9c90b80c4e711d8781e204ab55331f
排查与解决步骤
1. 明确错误根源
从Selenium日志可以看到,Dusk已经成功与Selenium建立会话(Session created by the Node),所以不是Dusk连不上Selenium,而是运行在Selenium容器内的Chrome浏览器无法访问你的Laravel应用。
Chrome容器内的localhost指向自身,而非app容器,直接访问/会导致连接拒绝。
2. 配置Dusk的基础访问地址
在.env中添加Dusk的基础URL,指定app容器的服务名(Sail默认app容器服务名为app):
DUSK_BASE_URL=http://app:80
或者直接在测试用例中指定完整地址:
public function testExample(): void { $this->browse(function (Browser $browser) { $browser->visit('http://app:80/') ->assertSee('Login'); }); }
3. 停止不必要的php artisan serve
Sail的app容器已经通过Nginx监听80端口提供服务,不需要额外启动php artisan serve,这会占用端口并导致冲突。执行以下命令停止该服务(在app容器内):
pkill -f "php artisan serve"
4. 验证容器间网络连通性
- 在app容器内测试Selenium连通性:
应返回Selenium Grid的页面。curl http://selenium:4444 - 在Selenium容器内测试app连通性:
应返回Laravel应用的页面。docker exec -it <selenium-container-id> curl http://app:80
日志警告解析
日志中的HTTP status_code: 500是Selenium处理Chrome访问请求时的内部错误,根源是Chrome无法访问应用地址,解决应用地址配置后该警告会自动消失。
内容的提问来源于stack exchange,提问作者fudo
相关产品推荐
相关产品推荐

