mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
mcp: add tests for click, fill, and scroll actions
This commit is contained in:
14
src/browser/tests/mcp_actions.html
Normal file
14
src/browser/tests/mcp_actions.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<button id="btn" onclick="window.clicked = true;">Click Me</button>
|
||||||
|
<input id="inp" oninput="window.inputVal = this.value" onchange="window.changed = true;">
|
||||||
|
<select id="sel" onchange="window.selChanged = this.value">
|
||||||
|
<option value="opt1">Option 1</option>
|
||||||
|
<option value="opt2">Option 2</option>
|
||||||
|
</select>
|
||||||
|
<div id="scrollbox" style="width: 100px; height: 100px; overflow: scroll;" onscroll="window.scrolled = true;">
|
||||||
|
<div style="height: 500px;">Long content</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -321,3 +321,63 @@ test "cdp.lp: getStructuredData" {
|
|||||||
const result = ctx.client.?.sent.items[0].object.get("result").?.object;
|
const result = ctx.client.?.sent.items[0].object.get("result").?.object;
|
||||||
try testing.expect(result.get("structuredData") != null);
|
try testing.expect(result.get("structuredData") != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "cdp.lp: action tools" {
|
||||||
|
var ctx = testing.context();
|
||||||
|
defer ctx.deinit();
|
||||||
|
|
||||||
|
const bc = try ctx.loadBrowserContext(.{});
|
||||||
|
const page = try bc.session.createPage();
|
||||||
|
const url = "http://localhost:9582/src/browser/tests/mcp_actions.html";
|
||||||
|
try page.navigate(url, .{ .reason = .address_bar, .kind = .{ .push = null } });
|
||||||
|
_ = bc.session.wait(5000);
|
||||||
|
|
||||||
|
// Test Click
|
||||||
|
const btn = page.document.getElementById("btn", page).?.asNode();
|
||||||
|
const btn_id = (try bc.node_registry.register(btn)).id;
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 1,
|
||||||
|
.method = "LP.clickNode",
|
||||||
|
.params = .{ .backendNodeId = btn_id },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test Fill Input
|
||||||
|
const inp = page.document.getElementById("inp", page).?.asNode();
|
||||||
|
const inp_id = (try bc.node_registry.register(inp)).id;
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 2,
|
||||||
|
.method = "LP.fillNode",
|
||||||
|
.params = .{ .backendNodeId = inp_id, .text = "hello" },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test Fill Select
|
||||||
|
const sel = page.document.getElementById("sel", page).?.asNode();
|
||||||
|
const sel_id = (try bc.node_registry.register(sel)).id;
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 3,
|
||||||
|
.method = "LP.fillNode",
|
||||||
|
.params = .{ .backendNodeId = sel_id, .text = "opt2" },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test Scroll
|
||||||
|
const scrollbox = page.document.getElementById("scrollbox", page).?.asNode();
|
||||||
|
const scrollbox_id = (try bc.node_registry.register(scrollbox)).id;
|
||||||
|
try ctx.processMessage(.{
|
||||||
|
.id = 4,
|
||||||
|
.method = "LP.scrollNode",
|
||||||
|
.params = .{ .backendNodeId = scrollbox_id, .y = 50 },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluate assertions
|
||||||
|
var ls: lp.js.Local.Scope = undefined;
|
||||||
|
page.js.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
|
var try_catch: lp.js.TryCatch = undefined;
|
||||||
|
try_catch.init(&ls.local);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
|
const result = try ls.local.compileAndRun("window.clicked === true && window.inputVal === 'hello' && window.changed === true && window.selChanged === 'opt2' && window.scrolled === true", null);
|
||||||
|
|
||||||
|
try testing.expect(result.isTrue());
|
||||||
|
}
|
||||||
|
|||||||
@@ -630,3 +630,66 @@ test "MCP - evaluate error reporting" {
|
|||||||
\\}
|
\\}
|
||||||
, out_alloc.writer.buffered());
|
, out_alloc.writer.buffered());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "MCP - Actions: click, fill, scroll" {
|
||||||
|
defer testing.reset();
|
||||||
|
const allocator = testing.allocator;
|
||||||
|
const app = testing.test_app;
|
||||||
|
|
||||||
|
var out_alloc: std.io.Writer.Allocating = .init(testing.arena_allocator);
|
||||||
|
defer out_alloc.deinit();
|
||||||
|
|
||||||
|
var server = try Server.init(allocator, app, &out_alloc.writer);
|
||||||
|
defer server.deinit();
|
||||||
|
|
||||||
|
const aa = testing.arena_allocator;
|
||||||
|
const page = try server.session.createPage();
|
||||||
|
const url = "http://localhost:9582/src/browser/tests/mcp_actions.html";
|
||||||
|
try page.navigate(url, .{ .reason = .address_bar, .kind = .{ .push = null } });
|
||||||
|
_ = server.session.wait(5000);
|
||||||
|
|
||||||
|
// Test Click
|
||||||
|
const btn = page.document.getElementById("btn", page).?.asNode();
|
||||||
|
const btn_id = (try server.node_registry.register(btn)).id;
|
||||||
|
var btn_id_buf: [12]u8 = undefined;
|
||||||
|
const btn_id_str = std.fmt.bufPrint(&btn_id_buf, "{d}", .{btn_id}) catch unreachable;
|
||||||
|
const click_msg = try std.mem.concat(aa, u8, &.{ "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"click\",\"arguments\":{\"backendNodeId\":", btn_id_str, "}}}" });
|
||||||
|
try router.handleMessage(server, aa, click_msg);
|
||||||
|
|
||||||
|
// Test Fill Input
|
||||||
|
const inp = page.document.getElementById("inp", page).?.asNode();
|
||||||
|
const inp_id = (try server.node_registry.register(inp)).id;
|
||||||
|
var inp_id_buf: [12]u8 = undefined;
|
||||||
|
const inp_id_str = std.fmt.bufPrint(&inp_id_buf, "{d}", .{inp_id}) catch unreachable;
|
||||||
|
const fill_msg = try std.mem.concat(aa, u8, &.{ "{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"fill\",\"arguments\":{\"backendNodeId\":", inp_id_str, ",\"text\":\"hello\"}}}" });
|
||||||
|
try router.handleMessage(server, aa, fill_msg);
|
||||||
|
|
||||||
|
// Test Fill Select
|
||||||
|
const sel = page.document.getElementById("sel", page).?.asNode();
|
||||||
|
const sel_id = (try server.node_registry.register(sel)).id;
|
||||||
|
var sel_id_buf: [12]u8 = undefined;
|
||||||
|
const sel_id_str = std.fmt.bufPrint(&sel_id_buf, "{d}", .{sel_id}) catch unreachable;
|
||||||
|
const fill_sel_msg = try std.mem.concat(aa, u8, &.{ "{\"jsonrpc\":\"2.0\",\"id\":3,\"method\":\"tools/call\",\"params\":{\"name\":\"fill\",\"arguments\":{\"backendNodeId\":", sel_id_str, ",\"text\":\"opt2\"}}}" });
|
||||||
|
try router.handleMessage(server, aa, fill_sel_msg);
|
||||||
|
|
||||||
|
// Test Scroll
|
||||||
|
const scrollbox = page.document.getElementById("scrollbox", page).?.asNode();
|
||||||
|
const scrollbox_id = (try server.node_registry.register(scrollbox)).id;
|
||||||
|
var scroll_id_buf: [12]u8 = undefined;
|
||||||
|
const scroll_id_str = std.fmt.bufPrint(&scroll_id_buf, "{d}", .{scrollbox_id}) catch unreachable;
|
||||||
|
const scroll_msg = try std.mem.concat(aa, u8, &.{ "{\"jsonrpc\":\"2.0\",\"id\":4,\"method\":\"tools/call\",\"params\":{\"name\":\"scroll\",\"arguments\":{\"backendNodeId\":", scroll_id_str, ",\"y\":50}}}" });
|
||||||
|
try router.handleMessage(server, aa, scroll_msg);
|
||||||
|
|
||||||
|
// Evaluate assertions
|
||||||
|
var ls: js.Local.Scope = undefined;
|
||||||
|
page.js.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
|
var try_catch: js.TryCatch = undefined;
|
||||||
|
try_catch.init(&ls.local);
|
||||||
|
defer try_catch.deinit();
|
||||||
|
|
||||||
|
const result = try ls.local.compileAndRun("window.clicked === true && window.inputVal === 'hello' && window.changed === true && window.selChanged === 'opt2' && window.scrolled === true", null);
|
||||||
|
|
||||||
|
try testing.expect(result.isTrue());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user