Skip to content

[Bug]: keyboard.type() inserts unwanted space between CJK characters and digits (e.g. "小米14" → "小米 14") #2176

@longway-code

Description

@longway-code

Version

System:
  OS: macOS 15.6.1
  CPU: (14) arm64 Apple M4 Pro
  Memory: 115.31 MB / 24.00 GB
  Shell: 5.9 - /bin/zsh
Browsers:
  Chrome: 146.0.7680.80
  Safari: 18.6

Details

使用 Chrome 插件执行输入操作时,如果输入内容包含中文紧跟数字的字符串(例如 小米14),实际插入到输入框中的文本会变成 小米 14,中间多出一个空格。

Image Image

复现步骤

在搜索框中输入 小米14,实际输入框中得到的是 小米 14

期望行为

输入框中应得到 小米14,不应有多余空格。

根本原因

问题出在 packages/web-integration/src/chrome-extension/cdpInput.tstype() 方法中。

该方法对每个字符逐一判断,根据字符是否存在于 _keyDefinitions 来选择不同的 CDP 输入方式:

// 原始逻辑
for (const char of text) {
  if (this.charIsKey(char)) {
    await this.press(char, { delay });   // → Input.dispatchKeyEvent(模拟真实按键)
  } else {
    await this.sendCharacter(char);      // → Input.insertText(直接插入文本)
  }
}

_keyDefinitions 中包含了数字 09 和空格,因此这些字符会走 Input.dispatchKeyEvent(模拟物理按键)。而中文字符不在其中,走的是 Input.insertText(直接插入,绕过输入法)。

两种方式混合使用时,浏览器/输入法检测到从"直接文本插入"切换到"物理按键模拟"的边界,IME 会在此时自动提交前面的 composition 并插入一个分隔空格,导致 小米14 变成 小米 14

建议的修复方案

对所有可打印字符统一使用 Input.insertText。只有 \r\n 需要走真实按键事件,因为浏览器需要物理 Enter 事件来提交表单或换行。

for (const char of text) {
  if (char === '\r' || char === '\n') {
    await this.press(char as KeyInput, { delay }); // 必须用真实按键事件
  } else {
    await this.sendCharacter(char); // 其他所有字符用 Input.insertText
  }
}

这样 小米14 整个字符串会作为统一的文本插入操作处理,IME 不会感知到模式切换,也就不会插入多余的空格。

如果维护者认可这个方案的话, 我愿意提交 PR 来完成这个修复。

Reproduce link

No

Reproduce Steps

在搜索框中输入 小米14,实际输入框中得到的是 小米 14。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions