mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 01:25:53 -04:00
cdp: fall back to dialog defaultText when LP.handleJavaScriptDialog promptText is null
When a CDP client pre-arms `LP.handleJavaScriptDialog {accept: true}` with
no `promptText` and the page subsequently calls `window.prompt(message,
defaultText)`, Lightpanda discarded the dialog's `defaultText` argument
and returned `""`. Chrome's behavior is to surface `defaultText` as the
prompt's return value — that's the natural "user accepted without typing
anything" outcome per the HTML simple-dialog algorithm.
The fix is one line in `Window.zig`'s `prompt` JS binding: keep the
second argument named (`default_text` instead of `_`) and use it as the
fallback. Pre-armed `promptText` still wins when the client supplies it;
`accept = false` still returns null regardless. When neither
`promptText` nor `defaultText` is provided, the binding still returns
`""` per the CDP spec.
Adds four new assertions to the existing `cdp.lp` integration test
covering the matrix: defaultText fallback (no promptText), promptText
overrides defaultText, accept=false ignores defaultText, and the
existing no-defaultText case continues to return `""`.
This commit is contained in:
@@ -1105,7 +1105,7 @@ pub const JsApi = struct {
|
||||
}
|
||||
}.confirm, .{});
|
||||
pub const prompt = bridge.function(struct {
|
||||
fn prompt(_: *const Window, message: ?[]const u8, _: ?[]const u8, frame: *Frame) ?[]const u8 {
|
||||
fn prompt(_: *const Window, message: ?[]const u8, default_text: ?[]const u8, frame: *Frame) ?[]const u8 {
|
||||
var response: Notification.DialogResponse = .{};
|
||||
frame._session.notification.dispatch(.javascript_dialog_opening, &.{
|
||||
.url = frame.url,
|
||||
@@ -1114,9 +1114,12 @@ pub const JsApi = struct {
|
||||
.response = &response,
|
||||
});
|
||||
if (!response.accept) return null;
|
||||
// promptText omitted with accept=true is "" per CDP spec
|
||||
// Pre-armed promptText wins when present. Otherwise fall back to
|
||||
// the dialog's defaultText (second arg to window.prompt) — Chrome's
|
||||
// accept-without-typing behavior. If both are absent, return ""
|
||||
// per CDP spec
|
||||
// (https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-handleJavaScriptDialog).
|
||||
return response.prompt_text orelse "";
|
||||
return response.prompt_text orelse default_text orelse "";
|
||||
}
|
||||
}.prompt, .{});
|
||||
|
||||
|
||||
@@ -569,7 +569,7 @@ test "cdp.lp: handleJavaScriptDialog controls confirm/prompt/alert return values
|
||||
const p_text_str = try p_text.toStringSlice();
|
||||
try testing.expectEqualSlices(u8, "hello", p_text_str);
|
||||
|
||||
// ---- prompt: accept=true without promptText returns "" per CDP spec ----
|
||||
// ---- prompt: accept=true without promptText AND no dialog defaultText returns "" ----
|
||||
try ctx.processMessage(.{ .id = 4, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = true } });
|
||||
try ctx.expectSentResult(null, .{ .id = 4 });
|
||||
|
||||
@@ -577,10 +577,35 @@ test "cdp.lp: handleJavaScriptDialog controls confirm/prompt/alert return values
|
||||
const p_empty_str = try p_empty.toStringSlice();
|
||||
try testing.expectEqualSlices(u8, "", p_empty_str);
|
||||
|
||||
// ---- prompt: accept=false makes prompt() return null ----
|
||||
try ctx.processMessage(.{ .id = 5, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = false } });
|
||||
// ---- prompt: accept=true without promptText falls back to dialog defaultText ----
|
||||
// Mirrors Chrome's accept-without-typing behavior: with no client-supplied
|
||||
// promptText, the prompt's return value is the second arg to window.prompt.
|
||||
try ctx.processMessage(.{ .id = 5, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = true } });
|
||||
try ctx.expectSentResult(null, .{ .id = 5 });
|
||||
|
||||
const p_default_text = try ls.local.exec("prompt('name?', 'John Smith')", null);
|
||||
const p_default_text_str = try p_default_text.toStringSlice();
|
||||
try testing.expectEqualSlices(u8, "John Smith", p_default_text_str);
|
||||
|
||||
// ---- prompt: pre-armed promptText overrides the dialog defaultText ----
|
||||
try ctx.processMessage(.{ .id = 6, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = true, .promptText = "typed" } });
|
||||
try ctx.expectSentResult(null, .{ .id = 6 });
|
||||
|
||||
const p_override = try ls.local.exec("prompt('name?', 'John Smith')", null);
|
||||
const p_override_str = try p_override.toStringSlice();
|
||||
try testing.expectEqualSlices(u8, "typed", p_override_str);
|
||||
|
||||
// ---- prompt: accept=false returns null regardless of dialog defaultText ----
|
||||
try ctx.processMessage(.{ .id = 7, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = false } });
|
||||
try ctx.expectSentResult(null, .{ .id = 7 });
|
||||
|
||||
const p_dismiss_with_default = try ls.local.exec("prompt('cancel?', 'John Smith')", null);
|
||||
try testing.expect(p_dismiss_with_default.isNull());
|
||||
|
||||
// ---- prompt: accept=false makes prompt() return null ----
|
||||
try ctx.processMessage(.{ .id = 8, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = false } });
|
||||
try ctx.expectSentResult(null, .{ .id = 8 });
|
||||
|
||||
const p_dismiss = try ls.local.exec("prompt('cancel?')", null);
|
||||
try testing.expect(p_dismiss.isNull());
|
||||
|
||||
@@ -589,8 +614,8 @@ test "cdp.lp: handleJavaScriptDialog controls confirm/prompt/alert return values
|
||||
try testing.expect(p_default.isNull());
|
||||
|
||||
// ---- alert: dispatches the event but has no return value to override ----
|
||||
try ctx.processMessage(.{ .id = 6, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = true } });
|
||||
try ctx.expectSentResult(null, .{ .id = 6 });
|
||||
try ctx.processMessage(.{ .id = 9, .method = "LP.handleJavaScriptDialog", .params = .{ .accept = true } });
|
||||
try ctx.expectSentResult(null, .{ .id = 9 });
|
||||
_ = try ls.local.exec("alert('important')", null);
|
||||
try ctx.expectSentEvent("Page.javascriptDialogOpening", .{
|
||||
.message = "important",
|
||||
|
||||
Reference in New Issue
Block a user