fwouts / react-screenshot-test

A dead simple library to screenshot test React components
https://www.npmjs.com/package/react-screenshot-test
MIT License
618 stars 24 forks source link

Docker screenshots mismatched between local and CI #298

Closed j-lea closed 3 years ago

j-lea commented 3 years ago

Hi! I've just started using react-screenshot-test and was so impressed by how easy it was to get running and how perfect it is for my use case, thanks! However I've hit a bit of an issue with screenshots mismatching between the ones I generate locally and those taken in circleCI.

I am running both in Docker, but the screenshots taken locally are missing a border around the component, whilst the ones in CI do have the border. Giving me the following diff for exactly the same code:

Screenshot 2021-05-07 at 15 36 56

One thing to note: the border is made using the boxShadow in the second div, rather than a normal border on the first div.

This is my component:

export const Button = () => {
  return (
    <div
      style={{
        boxSizing: 'border-box',
        borderRadius: '8px',
        padding: '20px',
        position: 'absolute',
        background: 'rgb(252, 248, 236)',
        boxShadow: 'rgba(0, 0, 0, 0.25) 0px 4px 4px 0px',
      }}
    >
      <div>
        <span
          style={{
            fontFamily: 'Roboto',
          }}
        >
          What needs to be done?
        </span>
      </div>
      <div
        style={{
          position: 'absolute',
          pointerEvents: 'none',
          inset: '0px',
          borderRadius: '8px',
          boxShadow: 'rgb(0, 0, 0) 0px 0px 0px 1px inset',
        }}
      ></div>
    </div>
  )
}

This is the test (copied from the example):

  ReactScreenshotTest.create('Button with border')
    .viewport('Desktop', {
      width: 1024,
      height: 768,
    })
    .viewport('iPhone X', {
      width: 375,
      height: 812,
      deviceScaleFactor: 3,
      isMobile: true,
      hasTouch: true,
      isLandscape: false,
    })
    .shoot('Default', <Button />)
    .run()

And this is my jest config in package.json:

  "jest": {
    "verbose": true,
    "testMatch": [
      "**/?(*.)+(spec|test).tsx"
    ],
    "transform": {
      "^.+\\.[t|j]sx?$": "babel-jest",
      "^.+\\.css$": "react-screenshot-test/css-transform"
    },
    "globalSetup": "react-screenshot-test/global-setup",
    "globalTeardown": "react-screenshot-test/global-teardown"
  },

And this is my circleCI.yaml

jobs:
  test:
    executor: default
    steps:
      - start_job
      - setup_remote_docker
      - restore_cache:
          keys:
            - node-cache-v2-{{ checksum "./package-lock.json" }}
      - run:
          name: Screenshot test
          command: ./ci-screenshot.sh // This contains npm install and npm run test
      - save_cache:
          key: node-cache-v2-{{ checksum "./package-lock.json" }}
          paths:
            - /home/circleci/.npm
      - store_artifacts:
          path: ./screenshot_tests/diffs
      - finish_job

Let me know if you need any more info!

fwouts commented 3 years ago

Thank you for the detailed feedback @j-lea!

This is actually affecting tests on master as well. I suspect it's an unexpected side-effect of #296. The trick should be to make sure the Docker image running on CircleCI has the same dependencies as the one used when running tests on your machine. I'm looking into it :)

fwouts commented 3 years ago

In the meantime, try reverting to v2.2.3?

fwouts commented 3 years ago

@j-lea I've just released v2.3.1, which should hopefully solve the issue. You'll probably also need to use the right Docker image on CircleCI, see https://github.com/fwouts/react-screenshot-test/blob/master/.circleci/config.yml for reference. Let me know how you go!

j-lea commented 3 years ago

Amazing! Upgrading to 2.3.1 seemed to sort it out :) Thank you so much @fwouts!

fwouts commented 3 years ago

Perfect. Feel free to file more issues with bugs and/or feedback as you use the library more. I'm especially curious to hear whether the limitation of only having server-side rendering becomes an issue for you (I'm considering building a more powerful version that does support client-side, but it's quite a bit more complex so I'm not sure yet whether I'd be offering it for free).