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> {
|
async type(selector: unknown, text: string, clearFirst = true, timeoutMs?: number): Promise<unknown> {
|
||||||
const info = await this.locate(selector, timeoutMs);
|
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);
|
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) {
|
if (clearFirst) {
|
||||||
await this.cdp("Input.dispatchKeyEvent", { type: "rawKeyDown", key: "a", code: "KeyA", windowsVirtualKeyCode: 65, modifiers: 2 });
|
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 });
|
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 this.cdp("Input.insertText", { text });
|
||||||
await new Promise((resolve) => setTimeout(resolve, 120));
|
await new Promise((resolve) => setTimeout(resolve, 120));
|
||||||
const expected = clearFirst ? text : `${info.value || ""}${text}`;
|
const expected = clearFirst ? text : `${info.value || ""}${text}`;
|
||||||
const actual = await this.evaluate<string>(`(() => { const el = document.activeElement; return el ? (el.value ?? el.textContent ?? '') : ''; })()`);
|
const actual = await this.withElement<string>(selector, `return String(el.value ?? el.textContent ?? '')`);
|
||||||
if (actual !== expected) throw new RuntimeError("evaluate_error", `输入校验失败:期望「${expected}」,实际「${actual}」`, { recommendation: "检查输入框状态或重新拾取元素" });
|
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 };
|
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> {
|
async getText(selector: unknown, attribute?: string): Promise<string> {
|
||||||
const info = await this.locate(selector);
|
const info = await this.locate(selector);
|
||||||
if (attribute) {
|
if (attribute) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user