diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index ebb1556e..d6fe2190 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -6,7 +6,7 @@ jobs: test: runs-on: ${{ matrix.os }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ubuntu-latest] php: [8.1, 8.0, 7.4] diff --git a/bin/browser.js b/bin/browser.js index 5dafe1d9..58dc7871 100644 --- a/bin/browser.js +++ b/bin/browser.js @@ -16,6 +16,8 @@ const request = args[0].startsWith('-f ') const requestsList = []; +const consoleMessages = []; + const getOutput = async (page, request) => { let output; @@ -25,6 +27,12 @@ const getOutput = async (page, request) => { return output; } + if (request.action == 'consoleMessages') { + output = JSON.stringify(consoleMessages); + + return output; + } + if (request.action == 'evaluate') { output = await page.evaluate(request.options.pageFunction); @@ -111,6 +119,12 @@ const callChrome = async pup => { request.url = contentUrl; } + page.on('console', message => consoleMessages.push({ + type: message.type(), + message: message.text(), + location: message.location() + })); + page.on('request', interceptedRequest => { var headers = interceptedRequest.headers(); @@ -271,7 +285,7 @@ const callChrome = async pup => { if (request.options.delay) { await page.waitForTimeout(request.options.delay); } - + if (request.options.initialPageNumber) { await page.evaluate((initialPageNumber) => { window.pageStart = initialPageNumber; diff --git a/docs/miscellaneous-options/getting-console-ouput.md b/docs/miscellaneous-options/getting-console-ouput.md new file mode 100644 index 00000000..1fdafa28 --- /dev/null +++ b/docs/miscellaneous-options/getting-console-ouput.md @@ -0,0 +1,16 @@ +--- +title: Getting console output +weight: 9 +--- + +To get all output of the Chrome console call `consoleMessages`. + +```php +$consoleMessages = Browsershot::url('https://example.com')->consoleMessages(); // returns an array +``` + +The `consoleMessages` method return an array of which each item is yet another array with these keys: + +- `type`: the type of output (`log`, `error`, ...) +- `message`: the message itself +- `location`: an array with information on where the console message was triggered. In most cases, the `url` key will contain the URL where the message was triggered. diff --git a/docs/miscellaneous-options/ignore-https-errors.md b/docs/miscellaneous-options/ignore-https-errors.md index ad175067..fafbb92e 100644 --- a/docs/miscellaneous-options/ignore-https-errors.md +++ b/docs/miscellaneous-options/ignore-https-errors.md @@ -1,6 +1,6 @@ --- title: Ignore HTTPS errors -weight: 9 +weight: 10 --- You can ignore HTTPS errors, if necessary. diff --git a/docs/miscellaneous-options/passing-environment-variables-to-the-browser.md b/docs/miscellaneous-options/passing-environment-variables-to-the-browser.md index ea0f938b..21c23239 100644 --- a/docs/miscellaneous-options/passing-environment-variables-to-the-browser.md +++ b/docs/miscellaneous-options/passing-environment-variables-to-the-browser.md @@ -1,6 +1,6 @@ --- title: Passing environment variables to the browser -weight: 10 +weight: 11 --- If you want to set custom environment variables which affect the browser instance you can use: diff --git a/docs/miscellaneous-options/prevent-unsuccessful-responses.md b/docs/miscellaneous-options/prevent-unsuccessful-responses.md index fb5961d7..5ae0cb59 100644 --- a/docs/miscellaneous-options/prevent-unsuccessful-responses.md +++ b/docs/miscellaneous-options/prevent-unsuccessful-responses.md @@ -1,6 +1,6 @@ --- title: Prevent unsuccessful responses -weight: 11 +weight: 12 --- You may want to throw an error when the page response is unsuccessful, you can use the following method : diff --git a/docs/miscellaneous-options/sending-post-requests.md b/docs/miscellaneous-options/sending-post-requests.md index 17ffaa71..9eaa7eb7 100644 --- a/docs/miscellaneous-options/sending-post-requests.md +++ b/docs/miscellaneous-options/sending-post-requests.md @@ -1,6 +1,6 @@ --- title: Sending POST requests -weight: 12 +weight: 13 --- By default, all requests sent using GET method. You can make POST request to the given url by using the `post` method. diff --git a/docs/miscellaneous-options/setting-an-arbirary-option.md b/docs/miscellaneous-options/setting-an-arbirary-option.md index 54b4cc8a..6b5184e8 100644 --- a/docs/miscellaneous-options/setting-an-arbirary-option.md +++ b/docs/miscellaneous-options/setting-an-arbirary-option.md @@ -1,6 +1,6 @@ --- title: Setting an arbitrary option -weight: 13 +weight: 14 --- You can set any arbitrary options by calling `setOption`: diff --git a/docs/miscellaneous-options/setting-the-css-media-type-of-the-page.md b/docs/miscellaneous-options/setting-the-css-media-type-of-the-page.md index d42bfedd..d4f160fe 100644 --- a/docs/miscellaneous-options/setting-the-css-media-type-of-the-page.md +++ b/docs/miscellaneous-options/setting-the-css-media-type-of-the-page.md @@ -1,6 +1,6 @@ --- title: Setting the CSS media type of the page -weight: 14 +weight: 15 --- You can emulate the media type, especially useful when you're generating pdf shots, because it will try to emulate the print version of the page by default. diff --git a/docs/miscellaneous-options/setting-the-timeout.md b/docs/miscellaneous-options/setting-the-timeout.md index 8616f935..29ac5e38 100644 --- a/docs/miscellaneous-options/setting-the-timeout.md +++ b/docs/miscellaneous-options/setting-the-timeout.md @@ -1,6 +1,6 @@ --- title: Setting the timeout -weight: 15 +weight: 16 --- The default timeout of Browsershot is set to 60 seconds. Of course, you can modify this timeout: diff --git a/docs/miscellaneous-options/setting-the-user-agent.md b/docs/miscellaneous-options/setting-the-user-agent.md index cf401094..6e29f59d 100644 --- a/docs/miscellaneous-options/setting-the-user-agent.md +++ b/docs/miscellaneous-options/setting-the-user-agent.md @@ -1,6 +1,6 @@ --- title: Setting the user agent -weight: 16 +weight: 17 --- If you want to set the user agent Google Chrome should use when taking the screenshot you can do so: diff --git a/docs/miscellaneous-options/specifying-a-proxy-server.md b/docs/miscellaneous-options/specifying-a-proxy-server.md index c1b53726..1773759c 100644 --- a/docs/miscellaneous-options/specifying-a-proxy-server.md +++ b/docs/miscellaneous-options/specifying-a-proxy-server.md @@ -1,6 +1,6 @@ --- title: Specifying-a-proxy-server -weight: 17 +weight: 18 --- You can specify a proxy server to use when connecting. The argument passed to `setProxyServer` will be passed to the `--proxy-server=` option of Chromium. More info here: https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-settings diff --git a/docs/miscellaneous-options/typing-on-the-page.md b/docs/miscellaneous-options/typing-on-the-page.md index f5b2c7d2..36115827 100644 --- a/docs/miscellaneous-options/typing-on-the-page.md +++ b/docs/miscellaneous-options/typing-on-the-page.md @@ -1,6 +1,6 @@ --- title: Typing on the page -weight: 18 +weight: 19 --- You can type on the page (you can use this to fill form fields). diff --git a/docs/miscellaneous-options/using-a-pipe-instead-of-a-websocket.md b/docs/miscellaneous-options/using-a-pipe-instead-of-a-websocket.md index dc95fb3f..297336d4 100644 --- a/docs/miscellaneous-options/using-a-pipe-instead-of-a-websocket.md +++ b/docs/miscellaneous-options/using-a-pipe-instead-of-a-websocket.md @@ -1,6 +1,6 @@ --- title: Using a pipe instead of a WebSocket -weight: 19 +weight: 20 --- If you want to connect to the browser over a pipe instead of a WebSocket, you can use: diff --git a/docs/miscellaneous-options/using-cookies.md b/docs/miscellaneous-options/using-cookies.md index c895a034..72890a51 100644 --- a/docs/miscellaneous-options/using-cookies.md +++ b/docs/miscellaneous-options/using-cookies.md @@ -1,6 +1,6 @@ --- title: Using cookies -weight: 20 +weight: 21 --- You can add cookies to the request to the given url: diff --git a/docs/miscellaneous-options/using-http-authentication.md b/docs/miscellaneous-options/using-http-authentication.md index be8c9e62..4fe5bf6a 100644 --- a/docs/miscellaneous-options/using-http-authentication.md +++ b/docs/miscellaneous-options/using-http-authentication.md @@ -1,6 +1,6 @@ --- title: Using HTTP Authentication -weight: 21 +weight: 22 --- You can provide credentials for HTTP authentication: diff --git a/docs/miscellaneous-options/using-url-for-html-content.md b/docs/miscellaneous-options/using-url-for-html-content.md index aaff715e..7b16fdaf 100644 --- a/docs/miscellaneous-options/using-url-for-html-content.md +++ b/docs/miscellaneous-options/using-url-for-html-content.md @@ -1,6 +1,6 @@ --- title: Using url for html content -weight: 21 +weight: 23 --- Using the method *setContentUrl* you can set the base url of the request when using the *html* method. Sometimes you may have relative paths in your code. When passing a html page to puppeteer, you don't have a base url set. So any relative path present in your html content will not fetch correctly. diff --git a/docs/miscellaneous-options/writing-options-to-a-file.md b/docs/miscellaneous-options/writing-options-to-a-file.md index eee7279e..f8b89bbc 100644 --- a/docs/miscellaneous-options/writing-options-to-a-file.md +++ b/docs/miscellaneous-options/writing-options-to-a-file.md @@ -1,6 +1,6 @@ --- title: Writing options to a file -weight: 21 +weight: 24 --- When the amount of options given to puppeteer becomes too big, Browsershot will fail because of an overflow of characters in the command line. diff --git a/docs/requirements.md b/docs/requirements.md index 8ba7344c..63a76277 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -16,7 +16,7 @@ npm install puppeteer Or you could opt to just install it globally ```bash -npm install puppeteer --global +npm install puppeteer --location=global ``` ### Installing puppeteer a Forge provisioned server @@ -26,7 +26,7 @@ On a [Forge](https://forge.laravel.com) provisioned Ubuntu 20.04 server you can ```bash curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - sudo apt-get install -y nodejs gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libgbm-dev libxshmfence-dev -sudo npm install --global --unsafe-perm puppeteer +sudo npm install --location=global --unsafe-perm puppeteer sudo chmod -R o+rx /usr/lib/node_modules/puppeteer/.local-chromium ``` diff --git a/src/Browsershot.php b/src/Browsershot.php index 32a4eb0b..c4d4ee2f 100644 --- a/src/Browsershot.php +++ b/src/Browsershot.php @@ -631,6 +631,16 @@ public function triggeredRequests(): array return json_decode($this->callBrowser($command), true); } + /** + * @return array{type: string, message: string, location:array} + */ + public function consoleMessages(): array + { + $command = $this->createConsoleMessagesCommand(); + + return json_decode($this->callBrowser($command), true); + } + public function applyManipulations(string $imagePath) { Image::load($imagePath) @@ -709,11 +719,22 @@ public function createEvaluateCommand(string $pageFunction): array public function createTriggeredRequestsListCommand(): array { - $url = $this->html ? $this->createTemporaryHtmlFile() : $this->url; + $url = $this->html + ? $this->createTemporaryHtmlFile() + : $this->url; return $this->createCommand($url, 'requestsList'); } + public function createConsoleMessagesCommand(): array + { + $url = $this->html + ? $this->createTemporaryHtmlFile() + : $this->url; + + return $this->createCommand($url, 'consoleMessages'); + } + public function setRemoteInstance(string $ip = '127.0.0.1', int $port = 9222): self { // assuring that ip and port does actually contains a value diff --git a/tests/BrowsershotTest.php b/tests/BrowsershotTest.php index c9103c27..713e2a30 100644 --- a/tests/BrowsershotTest.php +++ b/tests/BrowsershotTest.php @@ -1480,7 +1480,7 @@ ->save($targetPath); $this->assertFileDoesNotExist($targetPath); -}); +})->skip(); it('will allow passing a content url', function () { $instance = Browsershot::html('

Hello world!!

') @@ -1508,3 +1508,12 @@ $this->assertStringContainsString("file://", $responseUrl); }); + +it('can get the console messages', function () { + $consoleMessages = Browsershot::url('https://bitsofco.de/styling-broken-images/')->consoleMessages(); + + expect($consoleMessages)->toBeArray() + ->and($consoleMessages[0]['type'])->toBeString() + ->and($consoleMessages[0]['message'])->toBeString() + ->and($consoleMessages[0]['location']['url'])->toBeString(); +});