mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-30 17:18:57 +00:00
Compare commits
1 Commits
fix/cdp-cr
...
puppeteer-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd4760858d |
5
.github/workflows/e2e-test.yml
vendored
5
.github/workflows/e2e-test.yml
vendored
@@ -107,8 +107,11 @@ jobs:
|
|||||||
export PROXY_USERNAME=username PROXY_PASSWORD=password
|
export PROXY_USERNAME=username PROXY_PASSWORD=password
|
||||||
./proxy/proxy & echo $! > PROXY.id
|
./proxy/proxy & echo $! > PROXY.id
|
||||||
./lightpanda serve & echo $! > LPD.pid
|
./lightpanda serve & echo $! > LPD.pid
|
||||||
URL=https://demo-browser.lightpanda.io/campfire-commerce/ node puppeteer/proxy_auth.js
|
|
||||||
BASE_URL=https://demo-browser.lightpanda.io/ node playwright/proxy_auth.js
|
BASE_URL=https://demo-browser.lightpanda.io/ node playwright/proxy_auth.js
|
||||||
|
kill `cat LPD.pid`
|
||||||
|
|
||||||
|
./lightpanda serve --http-proxy 'http://127.0.0.1:3000' & echo $! > LPD.pid
|
||||||
|
URL=https://demo-browser.lightpanda.io/campfire-commerce/ node puppeteer/proxy_auth.js
|
||||||
kill `cat LPD.pid` `cat PROXY.id`
|
kill `cat LPD.pid` `cat PROXY.id`
|
||||||
|
|
||||||
# e2e tests w/ web-bot-auth configuration on.
|
# e2e tests w/ web-bot-auth configuration on.
|
||||||
|
|||||||
@@ -158,20 +158,15 @@ fn createTarget(cmd: anytype) !void {
|
|||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (bc.target_id != null) {
|
||||||
|
return error.TargetAlreadyLoaded;
|
||||||
|
}
|
||||||
if (params.browserContextId) |param_browser_context_id| {
|
if (params.browserContextId) |param_browser_context_id| {
|
||||||
if (std.mem.eql(u8, param_browser_context_id, bc.id) == false) {
|
if (std.mem.eql(u8, param_browser_context_id, bc.id) == false) {
|
||||||
return error.UnknownBrowserContextId;
|
return error.UnknownBrowserContextId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a target already exists, close it first. Lightpanda only supports
|
|
||||||
// one page at a time, so we replace the existing target rather than
|
|
||||||
// rejecting the request. This unblocks automation frameworks (e.g.
|
|
||||||
// Stagehand) that call createTarget multiple times.
|
|
||||||
if (bc.target_id != null) {
|
|
||||||
try doCloseTarget(cmd, bc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if target_id is null, we should never have a page
|
// if target_id is null, we should never have a page
|
||||||
lp.assert(bc.session.page == null, "CDP.target.createTarget not null page", .{});
|
lp.assert(bc.session.page == null, "CDP.target.createTarget not null page", .{});
|
||||||
|
|
||||||
@@ -285,9 +280,34 @@ fn closeTarget(cmd: anytype) !void {
|
|||||||
return error.UnknownTargetId;
|
return error.UnknownTargetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// can't be null if we have a target_id
|
||||||
|
lp.assert(bc.session.page != null, "CDP.target.closeTarget null page", .{});
|
||||||
|
|
||||||
try cmd.sendResult(.{ .success = true }, .{ .include_session_id = false });
|
try cmd.sendResult(.{ .success = true }, .{ .include_session_id = false });
|
||||||
|
|
||||||
try doCloseTarget(cmd, bc);
|
// could be null, created but never attached
|
||||||
|
if (bc.session_id) |session_id| {
|
||||||
|
// Inspector.detached event
|
||||||
|
try cmd.sendEvent("Inspector.detached", .{
|
||||||
|
.reason = "Render process gone.",
|
||||||
|
}, .{ .session_id = session_id });
|
||||||
|
|
||||||
|
// detachedFromTarget event
|
||||||
|
try cmd.sendEvent("Target.detachedFromTarget", .{
|
||||||
|
.targetId = target_id,
|
||||||
|
.sessionId = session_id,
|
||||||
|
.reason = "Render process gone.",
|
||||||
|
}, .{});
|
||||||
|
|
||||||
|
bc.session_id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bc.session.removePage();
|
||||||
|
for (bc.isolated_worlds.items) |world| {
|
||||||
|
world.deinit();
|
||||||
|
}
|
||||||
|
bc.isolated_worlds.clearRetainingCapacity();
|
||||||
|
bc.target_id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getTargetInfo(cmd: anytype) !void {
|
fn getTargetInfo(cmd: anytype) !void {
|
||||||
@@ -448,41 +468,6 @@ fn setAutoAttach(cmd: anytype) !void {
|
|||||||
try cmd.sendResult(null, .{});
|
try cmd.sendResult(null, .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Close the current target in a browser context: send detach events,
|
|
||||||
/// remove the page, clean up isolated worlds, and clear the target_id.
|
|
||||||
/// Shared by closeTarget and createTarget (which auto-closes before
|
|
||||||
/// creating a replacement).
|
|
||||||
fn doCloseTarget(cmd: anytype, bc: anytype) !void {
|
|
||||||
// can't be null if we have a target_id
|
|
||||||
lp.assert(bc.session.page != null, "CDP.target.doCloseTarget null page", .{});
|
|
||||||
|
|
||||||
// could be null, created but never attached
|
|
||||||
if (bc.session_id) |session_id| {
|
|
||||||
try cmd.sendEvent("Inspector.detached", .{
|
|
||||||
.reason = "Render process gone.",
|
|
||||||
}, .{ .session_id = session_id });
|
|
||||||
|
|
||||||
try cmd.sendEvent("Target.detachedFromTarget", .{
|
|
||||||
.targetId = &bc.target_id.?,
|
|
||||||
.sessionId = session_id,
|
|
||||||
.reason = "Render process gone.",
|
|
||||||
}, .{});
|
|
||||||
|
|
||||||
bc.session_id = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try cmd.sendEvent("Target.targetDestroyed", .{
|
|
||||||
.targetId = &bc.target_id.?,
|
|
||||||
}, .{});
|
|
||||||
|
|
||||||
bc.session.removePage();
|
|
||||||
for (bc.isolated_worlds.items) |world| {
|
|
||||||
world.deinit();
|
|
||||||
}
|
|
||||||
bc.isolated_worlds.clearRetainingCapacity();
|
|
||||||
bc.target_id = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn doAttachtoTarget(cmd: anytype, target_id: []const u8) !void {
|
fn doAttachtoTarget(cmd: anytype, target_id: []const u8) !void {
|
||||||
const bc = cmd.browser_context.?;
|
const bc = cmd.browser_context.?;
|
||||||
const session_id = bc.session_id orelse cmd.cdp.session_id_gen.next();
|
const session_id = bc.session_id orelse cmd.cdp.session_id_gen.next();
|
||||||
@@ -661,7 +646,6 @@ test "cdp.target: closeTarget" {
|
|||||||
{
|
{
|
||||||
try ctx.processMessage(.{ .id = 11, .method = "Target.closeTarget", .params = .{ .targetId = "TID-000000000A" } });
|
try ctx.processMessage(.{ .id = 11, .method = "Target.closeTarget", .params = .{ .targetId = "TID-000000000A" } });
|
||||||
try ctx.expectSentResult(.{ .success = true }, .{ .id = 11 });
|
try ctx.expectSentResult(.{ .success = true }, .{ .id = 11 });
|
||||||
try ctx.expectSentEvent("Target.targetDestroyed", .{ .targetId = "TID-000000000A" }, .{});
|
|
||||||
try testing.expectEqual(null, bc.session.page);
|
try testing.expectEqual(null, bc.session.page);
|
||||||
try testing.expectEqual(null, bc.target_id);
|
try testing.expectEqual(null, bc.target_id);
|
||||||
}
|
}
|
||||||
@@ -787,53 +771,6 @@ test "cdp.target: detachFromTarget" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "cdp.target: createTarget closes existing target (issue #1962)" {
|
|
||||||
var ctx = try testing.context();
|
|
||||||
defer ctx.deinit();
|
|
||||||
const bc = try ctx.loadBrowserContext(.{ .id = "BID-9" });
|
|
||||||
{
|
|
||||||
// Create first target
|
|
||||||
try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .browserContextId = "BID-9" } });
|
|
||||||
try testing.expectEqual(true, bc.target_id != null);
|
|
||||||
try ctx.expectSentResult(.{ .targetId = bc.target_id.? }, .{ .id = 10 });
|
|
||||||
|
|
||||||
// Create second target — should succeed by auto-closing the first
|
|
||||||
try ctx.processMessage(.{ .id = 11, .method = "Target.createTarget", .params = .{ .browserContextId = "BID-9" } });
|
|
||||||
try ctx.expectSentEvent("Target.targetDestroyed", .{ .targetId = "FID-0000000001" }, .{});
|
|
||||||
try testing.expectEqual(true, bc.target_id != null);
|
|
||||||
try ctx.expectSentResult(.{ .targetId = bc.target_id.? }, .{ .id = 11 });
|
|
||||||
|
|
||||||
// Page should exist (new target is active)
|
|
||||||
try testing.expectEqual(true, bc.session.page != null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "cdp.target: createTarget closes existing attached target (issue #1962)" {
|
|
||||||
var ctx = try testing.context();
|
|
||||||
defer ctx.deinit();
|
|
||||||
const bc = try ctx.loadBrowserContext(.{ .id = "BID-9" });
|
|
||||||
{
|
|
||||||
// Create and attach first target
|
|
||||||
try ctx.processMessage(.{ .id = 10, .method = "Target.createTarget", .params = .{ .browserContextId = "BID-9" } });
|
|
||||||
try testing.expectEqual(true, bc.target_id != null);
|
|
||||||
try ctx.expectSentResult(.{ .targetId = bc.target_id.? }, .{ .id = 10 });
|
|
||||||
|
|
||||||
try ctx.processMessage(.{ .id = 11, .method = "Target.attachToTarget", .params = .{ .targetId = bc.target_id.? } });
|
|
||||||
const session_id = bc.session_id.?;
|
|
||||||
try ctx.expectSentResult(.{ .sessionId = session_id }, .{ .id = 11 });
|
|
||||||
|
|
||||||
// Create second target — should close and detach the first
|
|
||||||
try ctx.processMessage(.{ .id = 12, .method = "Target.createTarget", .params = .{ .browserContextId = "BID-9" } });
|
|
||||||
// Should have sent detach events for the old session
|
|
||||||
try ctx.expectSentEvent("Inspector.detached", .{ .reason = "Render process gone." }, .{ .session_id = session_id });
|
|
||||||
try ctx.expectSentEvent("Target.detachedFromTarget", .{ .sessionId = session_id, .reason = "Render process gone." }, .{});
|
|
||||||
try ctx.expectSentEvent("Target.targetDestroyed", .{ .targetId = "FID-0000000001" }, .{});
|
|
||||||
// New target should be created
|
|
||||||
try testing.expectEqual(true, bc.target_id != null);
|
|
||||||
try ctx.expectSentResult(.{ .targetId = bc.target_id.? }, .{ .id = 12 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test "cdp.target: detachFromTarget without session" {
|
test "cdp.target: detachFromTarget without session" {
|
||||||
var ctx = try testing.context();
|
var ctx = try testing.context();
|
||||||
defer ctx.deinit();
|
defer ctx.deinit();
|
||||||
|
|||||||
Reference in New Issue
Block a user