회사를 옮기고 나서

프론트엔드개발자로서의 기본이 되야할

웹디자인에 맞춰서 페이지를 그려내는 작업을 하게됐다.

디자인에 맞춰서 css를 그리는것이 생각보다 어려울뿐만 아니라

기기종별 내장폰트유무로 달라지는 폰트차이등 신경써야할것이 생각보다 많았다.

특히 인라인요소는 사람을 미치게 한다.

완성되고나면 디자이너분이 꼼꼼하게 검수를 해주시지만.....

2603E750589594DF10 (1).jpg
(용의눈으로... 아 아닙니다..)

검수하는 시간도 꽤나 걸릴뿐만 아니라

특히 틀린그림찾기에도 미숙한 나 때문에 디자이너분의 시간이 뺏긴다는 사실에 부끄러워졌다.

게다가 검수하고 수정사항요청받을때 마다 왠지 나의 얼굴이 붉혀짐은 덤...

적어도 이 부분은 적은코드로 자동화할 수 있는 방법이 있지 않을까 싶어서 관련된 라이브러리를 찾아보았다.

그리고... 찾아냈다.

이것을 진행하려면 여러개의 라이브러리가 필요하다.

필자는 타입스크립트 러버로서 타입스크립트 기준으로 진행할것이다.

yarn add jest ts-jest typescript puppeteer jest-image-snapshot @types/jest @types/jest-image-snapshot @types/puppeteer -D
yarn tsc --init
yarn ts-jest config:init

//tsconfig.json
{
  "compilerOptions": {
    /* Basic Options */
    "target": "es6",   
    // ....
}

tsconfig의 target은 es6로 진행해야한다.

그리고 별도의 테스트폴더에서 테스트코드로 기본설정을 작성해보자

/// inspection.test.ts

import {Browser, Page, launch} from 'puppeteer';
import {toMatchImageSnapshot} from 'jest-image-snapshot';

expect.extends({toMatchImageSnapshot});

describe('some page',() => {
  let browser: Browser;
  let page: Page;
  beforeAll(async done => {
    browser = await launch();
    done();
  });
  beforeEach(async done => {
    page = await browser.newPage();
    done();
  });
  afterEach(async done => {
    await page.close();
    done();
  });
  afterAll(async done => {
    await browser.close();
    browser = null;
    done();
  });
});

beforeAll,afterAll에는 자신의 사이트를 열고 닫는 코드가 있어야한다.
하지만 일단 간단하게 코드만 보여주기 위해 사이트는 구글로 진행하겠다.
사이트를 검수한다고 가정해보고 구글의 스크린샷을 찍어보자.

/// inspection.test.ts

import {Browser, Page, launch} from 'puppeteer';


describe('some page',() => {
  // 생략

  it("main", async () => {
    await page.goto("https://www.google.com");
    const png = await page.screenshot();
    expect(png).toMatchImageSnapshot();
  });
});

자 테스트 실행!

yarn jest

짜잔!

테스트파일이 있는 폴더에 image_snapshots폴더가 생기고 결과물이 저장된다.
inspection-test-ts-some-page-main-1-snap.png

이것을 디자인시안파일이라고 가정하고 진행하자.
실제로는 디자인시안이미지를 이 이미지파일이름으로 바꾸고 교체하면된다.

하지만 같은페이지를 계속찍어봐야 우리가 원하는 검수비교가 된건지 알수가 없기에 행동을 추가해보자

//생략
describe('some page',() => {
  // 생략
  it("main", async () => {
    await page.goto("https://www.google.com");
    await page.type("input[type='text']", "test"); // 추가작성할 부분!
    const png = await page.screenshot();
    expect(png).toMatchImageSnapshot();
  });
});

다시 테스트 진행!
테스트실패.PNG

당연히 실패가 뜬다.

친절하게 몇퍼센트나 차이나는지 몇픽셀이나 다른지도 결과에 출력이 된다.

시각적 결과물은 image_snapshots폴더에 diff_output폴더에 저장된다.

inspection-test-ts-some-page-main-1-diff.png

기존이미지, 차이점, 새로찍은이미지순으로 이미지가 한이미지내에서 나열된다.

어떤가? 아름답지않은가?

여기서 좀더 코드를 추가하자면 기본적으로 디자인 크기에 맞춰서 브라우저의 viewport조정을 하면된다.

이전까지의 검수요청 > 검수진행 > 수정사항 요청 > 수정진행 > 검수진행 > 반영 프로세스를

자동검수진행 > 수정진행 > 디자이너와의 타협(?) > 반영 프로세스로 줄일 수 있게 되었다.

PROS

  1. 미쳐 보지못한 부분까지 전부 확인이 가능하다.
  2. 1 pixel까지 다맞춘다면 쾌감을 느낄수있다.
  3. 디자이너분의 검수시간을 줄일 수 있다.

CONS

  1. 변태취급을 받을 수 있다.
  2. 반응형에는 무쓸모이다.
  3. 모르는척 넘어갈 수 없다.(?)

단점에서의 반응형에서 무쓸모라는점은 사실 업무적으로 개선되어야 할 부분이다.
전체페이지 디자인이 아닌 컴포넌트별로 디자인을 별도로 진행하고
반응형 및 유스케이스별로 디자인상황에 대해서 각각 snapshot을 찍으면 될 부분이다.

Conclusion

지금까지 jest-image-snapshot을 활용한 디자인 검수자동화를 대강 진행해보았다.
아쉽게 회사상황상 그렇게 유용하게 쓰이지는 못했지만 기획 및 디자인이 정확하게 나오는 환경이라면 꽤나 유용할듯 싶다.

링크

jest
jest-image-snapshot
puppeteer

본 포스트는 제 블로그의 포스트를 재구성한 내용입니다.