npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

playshot

v1.0.6

Published

Magic potion for playwright to support visual regression with cloud storage

Downloads

9

Readme

playshot

playshot is a library designed to enhance the visual regression testing capabilities of Playwright. Unlike Playwright's built-in functionality, which stores screenshots locally, this library allows you to store screenshots on remote servers like Amazon S3 or SFTP servers, eliminating the need to manage screenshots in your local file system.

Installation

You can install playshot via npm:

npm install playshot --save

Basic Usage

Create an instance of PlayShot:

const playshot = new PlayShot({
  adapter: s3Adapter, // or sshAdapter for SFTP
  remotePathDelimiter: '__screenshots__',
});

The remotePathDelimiter is a required parameter that specifies how to divide the local file path to correspond with the storage path on S3 or on remote sftp server.

For example if the snapshotPathTemplate path in config file is

export default defineConfig({
  snapshotPathTemplate: `{testDir}/__screenshots__/{testFileName}/{arg}{ext}`,
  // other option
});

and if remotePathDelimiter is __screenshots__, the screenshots will be stored in s3 under {testFileName}/{arg}{ext} directory

Example:

  1. Local file path: /Users/user/tests/__screenshots__/test.spect.ts/test-existing-image-s3-without-name-1.png
  2. The corresponding S3 key for this screenshot would be test.spect.ts/test-existing-image-s3-without-name-1.png under the bucket configured in the adapter.

Options:

| Name | type | Required | Description | | |----------------------|----------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---| | adapter | StorageAdapter | Yes | Adpater that handles the storage and retrieval of images from remote server eg: AmazonS3Adapter, SftpAdapter | | | remotePathDelimiter | String | Yes | Specifies how to divide the local file path to correspond with the storage path on S3 or on remote sftp server. | | | attachImagesToReport | Boolean | No | When enabled, if screenshot matching fails, the plugin attaches the actual, expected, and difference images to the HTML report in base64 format. This feature is particularly useful when running tests in CI environments. Note: Enabling this feature will increase the file size of the HTML report. | |

Setting up adapters:

Amazon S3 Adapter:

const s3Adapter = new AmazonS3Adapter(new S3Client({
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY,
    secretAccessKey: process.env.S3_SECRET_KEY,
  },
  region: process.env.S3_REGION,
} as any), {
  bucket: process.env.S3_BUCKET, // bucket where the images are to be stored
});

SFTP adapter:

const sftpAdapter = new SftpAdapter({
  remoteDirectory: '/home/user/visual-regressions',
  pathSeparator: '/', // for windows server it should be "\\"
  host: 'localhost', // remote host name
  username: '',
  password: '',
  port: 22,
});

Creating matcher object and use it in your tests:

import { test, expect } from '@playwright/test';
import { PlayShot } from 'playshot';

const playshot = new PlayShot({
  adapter: s3Adapter, // or sshAdapter for SFTP
  remotePathDelimiter: '__screenshots__',
});

test('snapshot test', async ({ page }, testInfo) => {
  const playShot = playshot.createMatcher(page, testInfo);

  await page.goto('https://www.google.com');
  await playShot.assertPage();
  // or
  await playShot.assertElement(page.locator('table')); // asserts a specific web element
  await playShot.assertPage({
    fullScreen: true, // asserts the full page
  });
});

Both assertElement and assertPage methods support all the options available in the native toHaveScreenshot matcher provided by Playwright.

Configuting matcher via fixtures:

The simplest way to configure the matchers is by using Playwright test fixtures.

extended-test.ts

import { test as BaseTest, expect } from '@playwright/test';
import { PlayShot } from 'playwright-cloud-visuals';

const playshot = new PlayShot({
  adapter: s3Adapter, // or sshAdapter for SFTP
  remotePathDelimiter: '__screenshots__',
});

const test =
  BaseTest.extend <{ playShot: PlayShotMatcher }>
  {
    playShot: async ({ page }, use, testInfo) => {
      await use(playshot.createMatcher(page, testInfo));
    },
  };

export default test;

visual-test.spec.ts

import test from './extended-test';

test('snapshot test', async ({ page, playShot }) => {
  await page.goto('https://www.google.com');
  await playShot.assertPage();
  await playShot.assertElement(page.locator('table')); // asserts a specific web element
  await playShot.assertPage({
    fullScreen: true, // asserts the full page
  });
});

How It Works

  1. When the assertion method is invoked via assertElement or assertPage, the plugin constructs the expected image path internally and checks if the image already exists on the remote server. If the image is found, it is downloaded and placed in the directory where Playwright looks for baseline screenshots.
  2. If the tests are run for the first time and no baseline images are available, the plugin automatically identifies this and uploads the screenshot captured by Playwright to the remote server.
  3. If the user explicitly wants to update an image, the plugin will replace the existing image with the newly captured screenshot.

Advanced Features

  • Automatic Screenshot Upload: Missing screenshots are automatically pushed to the remote server based on test failures. You dont need to save the screenshots to the version control.
  • Screenshot Update: Users can individually update screenshots when the UI changes.
await playShot.assertPage({
  update: true,
});

This will replace the existing image in remote server with the latest screenshot taken during test execution

  • Flexible Validation: Methods for validating visual regression for both pages and individual web elements:
await playShot.assertElement(locator);
await playShot.assertPage();
await playShot.assertPage({ fullScreen: true });
await playShot.assertPage('login-page.png');
await playShot.assertPage(['nested-folder', 'login-page.png']);
  • Support for Soft Assertions: The library includes built-in support for soft assertions, which means that test failures will not halt the execution of subsequent test steps. The test will continue to run even if a soft assertion fails.
await playShot.soft.assertElement(locator);
await playShot.soft.assertPage();
await playShot.soft.assertPage({ fullScreen: true });
await playShot.soft.assertPage('login-page.png');
await playShot.soft.assertPage(['nested-folder', 'login-page.png']);

License

This project is licensed under MIT License - see the LICENSE file for details.