shadow-rootの中のelemnetが含まれている場合XPathでは指定できません AutoIt3を使って何とか操作する

2025年7月1日

XPath

/html/body/div/div[1]/main/article/controller//nav/ul/li[1]/button

HTML

<html>
  <body>
    <div>
      <div>
        <main>
          <article>
            <controller>
             #shadow-root (open)
              <nav>
                <ul>
                  <li>
                    <button>Click me!</button>
                  </li>
                </ul>
              </nav>
            </controller>
          </article>
        </main>
      </div>
    </div>
  </body>
</html>

GetShadowRoot

$sRoot = _WD_GetShadowRoot($sSession, $_WD_LOCATOR_ByXPath, "//*[@id='controller']")
$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByCSSSelector, "nav > ul > li:nth-child(1) > button" ,$sRoot, "", True)
_WD_ElementAction($sSession, $sElement, "click")
 

ヘルパー

Func _ShadowXPath($hSession, $sHostXPath, $sInnerSelector)
    Local $hRoot = _WD_GetShadowRoot($hSession, $_WD_LOCATOR_XPATH, $sHostXPath)
    If @error Then Return SetError(1, 0, 0)
    Return _WD_FindElement( _
               $hSession, $_WD_LOCATOR_ByCSSSelector, $sInnerSelector, _
               $hRoot, DefaultTimeout, True _
           )
EndFunc

; 使い方
Local $hBtn = _ShadowXPath( _
               $sSession, _
               "/html/body/div/div[1]/main/article/controller", _
               "nav > ul > li:nth-child(1) > button" _
            )
_WD_ClickElement($sSession, $hBtn)

コード

これで XPath ではなく CSS セレクタでの処理が可能です!

#include "au3WebDriver.au3"

;— 1) セッション起動&ページへ
Local $sSession = _WD_Startup("chrome")
_WD_Navigate($sSession, "https://your.page.url")

;— 2) Shadow‐host(controller)を XPath で取得
Local $sHostXPath = "/html/body/div/div[1]/main/article/controller"

;— 3) ShadowRoot をハンドル化
Local $hRoot = _WD_GetShadowRoot( _
                    $sSession, _
                    $_WD_LOCATOR_XPATH, _
                    $sHostXPath _
               )
If @error Then
    MsgBox(16, "Error", "shadowRoot の取得に失敗")
    _WD_DeleteSession($sSession)
    Exit
EndIf

;— 4) shadowRoot 以下を Selectorで検索
Local $sInnerSelector = "nav > ul > li:nth-child(2) > button"
Local $hBtn        = _WD_FindElement( _
                        $sSession, _
                        $_WD_LOCATOR_ByCSSSelector, _
                        $sInnerSelector, _
                        $hRoot, _        ; ← ここでコンテキストを渡す
                        DefaultTimeout, _
                        True             ; リトライ ON
                   )
If @error Then
    MsgBox(16, "Error", "Shadow-DOM 内要素が見つかりませんでした → " & $sInnerSelector)
    _WD_DeleteSession($sSession)
    Exit
EndIf

;— 5) ボタンクリック
_WD_ClickElement($sSession, $hBtn)

;— 6) 後片付け
_WD_DeleteSession($sSession)

HTML例

Shadow DOM Example

Shadow DOM Example

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shadow DOM Example</title>
</head>
<body>
    <h1>Shadow DOM Example</h1>
    <!-- Shadow Host -->
    <custom-element id="myShadowHost"></custom-element>

    <script>
        // Define the shadow-host behavior
        const shadowHost = document.getElementById("myShadowHost");

        // Attach open Shadow DOM
        const shadowRoot = shadowHost.attachShadow({ mode: "open" });

        // Add content inside Shadow DOM
        shadowRoot.innerHTML = `
            <style>
                button {
                    background-color: #6200ea;
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    cursor: pointer;
                    font-size: 16px;
                }
                button:hover {
                    background-color: #3700b3;
                }
            </style>
            <div>
                <p>Click the button inside Shadow DOM:</p>
                <button id="shadowButton">Click Me</button>
            </div>
        `;
    </script>
</body>
</html>

AutoIt

Posted by eightban