diff --git a/bin/playwright-server.js b/bin/playwright-server.js index f9fa1b5..5d55e28 100644 --- a/bin/playwright-server.js +++ b/bin/playwright-server.js @@ -121,7 +121,7 @@ class PlaywrightServer extends BaseHandler { const info = this.validateResource(this.routes, command.routeId, 'Route'); const route = info.route || info; const registry = CommandRegistry.create({ - fulfill: () => route.fulfill(command.options), + fulfill: () => this.fulfillRoute(route, command.options), abort: () => route.abort(command.errorCode), redirectNavigationRequest: () => this.redirectNavigationRequest(route, info, command), continue: () => this.continueRoute(route, info, command) @@ -131,6 +131,15 @@ class PlaywrightServer extends BaseHandler { this.routes.delete(command.routeId); } + async fulfillRoute(route, options = {}) { + const { isBase64, ...fulfillOptions } = options; + if (isBase64) { + if (typeof fulfillOptions.body !== 'string') throw new Error('route.fulfill isBase64 requires a string body'); + fulfillOptions.body = Buffer.from(fulfillOptions.body, 'base64'); + } + await route.fulfill(fulfillOptions); + } + async redirectNavigationRequest(route, info, command) { if (!this.pages.has(info.contextId)) throw new Error('Navigation redirects require a page route'); this.navigationRedirects.set(info.contextId, command.url); diff --git a/tests/Functional/Network/RouteTest.php b/tests/Functional/Network/RouteTest.php index b773aa4..382850e 100644 --- a/tests/Functional/Network/RouteTest.php +++ b/tests/Functional/Network/RouteTest.php @@ -45,6 +45,25 @@ public function testCanInterceptAndFulfillRequest(): void $this->assertStringContainsString('Mocked response', $result); } + public function testCanFulfillBase64EncodedBinaryBody(): void + { + $this->goto('/index.html'); + $expected = [0x77, 0x4F, 0x46, 0x32, 0x00, 0x01, 0x02, 0xFF]; + + $this->page->route('**/binary', static function ($route) use ($expected): void { + $route->fulfill([ + 'status' => 200, + 'contentType' => 'application/octet-stream', + 'body' => base64_encode(pack('C*', ...$expected)), + 'isBase64' => true, + ]); + }); + + $result = $this->page->evaluate('async () => Array.from(new Uint8Array(await (await fetch("/binary")).arrayBuffer()))'); + + $this->assertSame($expected, $result); + } + public function testCanInterceptAndAbortRequest(): void { $this->goto('/network.html');