0
0

[T-DASH] Shadow DOM を操作する

Last updated at Posted at 2024-09-13

Outline

Salesforceなどのように、Shadow DOMを用いたサイトを自動化するのは厄介だ。

T-DASHでは、Shadow DOMを使った要素を識別することができない(※ 2024/09/01 現在)

そこをなんとかする。

技術的情報

Document:querySelector()とShadowRootを用いて要素を特定する

具体例

まず、簡単なShadow DOMのボタンを定義しているサイトを用いる。

このサイトの「This button is inside a Shadow DOM」のボタンを要素特定してみる。
Developer toolで XPathを取得すると、以下の値になる

//*[@id="my-btn"]

しかし、これは「Here's a basic button example.」の上のボタンだけヒットして、とれません

image.png

では、以下のようにボタンのtextを指定してみるとどうなるか?

//button[text()="This button is inside a Shadow DOM."]

この場合、ヒットされません。
つまり、単純にXPathでは、Shadow DOMの中身を特定できないということです。

image.png

では、querySelector や ShadowRootを使ってどうやって取得するか?

querySelectorはXPathと類似で要素を効率よく検索するMethodである。
CSS selectorを指定して、それが一番最初にあるものを返します。

ShadowRootはDOMツリーとは別にレンダリングされるDOMサブツリーのルートノードを指定します。

では、selectorはどうやって取得するか?

2パターンあります

  • 対象のHTMLで”selectorをコピー”する
  • selectorの階層の情報を参照する(構成は "タグ" "selector" である)

image.png

では、具体的に「This button is inside a Shadow DOM」のボタンを querySelector で特定してみる。

① Shadow DOMの親階層を指定する

document.querySelector('#shadow-host')

② Shadow DOMのroot nodeであることを指定します

document.querySelector('#shadow-host').shadowRoot

③ buttonを特定します

document.querySelector('#shadow-host').shadowRoot.querySelector('#my-btn')

image.png

では、実際にこの記載で正しく特定できているかを、developer toolのコンソールを使って確認することができます。
コンソールで先ほどのqueryを記載して、リターンを押すと、対象のボタンが取れることが確認できると思います。

document.querySelector('#shadow-host').shadowRoot.querySelector('#my-btn')

image.png

こちら、robot frameworkで実際に処理したいときどうするか

*** Settings ***
Library  SeleniumLibrary


*** Test Cases ***
Open Browser and Access practice demo
	Open Browser  https://practice.expandtesting.com/shadowdom  chrome
	Click Element  dom:document.querySelector('#shadow-host').shadowRoot.querySelector('#my-btn')

Click Element  locator

こちらが、「locatorで指定された要素をクリックする」命令である。

locatorとして、xpath=${xpath} の形式で、xpathを指定するのがよくつかわれるパターン。
今回、locatorとして、domで指定する

image.png

T-DASHの手順

カスタム動作

以下設定内容を selenium.yamlのファイル名で保存する

ACT-CAT-CUSTOM-a7b47e3f-ab46-4e69-8133-bcc13b702cd0:
  action_category_name: Selenium
  icon: ''
  color: '#3b16c1'
  custom_data:
    file_name: Selenium
    pip_list: []
    library_list: []
  actions:
    ACT-CUSTOM-c92d773f-f636-4ff9-af5f-d9f329f507df:
      action_name: マウスで指定したlocatorをクリックする
      action_type: operation
      action_format: マウスでlocator「設定値1」をクリックする
      action_note: ''
      action_args:
      - value1
      action_def:
      - - Click Element
        - ${value1}
    ACT-CUSTOM-b33c3edc-c60d-41da-bffd-487c5745629a:
      action_name: Locatorをマウスオーバーする
      action_type: operation
      action_format: Locator「設定値1」をマウスオーバーする
      action_note: ''
      action_args:
      - value1
      action_def:
      - - Mouse Over
        - ${value1}

次に、作成された selenium.yamlをT-DASHの動作定義 -> カスタム動作 -> カスタム動作をインポート にてインポートする

2つのカスタム動作は、Selenium keywordsの操作をそのまま利用している。
ただ、locatorを引数で指定できるようにしている。
この引数に、先ほどのdomの情報を入力することで、domで定義したlocationをクリック、マウスオーバーできるようになる。

image.png

スクリプト

ブラウザを開き、対象のボタンをマウスオーバーし、クリックするだけである。
※尚、「秒待機」をいれているのは、このサイトは広告がたまにでるため、その広告を閉じるために設けている。
また、この練習サイトは、ボタンをクリックしても遷移はしません(動作が期待通りかわからない)。ただ、マウスオーバーすると、ボタンの色が変わるため、「マウスオーバー」処理を入れている。

image.png

テスト結果

スクリーンショットを確認すると、「This button is inside a Shadow DOM」のボタンの色が変わっており、そのボタンを特定していることが確認できる。

image.png

0
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
0
0