【PowerShell】Selenium-Module Get-SeSelectionOption 選択のオプション

目次

概要

 起動しているブラウザで選択項目がある場合、Get-SeSelectionOptionメソッドを利用して選択肢の各種選択ができます。シングル選択、マルチ選択の両方に対応しています。引数の一つである"ByFullText"については、癖が強くあまり利用をお勧めはできません。

 PowerShellでSeleniumを利用するに当たって、ある程度簡易的にSeleniumを利用できる様に専用のモジュールがGitHubに用意されています。いきなりPowerShellでSeleniumを扱うより、Seleniumを-Moduleを利用した方が簡単にPowerShellでSleniumを利用することができます。環境構築するには、以下ページを参照してみてください。

コマンド(Commond)

Get-SeSelectionOption

代替コマンド(Alias)

SeSelection

構文(Syntax)

  • Get-SeSelectionOption [-Element] <IWebElement> [-Clear] [-ListOptionText] [<CommonParameters>]
  • Get-SeSelectionOption [-ByValue] <string> [-Element] <IWebElement> [-Clear] [-GetSelected] [-GetAllSelected] [-PassThru] [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -ByFullText <string> [-Clear] [-GetSelected] [-GetAllSelected] [-PassThru] [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -ByPartialText <string> [-GetSelected] [-GetAllSelected] [-PassThru] [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -ByIndex <int> [-Clear] [-GetSelected] [-GetAllSelected] [-PassThru] [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -IsMultiSelect [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -GetSelected [<CommonParameters>]
  • Get-SeSelectionOption [-Element] <IWebElement> -GetAllSelected [<CommonParameters>]

オプション

Name引数型解説Short Example
ElementIWebElement対象Web要素の指定Get-SeSelectionOption -Element $Element -Clear
ByIndexintIndex値(0起点)指定による選択Get-SeSelectionOption -Element $Element -ByIndex 2 -Clear
ByValuestringValue値指定による選択Get-SeSelectionOption -Element $Element -ByValue "3"
ByFullTextstring完全一致検索の文字列検索。動作不具合(Short Exampleは代替方法を掲載)[SeleniumSelection.Option]::SelectByText($Element, $str , $false)
ByPartialTextstring部分一致検索の文字列検索Get-SeSelectionOption -Element $Element -ByPartialText $str
Clear選択解除。選択肢の指定が無い場合、全選択肢を選択解除。Get-SeSelectionOption -Element $Element -Clear
IsMultiSelect選択したWeb要素がマルチ選択可能か判定$IsMultSelect = Get-SeSelectionOption -IsMultiSelect -Element $Element
GetSelected選択中の文字列を取得
マルチ選択の場合、最初に選択した文字列を取得。シングル選択時に利用をお勧め。
Get-SeSelectionOption -Element $Element -GetSelected
GetAllSelected複数選択時、全選択中の文字列を取得。マルチ選択時に利用をお勧め。Get-SeSelectionOption -Element $Element -GetAllSelected
ListOptionText選択可能な文字列一覧を取得Get-SeSelectionOption -Element $Element -ListOptionText
PassThruWeb要素のオブジェクトプロパティを取得Get-SeSelectionOption -Element $Element -ByIndex 1 -PassThru
CommonParameters共通パラメータ

※ShortExampleは、動作確認ができたコードを記載しています。

オブジェクトプロパティ

NameShortExample
WrappedDriverOpenQA.Selenium.Chrome.ChromeDriver
TagNameselect
Text単一選択しかできないセレクトボックス・表示する値1・・・(後省略)
EnabledTRUE
SelectedFALSE
Location{X=356,Y=1370}
Size{Width=350, Height=106}
DisplayedTRUE
LocationOnScreenOnceScrolledIntoView{X=356,Y=199}
CoordinatesOpenQA.Selenium.Remote.RemoteCoordinates

※ShortExampleは、動作確認ができたコードを記載しています。

Example

シングル選択時

$url = "https://bayashita.com/p/entry/show/24"
$Driver = Start-SeChrome -Quiet
Enter-SeUrl $url -Driver $Driver
$Element = Get-SeElement -Target $Driver -XPath "//*[contains(@id,'list2')]" -Timeout 10

$str = "単一選択しかできないセレクトボックス・表示する値3"
Get-SeSelectionOption -Element $Element -ByIndex 1 -PassThru
Start-Sleep 1
Get-SeSelectionOption -Element $Element -ByValue "3"
Start-Sleep 1
Get-SeSelectionOption -Element $Element -GetSelected

Start-Sleep -Seconds 3
Stop-SeDriver $Driver

マルチ選択時

$url = "https://bayashita.com/p/entry/show/24"
$Driver = Start-SeChrome -Quiet
Enter-SeUrl $url -Driver $Driver
$Element = Get-SeElement -Target $Driver -XPath "//*[contains(@id,'list1')]" -Timeout 10

#全選択 ⇒ 3行目選択解除 ⇒ 全行選択解除
$str = "複数選択可能なセレクトボックス・表示する値"
Get-SeSelectionOption -Element $Element -ByPartialText $str
Start-Sleep 2
Get-SeSelectionOption -Element $Element -ByIndex 2 -Clear #index2の選択を解除
Start-Sleep 2
Write-Host `r`n "Clear:選択可能な文字列リスト取得してターミナル出力される"
Get-SeSelectionOption -Element $Element -Clear #全ての選択を外す 
Start-Sleep 2

#マルチ選択(奇数行選択) ⇒ 選択中の文字列をターミナル出力 ⇒ 選択可能な文字列をターミナルに出力
$IsMultSelect = Get-SeSelectionOption -IsMultiSelect -Element $Element
Write-Host "複数選択:$IsMultSelect"
$Selection = Get-SeSelectionOption -Element $Element
if ($IsMultSelect) {
    for ($i = 0; $i -lt $Selection.Count; $i += 2) {
        Get-SeSelectionOption -Element $Element -ByIndex $i
        #Get-SeSelectionOption -Element $Element -GetSelected
    }
}
Write-Host `r`n "GetAllSelected"
Get-SeSelectionOption -Element $Element -GetAllSelected
Write-Host `r`n "ListOptionText"
Get-SeSelectionOption -Element $Element -ListOptionText

Start-Sleep -Seconds 3
Stop-SeDriver $Driver

ByFullTextのテスト

 冒頭で説明したとおり、"ByFullText"は、動作に不具合があります。シングル選択でもマルチ選択でも選択肢の一番上の選択肢を選択していまいます。モジュール内でByFullTextの動作がどの様に動いているか確認してみると、ByFullTextの判定が上手くできておらず、if文が素通りしてしまい、elseで自動的にindexの0番目を選択する様に動作設定がされている状態です。
 以下、動作テスト用にいくつかコードを書いてみました。

#シングル選択時の選択実行テスト(一番上の選択肢が選択できない場合)
$url = "https://the-internet.herokuapp.com/dropdown"
$Driver = Start-SeChrome -Quiet
Enter-SeUrl $url -Driver $Driver
$Element = Get-SeElement -Target $Driver -Id "dropdown" -Timeout 10
Start-Sleep 2
[SeleniumSelection.Option]::SelectByText($Element, "Option 1" , $false) #成功
Start-Sleep 2
Get-SeSelectionOption -Element $Element -ByFullText "Option 2" #選択失敗(一番上の選択肢が選択不可のため?)
Start-Sleep 2
Stop-SeDriver $Driver

$url = "https://bayashita.com/p/entry/show/24"
$Driver = Start-SeChrome -Quiet
Enter-SeUrl $url -Driver $Driver

#マルチ選択時の選択実行テスト
#マルチ選択可能時は、SelectByTextメソッドは実行失敗する
$Element = Get-SeElement -Target $Driver -XPath "//*[contains(@id,'list1')]" -Timeout 10
$str = "複数選択可能なセレクトボックス・表示する2"
Get-SeSelectionOption -Element $Element -ByFullText $str #どの選択肢を指定しても一番上の選択肢を選択
Start-Sleep 2
[SeleniumSelection.Option]::SelectByText($Element, $str , $false) #エラー発生
Start-Sleep 2

#シングル選択時の選択実行テスト
$Element = Get-SeElement -Target $Driver -XPath "//*[contains(@id,'list2')]" -Timeout 10
$str = "単一選択しかできないセレクトボックス・表示する値2"
Get-SeSelectionOption -Element $Element -ByFullText $str #どの選択肢を指定しても一番上の選択肢を選択
$str = "単一選択しかできないセレクトボックス・表示する値4"
Start-Sleep 2
[SeleniumSelection.Option]::SelectByText($Element, $str , $false) #成功

Start-Sleep -Seconds 3
Stop-SeDriver $Driver

Module

 Get-SeSelectionOptionのSelenium-Module構文を以下に掲載します。

function Get-SeSelectionOption {
    [Alias('SeSelection')]
    [cmdletbinding(DefaultParameterSetName = 'default')]
    param (

        [Parameter(Mandatory = $true, ParameterSetName = 'byValue', Position = 0, ValueFromPipelineByPropertyName = $true)]
        [String]$ByValue,

        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 1)]
        [OpenQA.Selenium.IWebElement]$Element,

        [Parameter(Mandatory = $true, ParameterSetName = 'byText', ValueFromPipelineByPropertyName = $true)]
        [String]$ByFullText,

        [Parameter(Mandatory = $true, ParameterSetName = 'bypart', ValueFromPipelineByPropertyName = $true)]
        [String]$ByPartialText,

        [Parameter(Mandatory = $true, ParameterSetName = 'byIndex', ValueFromPipelineByPropertyName = $true)]
        [int]$ByIndex,

        [Parameter(Mandatory = $false, ParameterSetName = 'default')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byValue')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byText')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byIndex')]
        [switch]$Clear,

        [Parameter(Mandatory = $false, ParameterSetName = 'default')]
        [switch]$ListOptionText,

        [Parameter(Mandatory = $true, ParameterSetName = 'multi')]
        [switch]$IsMultiSelect,

        [Parameter(Mandatory = $true, ParameterSetName = 'selected')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byValue')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byText')]
        [Parameter(Mandatory = $false, ParameterSetName = 'bypart')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byIndex')]
        [switch]$GetSelected,

        [Parameter(Mandatory = $true, ParameterSetName = 'allSelected')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byValue')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byText')]
        [Parameter(Mandatory = $false, ParameterSetName = 'bypart')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byIndex')]
        [switch]$GetAllSelected,

        [Parameter(Mandatory = $false, ParameterSetName = 'byValue')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byText')]
        [Parameter(Mandatory = $false, ParameterSetName = 'bypart')]
        [Parameter(Mandatory = $false, ParameterSetName = 'byIndex')]
        [Alias('PT')]
        [switch]$PassThru
    )
    try {
        #byindex can be 0, but ByText and ByValue can't be empty strings
        if ($ByFullText -or $ByPartialText -or $ByValue -or $PSBoundParameters.ContainsKey('ByIndex')) {
            if ($Clear) {
                if ($ByText) { [SeleniumSelection.Option]::DeselectByText($Element, $ByText) }
                elseif ($ByValue) { [SeleniumSelection.Option]::DeselectByValue($Element, $ByValue) }
                else { [SeleniumSelection.Option]::DeselectByIndex($Element, $ByIndex) }
            }
            else {
                if ($ByText) { [SeleniumSelection.Option]::SelectByText($Element, $ByText, $false) }
                if ($ByPartialText) { [SeleniumSelection.Option]::SelectByText($Element, $ByPartialText, $true) }
                elseif ($ByValue) { [SeleniumSelection.Option]::SelectByValue($Element, $ByValue) }
                else { [SeleniumSelection.Option]::SelectByIndex($Element, $ByIndex) }
            }
        }
        elseif ($Clear) { [SeleniumSelection.Option]::DeselectAll($Element) }
        if ($IsMultiSelect) {
            return [SeleniumSelection.Option]::IsMultiSelect($Element)
        }
        if ($PassThru -and ($GetAllSelected -or $GetAllSelected)) {
            Write-Warning -Message "-Passthru option ignored because other values are returned"
        }
        if ($GetSelected) {
            return [SeleniumSelection.Option]::GetSelectedOption($Element).text
        }
        if ($GetAllSelected) {
            return [SeleniumSelection.Option]::GetAllSelectedOptions($Element).text
        }
        if ($PSCmdlet.ParameterSetName -eq 'default') {
            [SeleniumSelection.Option]::GetOptions($Element) | Select-Object -ExpandProperty Text
        }
        elseif ($PassThru) { $Element }
    }
    catch {
        throw "An error occured checking the selection box, the message was:`r`n $($_.exception.message)"
    }
}
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

VBAを中心とした自動化、効率化の手法を紹介しています。現在は、SeleniumBasicのexamplesを紹介しています。その内、SeleniumBasic以外の手法も掲載したいと思っております。

目次