C# Selenium jQueryのイベント発火について

タグの編集
投稿者 えんぴー  (社会人) 投稿日時 2024/5/15 11:53:31
SelectIDおよびSelectID2に値を入れることは出来ました。
TestCodeおよびCheckTESTに自動的に値が入ってくれればいいのですが
ajaxは動作できないのか反映しません。

どうにかイベントを発火させたいのですが
方法はないでしょうか?

C# Chrome Selenium側

SelectElement selectElement3 = new SelectElement(driver.FindElement(By.Id("SelectID")));
selectElement3.SelectByText("テストIDだよ");


→ちゃんと「テストIDだよ」と表示されていることを確認


IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
jsExecutor.ExecuteScript("$(arguments[0]).change();", selectElement3);



上記のようにやったらchangeイベントが動くかと思ったのですが、
効果はありませんでした。


必要そうなHTMLのスクリプトソースを添付します。

-------------
一部抜粋
[pre]
<script>
$(document).ready(function() {
$("#Piyo").select2({
dropdownAutoWidth: true,
language: "ja",
matcher: select2_matchStart
});
setupSelect2($('#SelectID2In'));
setupSelect2($('#SelectID2'));
setupSelect2($('#SelectID'));

1つ目のソース
$('#SelectID').on('select2:select', function(e) {
$.ajax({
url: '/AAAA/BBBBBBBBBB=' + this.value,
success: function(result) {
$('#TestCode').val(result);
},
error: function(error) {
$('#TestCode').val("");
displayErrorDialog("エラー");
}
});
});

-----
2つ目のソース

$('#SelectID2').on('select2:select', function(e) {
$('#SelectID2In').val(this.value);
$('#SelectID2In').trigger("change");
$.ajax({
url: '/AAAAAAA/BBBBBB=' + this.value,
success: function(result) {
$('#CheckTEST').val(result);
},
error: function(error) {
$('#CheckTEST').val("");
displayErrorDialog("エラー");
}
});
});

-------
</script>
[/pre]
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2024/5/15 15:59:56
> [pre]
この掲示板における preformatted タグは、
小文字 pre ではなく大文字 PRE ですね。

> jsExecutor.ExecuteScript("$(arguments[0]).change();", selectElement3);
標準外のカスタムイベントも含めてディスパッチすることが目的なのであれば、
dispatchEvent メソッドの方が良いかもしれません。
https://ja.javascript.info/dispatch-events

当方未確認ですが、こんな感じでどうでしょう。素の change イベントだけならこんな感じ。
もしくは jQuery の on メソッド経由で。
jsExecutor.ExecuteScript("arguments[0].dispatchEvent(new Event('change'))");


> ajaxは動作できないのか反映しません。
この場合は ajax というか、jQuery にも見えますね。

今回は、DOM 標準の change イベントでは無く、
jQuery UI の select2:select イベントが対象なのですよね?
だとしたら、select2 イベント名前空間の指定も必要になるかもしれません。
https://select2.org/programmatic-control/events

jQuery 操作の場合、イベントの発火には trigger メソッドを使ってみてください。
標準の change イベントなら .trigger("select")
スコープ付きの change.select2 イベントなら .trigger('change.select2')
選択結果を受け取れる select2:select イベントなら .trigger({type:'select2:select',params:{data:data}})
https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2
投稿者 えんぴー  (社会人) 投稿日時 2024/5/16 13:08:27
魔界の仮面弁士様

回答ありがとうございます。
大文字のPREですね、失礼しました。



 IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
 jsExecutor.ExecuteScript("$(arguments[0]).change();", selectElement3);//変わらず
 jsExecutor.ExecuteScript("arguments[0].dispatchEvent(new Event('change'))", selectElement3);//変わらず
 jsExecutor.ExecuteScript("$(arguments[0]).trigger('select')");//変わらず
 jsExecutor.ExecuteScript("$(arguments[0]).trigger('change.select2');", selectElement3);//変わらず



>選択結果を受け取れる select2:select イベントなら .trigger({type:'select2:select',params:{data:data}})
これについては、dataをどのようにしたら良いかわからずテスト出来ませんでした。

どうにもHTML側(JQuery側)が分かってないので動作できなさそうです。
select2も良く分かっておらず申し訳ありません。

ただ、1つだけ兆しが見えました。

 driver.FindElement(By.XPath("//*[@id=\"select2-SelectID-results\"]/li[2]")).Click();



このIDは、プルダウンをクリックしたときに動的?に作られるもののようです。
これを実行したら、2つ目のリストが選択されて連動するリストも自動選択されました!

ただ、選択したいのがリスト何番目にあるのか、簡単には取得できなさそうでした。

また、【1】の所で、なぜかSendkeyがエラーになります。
ググッてそのまま利用させていただいている要素待機やwaitも効果がありませんでした。
OpenQA.Selenium.ElementNotInteractableException: 'element not interactable

ただ、クリックして要素を表示することができれば
「select2-SelectID-results」というIDが表示されます。
このIDをもとに
「」というXPASHをClickすると、連動して選択されることがわかりました。

問題点としては
・ID「SelectID」の要素クリックに失敗する(SelectElementのSelectByTextは出来てる)
 ※クリックできれば「」のIDが表示になる
 OpenQA.Selenium.ElementNotInteractableException: 'element not interactable

・要素表示待ちを組み込んでみたが、上記エラーが変わらない

・select2-SelectID-resultsのリスト一覧およびリスト番号が分からない




//-------一部抜粋-----
                SelectElement selectElement3 = new SelectElement(driver.FindElement(By.Id("SelectID")));
                selectElement3.SelectByText(AfterTenS);//問題なくデータ入力できてる
                pagewait();
               
                var ClickData = driver.FindElement(By.Id("SelectID"),1000);
                ClickData.SendKeys(OpenQA.Selenium.Keys.Enter);//なぜかSendKeysがエラーになる【1】
                pagewait();
                driver.FindElement(By.XPath("//*[@id=\"select2-SelectID-results\"]/li[2]")).Click();// 4

//------------

//待機用
        static void pagewait()
        {
            //</html>を見つけるまで待機
            try
            {
                WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(0.01));
                IWebElement firstResult = wait.Until(e => e.FindElement(By.XPath("/html")));

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }





別のクラス
    public static class WebDriverExtensions
    {
        public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
        {
            if (timeoutInSeconds > 0)
            {
                var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
                return wait.Until(drv => drv.FindElement(by));
            }
            return driver.FindElement(by);
        }
    }

投稿者 えんぴー  (社会人) 投稿日時 2024/6/3 10:55:39
その後色々と試してみましたが、私には難しいということが理解できました。
TryでSelectByTextで選択させようと思います!
ありがとうございました。