3行でわかる概要
- JavaのSelenium(4.0.0-alpha-4)の
WebElement::sendKeys
で左右Shiftキーを使い分けようとした際に少し詰まった - 用意されている
Keys
はSHIFT
/LEFT_SHIFT
の中身が同じ -
Keys
を使わずに文字列で"ShiftRight"
と指定すると右Shiftとして認識される
問題
JavaでSeleniumを使用してkeyDownさせる場合、下記のようなコードを書く。
public void sendKey(WebDriver webDriver, CharSequence... keys) {
WebElement element = webDriver.findElement(By.className("hoge"))
element.sendKeys(keys);
}
WebElement.sendKeys
は引数にCharSequence...
を取るが、用意されているenumKeys
を使用することが多い。
ただし、右Shiftキー/左Shiftキーのように同一機能のキーについて左右で使い分けたい場合は注意が必要。
enumKeys
の実装は下記のようになっている。
SHIFT
/LEFT_SHIFT
がそれぞれ定義されているが、残念なことにどちらを送った場合でも左Shiftキーの挙動になってしまう。
Keys.java
public enum Keys implements CharSequence {
...
SHIFT ('\uE008'),
LEFT_SHIFT (Keys.SHIFT),
CONTROL ('\uE009'),
LEFT_CONTROL (Keys.CONTROL),
ALT ('\uE00A'),
LEFT_ALT (Keys.ALT),
LEFT ('\uE012'),
ARROW_LEFT (Keys.LEFT),
UP ('\uE013'),
ARROW_UP (Keys.UP),
RIGHT ('\uE014'),
ARROW_RIGHT (Keys.RIGHT),
DOWN ('\uE015'),
ARROW_DOWN (Keys.DOWN),
...
}
解決策
Keys
はCharSequence
を実装しており、コンストラクタおよびtoString()
の実装は下記のようになっている。
Keys.java
public enum Keys implements CharSequence {
...
private final char keyCode;
private final int codePoint;
Keys(Keys key) {
this(key.charAt(0));
}
Keys(char keyCode) {
this.keyCode = keyCode;
this.codePoint = String.valueOf(keyCode).codePoints().findFirst().getAsInt();
}
...
@Override
public String toString {
return String.valueOf(keyCode);
}
}
また、WebElement.sendKeys
は実質与えられたkeycodeを改行区切りで結合してWebDriverに送っているだけ。
そこで、Keys.SHIFT
で定義されたKeyCodeを使用せずに下記のように文字列で指定することで正常に認識されるようになる。
WebElement element = webDriver.findElement(By.className("hoge"))
element.sendKeys("ShiftRight");