目次
概要
起動しているブラウザで選択項目がある場合、Get-SeSelectionOptionメソッドを利用して選択肢の各種選択ができます。シングル選択、マルチ選択の両方に対応しています。引数の一つである"ByFullText"については、癖が強くあまり利用をお勧めはできません。
PowerShellでSeleniumモジュールを利用する方法
Seleniumは多言語で利用可能なツールです。PowerShell専用でSeleniumのクラスは用意されていませんが、C#用に.NETのSeleniumは用意されています。公式には例文も無い...
コマンド(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 |
---|---|---|---|
Element | IWebElement | 対象Web要素の指定 | Get-SeSelectionOption -Element $Element -Clear |
ByIndex | int | Index値(0起点)指定による選択 | Get-SeSelectionOption -Element $Element -ByIndex 2 -Clear |
ByValue | string | Value値指定による選択 | Get-SeSelectionOption -Element $Element -ByValue "3" |
ByFullText | string | 完全一致検索の文字列検索。動作不具合(Short Exampleは代替方法を掲載) | [SeleniumSelection.Option]::SelectByText($Element, $str , $false) |
ByPartialText | string | 部分一致検索の文字列検索 | 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 | |
PassThru | Web要素のオブジェクトプロパティを取得 | Get-SeSelectionOption -Element $Element -ByIndex 1 -PassThru | |
CommonParameters | 共通パラメータ |
※ShortExampleは、動作確認ができたコードを記載しています。
オブジェクトプロパティ
Name | ShortExample |
---|---|
WrappedDriver | OpenQA.Selenium.Chrome.ChromeDriver |
TagName | select |
Text | 単一選択しかできないセレクトボックス・表示する値1・・・(後省略) |
Enabled | TRUE |
Selected | FALSE |
Location | {X=356,Y=1370} |
Size | {Width=350, Height=106} |
Displayed | TRUE |
LocationOnScreenOnceScrolledIntoView | {X=356,Y=199} |
Coordinates | OpenQA.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)"
}
}