Filed here because issues are disabled on pestphp/pest-plugin-browser. This concerns that package.
What happened
In LaravelHttpServer::asset(), JavaScript assets are read with a single fread() call sized to the file length:
// src/Drivers/LaravelHttpServer.php (v4.3.1, the `.js` branch of asset())
$temporaryContent = fread($file, (int) filesize($filepath));
fread() returns at most one chunk per call (8192 bytes on a stock build), regardless of the requested length. So any served .js file larger than 8 KB is delivered truncated to 8192 bytes.
In practice this hits the bundled application JS (e.g. a Vite app.js), which is almost always well over 8 KB. The browser receives a truncated script and throws:
Uncaught SyntaxError: Unexpected end of input
This is only reached for .js files because that branch buffers the content (to rewrite asset URLs) before streaming it; other assets are streamed directly from the file handle and are unaffected.
Impact
Any page that loads a JS bundle larger than 8 KB fails assertNoJavascriptErrors() (and any behaviour that depends on the bundle executing). The page HTML itself still renders, so assertSee(...) passes — which makes it look like an environment/CI issue rather than truncated JS.
Reproduction
- Build a front-end bundle larger than 8 KB (e.g. a default Laravel + Vite
app.js).
- Visit any page that loads it in a browser test and call
assertNoJavascriptErrors().
- The assertion fails with
Uncaught SyntaxError: Unexpected end of input.
Confirmed by fetching the served asset from within the page: content-length/actual body is 8192 bytes while the file on disk is ~44 KB, and the truncated body fails to parse.
Suggested fix
Read the whole stream instead of relying on a single fread():
$temporaryContent = stream_get_contents($file);
stream_get_contents() drains the handle completely, so the full asset is buffered before the URL rewrite + streaming. This resolves the truncation in our test suite (browser suite went from failing on every JS-loading page to fully green).
Version
pestphp/pest-plugin-browser v4.3.1
What happened
In
LaravelHttpServer::asset(), JavaScript assets are read with a singlefread()call sized to the file length:fread()returns at most one chunk per call (8192 bytes on a stock build), regardless of the requested length. So any served.jsfile larger than 8 KB is delivered truncated to 8192 bytes.In practice this hits the bundled application JS (e.g. a Vite
app.js), which is almost always well over 8 KB. The browser receives a truncated script and throws:This is only reached for
.jsfiles because that branch buffers the content (to rewrite asset URLs) before streaming it; other assets are streamed directly from the file handle and are unaffected.Impact
Any page that loads a JS bundle larger than 8 KB fails
assertNoJavascriptErrors()(and any behaviour that depends on the bundle executing). The page HTML itself still renders, soassertSee(...)passes — which makes it look like an environment/CI issue rather than truncated JS.Reproduction
app.js).assertNoJavascriptErrors().Uncaught SyntaxError: Unexpected end of input.Confirmed by fetching the served asset from within the page:
content-length/actual body is 8192 bytes while the file on disk is ~44 KB, and the truncated body fails to parse.Suggested fix
Read the whole stream instead of relying on a single
fread():stream_get_contents()drains the handle completely, so the full asset is buffered before the URL rewrite + streaming. This resolves the truncation in our test suite (browser suite went from failing on every JS-loading page to fully green).Version
pestphp/pest-plugin-browserv4.3.1