発生した問題
RSpecでsystem specを実行すると以下のようなエラーが出る。
具体的には下記2つが発生
Got 0 failures and 2 other errors:
1.1) Failure/Error: visit root_path
Selenium::WebDriver::Error::SessionNotCreatedError:
session not created: Chrome failed to start: exited normally.
(session not created: DevToolsActivePort file doesn't exist)
(The process started from chrome location /opt/google/chrome/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
1.2) Failure/Error: Unable to infer file and line number from backtrace
Selenium::WebDriver::Error::SessionNotCreatedError:
session not created: Chrome failed to start: exited normally.
(session not created: DevToolsActivePort file doesn't exist)
(The process started from chrome location /opt/google/chrome/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
開発環境
- Rails 6.0.6.1
- Ruby 2.7.7
- rspec-rails 5.1.2
- webdrivers 5.3.1
- selenium-webdriver 4.9.0
- capybara 3.39.2
原因
Google Chromeが起動しなかった
- D-Busを起動していなかった
- Windows環境にxserverをインストールしていなかった
- WSL2を使用する場合、特殊なDISPLAY変数の設定方法をする必要がある場合もある
解決方法
-
D-Busを起動する
$ sudo service dbus start
-
xserverをインストール
下記サイトを参考にVcXsrvをインストールし、起動
-
DISPLAY変数の設定
下記を
.bashrc
に記載// .bashrc export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
上記で無事動くようになりました!
正しい原因にたどり着くまでかなり紆余曲折してしまったので、以下にデバッグの全過程を記録として残します。
デバッグの全過程
やったこと① chromedriverのインストール
ChatGPTを使用して状況確認
以下の回答を得る
このエラーは、Chromeブラウザが起動できないために発生しています。DevToolsActivePort file doesn't exist というエラーメッセージは、Chromeブラウザが正しく起動しなかったことを示しています。
chromedriverのインストール
まずインストールしたGoogle Chromeのバージョンを確認
$ /usr/bin/google-chrome --version
Google Chrome 128.0.6613.119
次に、chromedriverを確認したところインストールされていないことが発覚。
Google Chromeのバージョンに合わせたDriverを下記で確認しインストールし、/usr/bin/に移動して実行権限を付与
https://googlechromelabs.github.io/chrome-for-testing/#stable
$ wget https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chromedriver-linux64.zip
$ unzip chromedriver-linux64.zip
$ sudo mv chromedriver-linux64/chromedriver /usr/bin/
$ sudo chmod +x /usr/bin/chromedriver
念の為バージョン情報を表示して、Google Chromeのバージョンとあっていることを確認
~$ /usr/bin/chromedriver --version
ChromeDriver 128.0.6613.119 (6e439cfca4deda5954b0c74cde9b521c03cb31ad-refs/branch-heads/6613@{#1464})
再度テストを実行
全く同じエラーが継続
やったこと② Google Chromeとchromedriverのダウングレード
下記の記事を確認
RSpecを実行するとWebdrivers::VersionErrorが発生する場合の対処方法
エラーメッセージは異なるが、古いバージョンのRubyで不具合が出るという記述から互換性が原因と推測
webdrivers
のバージョンを確認したところ、5.3.1 だったため、記事記載の内容が正しければ機能しそうだと感じたが、
念の為Google Chromeとchromedriverのダウングレードを試してみることにする
現行バージョンを削除し、旧バージョンのダウンロードとインストール
Google Chrome Older Versions Download (Windows, Linux & Mac)
から旧バージョンのGoogle Chromeをインストール、併せて公式サイトから旧バージョンのchromedriverをインストールした
$ wget https://www.slimjet.com/chrome/download-chrome.php?file=files%2F104.0.5112.102%2Fgoogle-chrome-stable_current_amd64.deb
$ sudo apt install ./'download-chrome.php?file=files%2F104.0.5112.102%2Fgoogle-chrome-stable_current_amd64.deb'
$ sudo apt-mark hold google-chrome-stable //自動アップデートを防ぐ設定
$ wget https://chromedriver.storage.googleapis.com/104.0.5112.79/chromedriver_linux64.zip
$ unzip chromedriver-linux64.zip
$ sudo mv chromedriver-linux64/chromedriver /usr/bin/
$ sudo chmod +x /usr/bin/chromedriver
※バージョンも確認し、適切にダウングレードできていることを確認
結果
全く同じエラーが継続
Google Chromeとdriverを最新バージョンに戻す
やったこと③ Google Chromeの手動起動調査
手動でGoogle Chromeの起動を試みても起動しない
$ google-chrome
[13003:13029:0911/201522.846322:ERROR:bus.cc(407)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[13003:13003:0911/201522.849773:ERROR:ozone_platform_x11.cc(244)] Missing X server or $DISPLAY
[13003:13003:0911/201522.849860:ERROR:env.cc(258)] The platform failed to initialize. Exiting.
エラーの解釈
-
/run/dbus/system_bus_socket
が存在しない、あるいはアクセスできない -
X server or $DISPLAY
が存在しない、あるいはアクセスできない
socketについてのデバッグ
- system_bus_socketの存在確認
-
system_bus_socketの存在確認
$ ls /run/dbus/system_bus_socket ls: cannot access '/run/dbus/system_bus_socket': No such file or directory
上記からファイルが存在しないか、D-Busが起動していない可能性がある
-
D-Busのステータス確認
$ sudo service dbus status * dbus is not running
-
D-Busを起動
$ sudo service dbus start * Starting system message bus dbus [ OK ]
-
system_bus_socketの再確認
$ ls /run/dbus/system_bus_socket /run/dbus/system_bus_socket
これでsocketは存在していそう!
-
あらためてGoogle Chromeの起動を試みる
$ google-chrome [5817:5817:0912/142950.762496:ERROR:ozone_platform_x11.cc(244)] Missing X server or $DISPLAY [5817:5817:0912/142950.762629:ERROR:env.cc(258)] The platform failed to initialize. Exiting.
次はX Serverか$DISPLAYを何とかする必要がある
-
Xserverについてのデバッグ
-
XServerの起動確認
$ ps aux | grep Xorg omi 5876 0.0 0.0 4024 1984 pts/0 S+ 14:41 0:00 grep --color=auto Xorg
-
ps
はプロセスを取得 -
a
はすべてのユーザー -
u
はユーザーやCPU使用率などの情報も含めて表示 -
x
はターミナルに関連づいていないプロセスも含めて表示 -
|
は左の処理を右の処理に渡す意図 -
grep Xorg
でXサーバーのプロセスをフィルタリング
表示されているのはこのコマンド自体の情報なので、結論XServerが起動できていなさそう
-
-
XServerのインストール
WSL上でXServerを使う場合、Windows側にXServerをインストールして、Ubuntu上でDISPLAY環境変数を設定する必要があるらしい。
そのため、下記のサイトを参照し、VcXsrvをインストールした。
-
Ubuntu上で$DISPLAYの設定
$ export DISPLAY=localhost:0.0
-
VcXsrvでXserverを起動
ショートカット作成せず、検索にもなぜか引っかからなかったので地味に探すの手間取った><Programfile/VcXsrvからvcxsrv.exeを起動
起動時の設定は下記の通り
-
Display settings:
- "Multiple windows" を選択
-
"Display number" は
0
-
Client startup:
- "Start no client" を選択
-
Extra settings:
- "Disable access control" を選択
-
Display settings:
-
Xserverの起動を再確認
下記の通り、変わらず…
$ ps aux | grep Xorg omi 6171 0.0 0.0 4024 2020 pts/0 S+ 22:08 0:00 grep --color=auto Xorg
可能性として、下記が挙げられる
-
xserverが起動できていない
⇒ステータスバーにアイコンはちゃんと表示されている
-
起動できているが何かしらのエラーが有る
⇒ログを確認したところ、特に問題はなさそう
-
Windows側のxserverとWSL側の連携がうまく取れていない
⇒これかも…chatGPTはこれについてはあまり答えてくれないので、Google検索
-
-
Ubuntu google chrome Missing X server or $DISPLAYで検索
- 有用そうな記事をいくつか見つける
-
$DISPLAYの設定を変更
-
下記を
.bashrc
に記載// .bashrc export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0
-
.bashrcを再読み込み
$ source ~/.bashrc
-
正しく読み込まれているか確認
~$ echo $DISPLAY 172.xx.xxx.x:0.0
-
Google Chromeの起動を試みる
~$ google-chrome なんだかたくさんのエラー
が、その後Google Chromeの画面が立ち上がる…!
たくさんのエラーはD-Busに関連するもので、$DISPLAYをいじったことが関係していそうな印象だが、いったん動作するので解消まではしないことにする。
-
今回のデバッグで学んだこと
-
socket
- socketとは、クライアントとサーバーのやり取りのための通路のようなもので、どこに情報を送るのか、どこに情報を受け取るのかということを規定する役割がある
- IPアドレスの指定とポート番号の指定の2つの役割がメイン
- ソケットファイルの種類
- UNIXドメインソケットファイル:同じマシン上のプロセス間で通信するためのもの
- ネットワークソケットファイル:ネットワーク上のプロセス間で通信するためのもの。IPアドレスとポート番号を持つのはこれ
- 一般的なソケットファイル:アプリケーションやサービスがプロセス間通信をするためのもの
-
/run/dbus/system_bus_socket
とは?- D-Bus(Desktop Bus)というプロセス間通信システムで使われるソケットファイルです。このソケットは、特にLinuxシステム上で動作するプロセス同士がデータをやり取りするための「通信経路」として機能します。
- 種類としてはUNIXドメインソケット
- ソケットファイル内になにか具体的なデータが記載されているわけではない。接続ポイントとして機能するらしい。よくわからん。
- Server起動時に生成され、終了時に消滅する=>Serverを起動しないといけない!
- socketとは、クライアントとサーバーのやり取りのための通路のようなもので、どこに情報を送るのか、どこに情報を受け取るのかということを規定する役割がある
-
XServer、$DISPLAYとは
- XServer
- GUIを使うためのソフトウェア
- アプリケーションがグラフィカルな表示をおこなうためのサーバーとして機能する
- 通常はLinuxログイン時に起動する
- $DISPLAY
- 環境変数の一つで、X Serverがどこで動作しているかを指定するためのもの
- 通常はXSERVER起動時に生成される
- 関係性
-
X Serverをカフェの店員だとすると、$DISPLAYはそのカフェのどのテーブルでコーヒーを出すかの指定です。バリスタ(X Server)がカフェ(コンピュータ)でコーヒー(グラフィカルな表示)を提供し、テーブル番号(
$DISPLAY
)でどのテーブルにコーヒーを運ぶかを決めるイメージです。
-
X Serverをカフェの店員だとすると、$DISPLAYはそのカフェのどのテーブルでコーヒーを出すかの指定です。バリスタ(X Server)がカフェ(コンピュータ)でコーヒー(グラフィカルな表示)を提供し、テーブル番号(
- XServer
-
.bashrcとは
- シェル起動時に自動で読み込まれるファイル
- コマンドのエイリアスや環境変数を設定などにも使われている