diff --git a/src/Api/Concerns/InteractsWithScreen.php b/src/Api/Concerns/InteractsWithScreen.php index 4ff8b439..655f7b0b 100644 --- a/src/Api/Concerns/InteractsWithScreen.php +++ b/src/Api/Concerns/InteractsWithScreen.php @@ -18,6 +18,20 @@ public function screenshot(bool $fullPage = true, ?string $filename = null): sel return $this; } + /** + * Performs a series of screenshots at different browser sizes to emulate different devices. + * + * @param array $responsiveScreenSizes + */ + public function responsiveScreenshots(?string $filename = null, array $responsiveScreenSizes = []): self + { + $filename = $this->getFilename($filename); + + $this->page->responsiveScreenshots($filename, $responsiveScreenSizes); + + return $this; + } + /** * Performs a screenshot of an element and saves it to the given path. */ diff --git a/src/Playwright/Page.php b/src/Playwright/Page.php index d97f3db3..d750075a 100644 --- a/src/Playwright/Page.php +++ b/src/Playwright/Page.php @@ -438,6 +438,29 @@ public function screenshot(bool $fullPage = true, ?string $filename = null): ?st return Screenshot::save($binary, $filename); } + /** + * Take a series of screenshots at different browser sizes to emulate different devices. + * + * @param array $responsiveScreenSizes + */ + public function responsiveScreenshots(string $filename, array $responsiveScreenSizes = []): self + { + if (mb_substr($filename, -1) !== '/') { + $filename .= '-'; + } + + if ($responsiveScreenSizes === []) { + $responsiveScreenSizes = $this->responsiveScreenSizes(); + } + + foreach ($responsiveScreenSizes as $device => $size) { + $this->setViewportSize($size['width'], $size['height']) + ->screenshot(filename: "$filename$device"); + } + + return $this; + } + /** * Make screenshot of a specific element. */ @@ -662,6 +685,41 @@ private function screenshotOptions(bool $fullPage = true): array ]; } + /** + * Returns the responsive screen sizes. + * + * @return array + */ + private function responsiveScreenSizes(): array + { + return [ + 'xs' => [ + 'width' => 360, + 'height' => 640, + ], + 'sm' => [ + 'width' => 640, + 'height' => 360, + ], + 'md' => [ + 'width' => 768, + 'height' => 1024, + ], + 'lg' => [ + 'width' => 1024, + 'height' => 768, + ], + 'xl' => [ + 'width' => 1280, + 'height' => 1024, + ], + '2xl' => [ + 'width' => 1536, + 'height' => 864, + ], + ]; + } + /** * Create an HTML view for the image diff. */ diff --git a/tests/Browser/Webpage/ScreenshotTest.php b/tests/Browser/Webpage/ScreenshotTest.php index cc15fceb..2a522069 100644 --- a/tests/Browser/Webpage/ScreenshotTest.php +++ b/tests/Browser/Webpage/ScreenshotTest.php @@ -42,3 +42,40 @@ expect(file_exists(Screenshot::path('element-screenshot.png'))) ->toBeTrue(); }); + +it('captures responsive screenshots', function (string $device): void { + Route::get('/', fn (): string => '
+

Responsive Screenshot Test

+

This page will be captured at different screen sizes

+
'); + + $page = visit('/'); + + $page->responsiveScreenshots(filename: 'responsive-test'); + + expect(file_exists(Screenshot::path("responsive-test-{$device}.png"))) + ->toBeTrue(); +})->with(['xs', 'sm', 'md', 'lg', 'xl', '2xl']); + +it('captures responsive screenshots with custom screen sizes', function (): void { + Route::get('/', fn (): string => '
+

Responsive Screenshot Test

+

This page will be captured at different screen sizes

+
'); + + $page = visit('/'); + + $responsiveScreenSizes = [ + 'xs' => ['width' => 360, 'height' => 640], + 'sm' => ['width' => 640, 'height' => 360], + ]; + + $page->responsiveScreenshots(filename: 'responsive-test', responsiveScreenSizes: $responsiveScreenSizes); + + $devices = array_keys($responsiveScreenSizes); + + foreach ($devices as $device) { + expect(file_exists(Screenshot::path("responsive-test-{$device}.png"))) + ->toBeTrue(); + } +});