最近使用Selenium执行公司大模型产品的UI自动化时部分输入问题报错:selenium.common.exceptions.WebDriverException: Message: unknown error: ChromeDriver only supports characters in the BMP。
BMP 和 非 BMP 字符
BMP (Basic Multilingual Plane) 包含了 Unicode 的前 65536 个字符,即从 U+0000 到 U+FFFF。
非 BMP 字符 则超出了这个范围,属于 Unicode 的辅助平面(Supplementary Planes),这些字符的 Unicode 编码大于 U+FFFF。
例如,像表情符号(emojis)和某些较冷门的汉字(例如古文字符)等,通常都位于非 BMP 区域。
Selenium的sendKeys方法不支持输入非BMP字符,所以需要将文本先转义非 BMP 字符再输入。
/**
* 转义非 BMP 字符
* @param input 输入的字符串
* @return 转义后的字符串
*/
public static String escapeNonBMPChars(String input) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < input.length(); ) {
int codePoint = input.codePointAt(i);
if (Character.isSupplementaryCodePoint(codePoint)) {
// 获取高代理和低代理
char highSurrogate = Character.highSurrogate(codePoint);
char lowSurrogate = Character.lowSurrogate(codePoint);
// 将高代理和低代理转义为 Unicode 转义序列
sb.append("\\u").append(Integer.toHexString(highSurrogate).toUpperCase());
sb.append("\\u").append(Integer.toHexString(lowSurrogate).toUpperCase());
} else {
// 直接添加非辅助平面字符
sb.append(Character.toChars(codePoint));
}
// 移动到下一个字符
i += Character.charCount(codePoint);
}
return sb.toString();
}
还
如果不想转义,可以使用 JavaScript 设置 value 实现(各种输入框事件根据实际情况使用,一般触发输入框的 input 事件就可以了):
例如:
public void jsSendKeys(WebElement element,String value) {
if(element!=null) {
// 触发输入框的 focus 事件 当元素获得焦点时触发
//((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new Event('focus'));", element);
((JavascriptExecutor) driver).executeScript("arguments[0].value = arguments[1];", element, value);
logger.info("在元素"+ element+"Javascrip设置数据:"+value+" 成功");
//触发输入框的 input 事件 已经触发,用于表示用户输入值的变化。
((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new Event('input'));", element);
// 触发输入框的 change 事件 当输入框的值发生变化且失去焦点时触发
//((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new Event('change'));", element);
// 触发输入框的 blur 事件 当元素失去焦点时触发
//((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new Event('blur'));", element);
}else {
logger.error("元素没有定位到,设置失败 "+value);
}
}