1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

go-rodでJSの入力バリデーションalertに阻まれた話と対処法

Last updated at Posted at 2025-08-28

要約 (TL;DR)

  • alert()/confirm()/prompt()/beforeunloadはJavaScriptをブロックする
  • Rodではgoroutineを使って処理することが推奨されている
	wait, handle := page.MustHandleDialog()
	go page.MustElement("button").MustClick()
	wait()
	handle(true, "")

rod/page.go at v0.116.2 #L384C1-L391 · go-rod/rod · GitHub

環境

What is go-rod?

A Chrome DevTools Protocol driver for web automation and scraping.
go-rodは、CDP(Chrome DevTools Protocol)を使ってブラウザ操作の自動化やスクレイピングを行うためのツールです。

事象

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Alert Sample</title>
</head>

<body>
  <input type="text" id="input" />
  <button id="btn_valid" onclick="document.getElementById('input').value.length > 2 ? alert('2文字以内で入力してください') : null;">Click me</button>
</body>
</html>
page := browser.MustPage("./sample.html")
page.MustElement("#input").MustInput("123")
page.MustElement("#btn_valid").MustClick()
// 後続処理...

上記は、入力フォームをJavaScriptでチェックする場合に、エラーメッセージをalert()で出力しているサンプルです。

このスクリプトを動かすと、page.MustElement("#btn_valid").MustClick()で処理が止まってしまい後続処理がまったく動かない状態になります。

原因

alert()が実行されると[OK]が押されるまで、JavaScriptがブロックされる挙動になってしまうためでした。
この挙動について調べると、「ブラウザ自動操作ライブラリ全般に共通する課題」のようで、SeleniumではUnexpectedAlertPresentExceptionという例外がスローされて処理が止まるようです。
【Python Selenium】UnexpectedAlertPresentException:Chromeポップアップ操作 | OFFICE54

対処法


// 1) ダイアログのリスナーとハンドラ取得
wait, handle := page.MustHandleDialog()

// 2) クリックなどダイアログを“発火させる操作”は別goroutineで走らせる
go page.MustElement("#btn_valid").MustClick()

// 3) 実際にダイアログが開くのを待つ(1回限り)
wait()

// 4) 受理/却下やprompt入力を行う
handle(true, "") // OKを押す(confirmならOK、promptなら第2引数に文字列)

// 後続処理...

上記は事象サンプルのコードに、go-rodライブラリでalertダイアログを処理する推奨コード例を参考に変更を加えたものです。

	wait, handle := page.MustHandleDialog()
	go page.MustElement("button").MustClick()
	wait()
	handle(true, "")

rod/page.go at v0.116.2 #L384C1-L391 · go-rod/rod · GitHub

page.MustElement("button").MustClick()をgoroutineを使い、別スレッドで動かす。
alertダイアログが表示されるとJSブロックするので、別スレッドで動かしています。

wait, handle := page.MustHandleDialog()は、Page.javascriptDialogOpeningイベントを一回に限り待つリスナーのwaitとイベント時に処理する関数のhandleを返します。
Page.javascriptDialogOpeningイベントは、alert()などのJSダイアログが表示される時に呼ばれます。

wait()で、JSダイアログが表示されるのを一回に限り待つ。
handle(true, "")で、JSダイアログでOKボタンを押下する。

入力値によってJSダイアログの表示有無が変わる場合

wait, handle := page.MustHandleDialog()を行います。
wait()でタイムアウトした場合は、JSダイアログが表示されなかったとして処理すればOKです。

Goでのパッケージ公開練習と、備忘録を兼ねて上記処理をラップした関数をgo-rodのユーティリティ関数として定義していますので、参考までに
https://github.com/buzzword111/rod-util

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?