Nascent Personality Manifestation

    @digigov/storybook-addon-playwright
    TypeScript icon, indicating that this package has built-in type declarations

    4.15.1 • Public • Published

    storybook-addon-playwright

    An addon to visually test the stories in the multiple browsers within storybook environment.

    Addon will not work in storybook static build, but the screenshots can be tested against the static build files.

    This package has been tested with react framework only, therefore it may not work with other frameworks.

    Works with Component Story Format (CSF) only.

    addon-screenshot

    Compatibility

    Package Version
    storybook ~6.4
    playwright ~1.17

    Motivation

    Being able to make components that feel and look same in all browser were always a challenge, it's required that developer keep switching between browsers and visually checking the components. It's also important to keep track of the changes and be able to detect changes as quickly as possible. That's why this add-on has been created. With the help of playwright and storybook now it's possible to visually check components and be notified of changes all in one place.

    Example

    storybook-addon-playwright-example

    Getting Started

    Required packages:

    • storybook-addon-playwright
    • @storybook/addon-knobs
    yarn add storybook-addon-playwright @storybook/addon-knobs --dev

    Configuration

    within .storybook/main.js

    module.exports = {
      stories: ['../**/*.stories.[tj]sx'],
      addons: [
        '@storybook/addon-knobs/register',
        'storybook-addon-playwright/preset',
        'storybook-addon-playwright/register',
      ],
    };

    If story book complain that it can not find register in @storybook/addon-knobs/register path you may need to point it to destination folder: @storybook/addon-knobs/dist/register

    within .storybook/main.js OR .storybook/middleware.js:

    const { setConfig } = require('storybook-addon-playwright/configs');
    const playwright = require('playwright');
    
    (async () => {
      let browser = {
        chromium: await playwright['chromium'].launch(),
        firefox: await playwright['firefox'].launch(),
        webkit: await playwright['webkit'].launch(),
      };
      setConfig({
        storybookEndpoint: `http://localhost:6006/`,
        getPage: async (browserType, options) => {
          const page = await browser[browserType].newPage(options);
          return page;
        },
        afterScreenshot: async (page) => {
          await page.close();
        },
      });
    })();

    within .storybook/middleware.js :

    const middleware = require('storybook-addon-playwright/middleware');
    module.exports = middleware;

    setConfig Options

    • storybookEndpoint
    • enableMigration
    • beforeScreenshot
    • afterScreenshot
    • beforeStoryImageDiff
    • afterStoryImageDiff
    • beforeFileImageDiff
    • afterFileImageDiff
    • beforeAllImageDiff
    • afterAllImageDiff
    • pageGotoOptions
    • afterUrlConstruction
    • afterNavigation
    • releaseModifierKey
    • screenshotOptions
    • theme

    storybookEndpoint

    storybookEndpoint must match the ip/port of storybook.

    For docker and none locale browsers, the public ip address of storybook required.

    enableMigration

    If set true will apply changes to the json file generate by add-on, read more in Migration section.

    beforeScreenshot

    Will be called before taking a screenshot, useful to manipulate the page.

    afterScreenshot

    Will be called after a screenshot taken.

    afterStoryImageDiff

    Will be called before/after running image diff test on whole application screenshot.

    beforeStoryImageDiff/afterStoryImageDiff

    Will be called before/after running image diff on particular story.

    beforeFileImageDiff/afterFileImageDiff

    Will be called before/after running image diff on particular file.

    beforeAllImageDiff/afterAllImageDiff

    Will be called after imageDiff process of all stories screenshots complete.

    pageGotoOptions

    please refer top Playwright API page.goto option

    afterUrlConstruction

    Will be called before page.goto, can be used to manipulate url.

    afterNavigation

    Will be called when page navigated to story.

    releaseModifierKey

    When set to true, will execute keyboard.up for modifier key, Shift, Meta, Control, or Alt, after screenshot taken.

    screenshotOptions

    Default Options to apply when taking screenshot.

    theme

    It overrides the default theme of the addon. It is a json of type material-ui Theme object.

    .
    .
    .
    setConfig({
      theme: {
        palette: {
          primary: {
            main: '#0052cc',
          },
          secondary: {
            main: '#edf2ff',
          },
        },
      }
    });
    .
    .
    .

    How it works

    This add-on is basically an interface between playwright and storybook stories. Add-on executes user instruction on the page provided in configuration.

    Instructions created by user will save in a json file next to the story file. therefore its available for the next load.

    This add-on consist of there parts:

    • Action list panel
    • Screenshots list panel
    • Screenshots preview panel

    Action list panel:

    Action panel act like a playground, it consists of the list of action sets that created by user for specific story and will be executed in the browser page when selected.

    An action set can have single or multiple actions.

    Actions are referred to the playwright page methods such as click, mouse move etc...

    Screenshots list panel

    This panel holds the screenshots taken previously by user, here you can manage screenshots such as delete edit or sort screenshots.

    Screenshots preview panel

    The preview panel displays the latest screenshots taken by the playwright, it can selectively display all or some of the supported browser by playwright.

    Here you can save and change the screenshots settings such as with, height etc.

    The screenshots are saved in the folder named __screenshots__ under the story folder.

    Add or extend playwright page methods

    To add or extend the playwright method, the following properties are available in the setConfig method:

    • customActionSchema

    customActionSchema

    This property enables developer to add a new method to the playwright page. every entries in the customActionSchema property will appear in the 'Add Actions' menu under the Actions panel.

    This property follows the json-schema rules with one additional property named parameters, therefore clear understanding of json-schema required.

    Here is an example to add a box to the page:

    //async function addBox(this: Page, position: { x: number; y: number })
    async function addBox(position) {
      await this.evaluate((pos) => {
        if (!pos) return;
        const div = document.createElement('div');
        div.style.backgroundColor = '#009EEA';
        div.style.width = '200px';
        div.style.height = '200px';
        div.style.position = 'absolute';
        div.style.top = pos.y + 'px';
        div.style.left = pos.x + 'px';
        document.body.append(div);
      }, position);
    }
    
    (async () => {
      let browser = {
        chromium: await playwright['chromium'].launch(),
        firefox: await playwright['firefox'].launch(),
        webkit: await playwright['webkit'].launch(),
      };
      setConfig({
        storybookEndpoint: `http://localhost:6006/`,
        getPage: async (browserType, options) => {
          const page = await browser[browserType].newPage(options);
          page.addBox = addBox;
          return page;
        },
        afterScreenshot: async (page) => {
          await page.close();
        },
        customActionSchema: {
          addBox: {
            type: 'promise',
            parameters: {
              position: {
                type: 'object',
                properties: {
                  x: {
                    type: 'number',
                  },
                  y: {
                    type: 'number',
                  },
                },
                required: ['x', 'y'],
              },
            },
          },
        },
      });
    })();

    Additional Page Methods

    The following custom methods has been added to the playwright page:

    • clearInput,
    • mouseDownOnSelector
    • mouseMoveToSelector
    • setSelectorSize
    • scrollSelector
    • dragDropSelector
    • takeScreenshot
    • takeScreenshotOptions
    • selectorMouseWheel
    • mouseFromTo

    clearInput

    This method fetches an element with selector, waits for actionability checks, focuses the element, clear it and triggers an input event.

    mouseDownOnSelector

    This method fetches an element with selector, and perform mousedown on the center of selector.

    mouseMoveToSelector

    This method fetches an element with selector, and move the mouse to center of selector.

    setSelectorSize

    This method fetches an element with selector, and set the selector with or height.

    scrollSelector

    This method fetches an element with selector, and set the selector scrollLeft and scrollTop.

    dragDropSelector

    This method fetches an element with selector, and move it to the position given by user.

    takeScreenshot

    This method will take a screenshot between actions, its useful for taking a screenshot in sequence for events/actions. In the end the screenshots will be merged with the final screenshot.

    takeScreenshotOptions

    The purpose of this action is to have centralized options for all screenshots. This action can be used in conjunction with takeScreenshot action only. Only one instance can be used.

    selectorMouseWheel

    This method fetches an element with selector, and dispatch WheelEvent.

    mouseFromTo

    This method will perform mouse down, move,and up from to selected location.

    Testing

    Screenshots saved with the addon can also be tested with the test framework like jest. to do so configure the jest as follow:

    add setup file to jest.config.js

    module.exports = {
      setupFilesAfterEnv: ['./jest.setup.js'],
    };

    within jest.setup.js

    const playwright = require('playwright');
    const { setConfig } = require('storybook-addon-playwright/configs');
    const { toMatchScreenshots } = require('storybook-addon-playwright');
    
    expect.extend({ toMatchScreenshots });
    
    let browser = {};
    
    beforeAll(async () => {
      browser = {
        chromium: await playwright['chromium'].launch(),
        firefox: await playwright['firefox'].launch(),
        webkit: await playwright['webkit'].launch(),
      };
      setConfig({
        storybookEndpoint: `http://localhost:6006/`, // or  `./storybook-static`
        getPage: async (browserType, options) => {
          const page = await browser[browserType].newPage(options);
          return page;
        },
        afterScreenshot: async (page) => {
          await page.close();
        },
      });
    });
    
    afterAll(async () => {
      const promises = Object.keys(browser).map((browserType) =>
        browser[browserType].close(),
      );
      await Promise.resolve(promises);
    });

    and within the test file:

    describe('test screenshots', () => {
      it('should pass image diff', async () => {
        await expect('*').toMatchScreenshots();
      }, 10000);
    });

    Or with toMatchImageSnapshot:

    const { getScreenshots } = require('storybook-addon-playwright');
    
    describe('test screenshots manually', () => {
      it('should pass image diff', async () => {
        await getScreenshots({
          onScreenshotReady: (screenshotBuffer, baselineScreenshotPath) => {
            expect(screenshotBuffer).toMatchImageSnapshot({
              customSnapshotIdentifier: baselineScreenshotPath.screenshotIdentifier,
              customSnapshotsDir: baselineScreenshotPath.screenshotsDir,
            });
          },
        });
      }, 10000);
    });

    Make sure to set appropriate timeout for your tests.

    Typescript

    If your editor does not recognise the toMatchScreenshots matcher, add a global.d.ts file to your project with:

    import 'storybook-addon-playwright';

    Migration

    It is possible that the structure of the json file generated by addon change because of the new features, to fix and apply the changes set the enableMigration to true in setConfig and run the storybook.

    Make sure after migration set the enableMigration to false

    Adding extra selectors

    After adding an extra selector you need to run

    npx ts-node storybook-addon-playwright/src/api/server/scripts/generate-all-schema.ts

    in order for the action-schema.json to be updated. After that you need to build the project so the new selector appears at the storybook actions.

    Install

    npm i @digigov/storybook-addon-playwright

    DownloadsWeekly Downloads

    29

    Version

    4.15.1

    License

    MIT

    Unpacked Size

    2.73 MB

    Total Files

    1033

    Last publish

    Collaborators

    • digigov-bot
    • kpap
    • tsironis
    • vkefallinos.grnet
    • thanasisk00
    • gmantzios