fix: 修复网页输入聚焦与降级写入
This commit is contained in:
parent
bec3d9daa4
commit
ced89e26cf
@ -391,7 +391,17 @@ export class BrowserSession implements BrowserLike {
|
||||
|
||||
async type(selector: unknown, text: string, clearFirst = true, timeoutMs?: number): Promise<unknown> {
|
||||
const info = await this.locate(selector, timeoutMs);
|
||||
this.win.show();
|
||||
this.win.focus();
|
||||
await this.mouseClick(info.rect.x + info.rect.width / 2, info.rect.y + info.rect.height / 2);
|
||||
const focused = await this.withElement<boolean>(selector, `
|
||||
el.focus({ focusVisible: true });
|
||||
return document.activeElement === el || el.contains(document.activeElement);
|
||||
`);
|
||||
if (!focused) {
|
||||
const direct = await this.setValueDirect(selector, clearFirst ? text : `${info.value || ""}${text}`);
|
||||
return { selector: info.selector, value: direct };
|
||||
}
|
||||
if (clearFirst) {
|
||||
await this.cdp("Input.dispatchKeyEvent", { type: "rawKeyDown", key: "a", code: "KeyA", windowsVirtualKeyCode: 65, modifiers: 2 });
|
||||
await this.cdp("Input.dispatchKeyEvent", { type: "keyUp", key: "a", code: "KeyA", windowsVirtualKeyCode: 65, modifiers: 2 });
|
||||
@ -400,11 +410,32 @@ export class BrowserSession implements BrowserLike {
|
||||
await this.cdp("Input.insertText", { text });
|
||||
await new Promise((resolve) => setTimeout(resolve, 120));
|
||||
const expected = clearFirst ? text : `${info.value || ""}${text}`;
|
||||
const actual = await this.evaluate<string>(`(() => { const el = document.activeElement; return el ? (el.value ?? el.textContent ?? '') : ''; })()`);
|
||||
if (actual !== expected) throw new RuntimeError("evaluate_error", `输入校验失败:期望「${expected}」,实际「${actual}」`, { recommendation: "检查输入框状态或重新拾取元素" });
|
||||
const actual = await this.withElement<string>(selector, `return String(el.value ?? el.textContent ?? '')`);
|
||||
if (actual !== expected) {
|
||||
const fallback = await this.setValueDirect(selector, clearFirst ? text : expected);
|
||||
if (fallback !== expected) {
|
||||
throw new RuntimeError("evaluate_error", `输入校验失败:期望「${expected}」,实际「${fallback}」`, { recommendation: "检查输入框状态或重新拾取元素" });
|
||||
}
|
||||
return { selector: info.selector, value: fallback };
|
||||
}
|
||||
return { selector: info.selector, value: actual };
|
||||
}
|
||||
|
||||
private async setValueDirect(selector: unknown, text: string): Promise<string> {
|
||||
return this.withElement<string>(selector, `
|
||||
if (el.isContentEditable) {
|
||||
el.textContent = ${JSON.stringify(text)};
|
||||
} else {
|
||||
const prototype = el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype;
|
||||
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'value');
|
||||
descriptor?.set?.call(el, ${JSON.stringify(text)});
|
||||
}
|
||||
el.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
el.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
return String(el.value ?? el.textContent ?? '');
|
||||
`);
|
||||
}
|
||||
|
||||
async getText(selector: unknown, attribute?: string): Promise<string> {
|
||||
const info = await this.locate(selector);
|
||||
if (attribute) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user