diff --git a/.circleci/config.yml b/.circleci/config.yml index 9aa8c392ca..b024c82e3f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,10 +22,10 @@ references: ignore: gh-pages - dist: requires: - - setup + - setup - compile: requires: - - setup + - setup - lint: requires: - setup @@ -166,7 +166,7 @@ workflows: <<: *workflow triggers: - schedule: - cron: "0 0 * * *" + cron: '0 0 * * *' filters: branches: only: diff --git a/.github/workflows/ui-ci.yml b/.github/workflows/ui-ci.yml new file mode 100644 index 0000000000..4d0ecb7cc9 --- /dev/null +++ b/.github/workflows/ui-ci.yml @@ -0,0 +1,31 @@ +name: UI-TEST + +on: + issue_comment: + types: [created] + +jobs: + ui: + runs-on: ubuntu-latest + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/ui') + steps: + - name: checkout + uses: actions/checkout@master + + - name: install + run: npm ci + + - name: dist + run: npm run dist + + - name: test + run: npm run test:image + + - name: VERCEL Now Deployment + uses: amondnet/now-deployment@v2.0.3 + with: + zeit-token: ${{ secrets.VERCEL_TOKEN }} + now-project-id: ${{ secrets.VERCEL_PROJECT_ID}} + now-org-id: ${{ secrets.VERCEL_ORG_ID}} + working-directory: ./jest-stare + if: failure() diff --git a/.gitignore b/.gitignore index bb8d5b7e86..f59fe24f3b 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,7 @@ site/theme/template/Resources/**/*.jsx site/theme/template/NotFound.jsx scripts/previewEditor/index.html components/version/version.tsx + +# Image snapshot diff +__diff_output__/ +/jest-stare diff --git a/.jest.image.js b/.jest.image.js new file mode 100644 index 0000000000..9d5b93df08 --- /dev/null +++ b/.jest.image.js @@ -0,0 +1,24 @@ +const { moduleNameMapper, transformIgnorePatterns } = require('./.jest'); + +// jest config for image snapshots +module.exports = { + setupFiles: ['./tests/setup.js'], + moduleFileExtensions: ['ts', 'tsx', 'js', 'md'], + moduleNameMapper, + transform: { + '\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor', + '\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor', + '\\.md$': './node_modules/@ant-design/tools/lib/jest/demoPreprocessor', + '\\.(jpg|png|gif|svg)$': './node_modules/@ant-design/tools/lib/jest/imagePreprocessor', + }, + testRegex: 'image\\.test\\.js$', + testEnvironment: 'node', + transformIgnorePatterns, + snapshotSerializers: ['enzyme-to-json/serializer'], + globals: { + 'ts-jest': { + tsConfigFile: './tsconfig.test.json', + }, + }, + reporters: ['default', 'jest-stare'], +}; diff --git a/.jest.js b/.jest.js index afcd51ffab..6f712cdf65 100644 --- a/.jest.js +++ b/.jest.js @@ -26,7 +26,7 @@ module.exports = { '^react-dnd-test-backend$': 'react-dnd-test-backend/dist/cjs', '^react-dnd-test-utils$': 'react-dnd-test-utils/dist/cjs', }, - testPathIgnorePatterns: ['/node_modules/', 'dekko', 'node'], + testPathIgnorePatterns: ['/node_modules/', 'dekko', 'node', 'image.test.js'], transform: { '\\.tsx?$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor', '\\.js$': './node_modules/@ant-design/tools/lib/jest/codePreprocessor', diff --git a/components/grid/__tests__/__image_snapshots__/image-test-js-grid-image-image-test-component-image-screenshot-should-correct-1-snap.png b/components/grid/__tests__/__image_snapshots__/image-test-js-grid-image-image-test-component-image-screenshot-should-correct-1-snap.png new file mode 100644 index 0000000000..65341e5d00 Binary files /dev/null and b/components/grid/__tests__/__image_snapshots__/image-test-js-grid-image-image-test-component-image-screenshot-should-correct-1-snap.png differ diff --git a/components/grid/__tests__/image.test.js b/components/grid/__tests__/image.test.js new file mode 100644 index 0000000000..4c308e158c --- /dev/null +++ b/components/grid/__tests__/image.test.js @@ -0,0 +1,37 @@ +import React from 'react'; +import { Col, Row } from '..'; +import imageTest from '../../../tests/shared/imageTest'; + +describe('Grid image', () => { + imageTest( + <> + + col + + + col + col + col + col + + + col + + + col-12 + col-12 + + + col-8 + col-8 + col-8 + + + col-6 + col-6 + col-6 + col-6 + + , + ); +}); diff --git a/package.json b/package.json index abba3a2244..c8b50cb2eb 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "test-node": "jest --config .jest.node.js --no-cache", "tsc": "tsc", "site:test": "jest --config .jest.site.js --cache=false", + "test:image": "npm install puppeteer@2.1.1 --no-save && jest --config .jest.image.js --no-cache", "version": "node ./scripts/generate-version" }, "husky": { @@ -159,8 +160,10 @@ "@types/enzyme": "^3.10.5", "@types/gtag.js": "^0.0.3", "@types/jest": "^25.1.0", + "@types/jest-image-snapshot": "^2.12.0", "@types/lodash": "^4.14.139", "@types/prop-types": "^15.7.1", + "@types/puppeteer": "^2.0.1", "@types/raf": "^3.4.0", "@types/react": "^16.9.21", "@types/react-color": "^3.0.1", @@ -213,6 +216,8 @@ "inquirer": "^7.1.0", "intersection-observer": "^0.10.0", "jest": "^26.0.0", + "jest-image-snapshot": "^3.1.0", + "jest-stare": "^2.0.1", "jquery": "^3.4.1", "jsdom": "^16.0.0", "jsonml.js": "^0.1.0", diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 0000000000..c4f924ec86 --- /dev/null +++ b/tests/index.html @@ -0,0 +1,12 @@ + + + + + + Amazing Antd + + + +
+ + diff --git a/tests/shared/imageTest.ts b/tests/shared/imageTest.ts new file mode 100644 index 0000000000..b9b3df77c0 --- /dev/null +++ b/tests/shared/imageTest.ts @@ -0,0 +1,38 @@ +import React from 'react'; +// Reference: https://github.com/ant-design/ant-design/pull/24003#discussion_r427267386 +// eslint-disable-next-line import/no-unresolved +import puppeteer, { Browser, Page } from 'puppeteer'; +import { toMatchImageSnapshot } from 'jest-image-snapshot'; +import ReactDOMServer from 'react-dom/server'; + +expect.extend({ toMatchImageSnapshot }); + +// eslint-disable-next-line jest/no-export +export default function imageTest(component: React.ReactElement) { + describe(`Image test`, () => { + let browser: Browser; + let page: Page; + + beforeAll(async () => { + browser = await puppeteer.launch(); + page = await browser.newPage(); + await page.goto(`file://${process.cwd()}/tests/index.html`); + await page.addStyleTag({ path: `${process.cwd()}/dist/antd.css` }); + }); + + afterAll(() => { + browser.close(); + }); + + it('component image screenshot should correct', async () => { + const html = ReactDOMServer.renderToString(component); + await page.evaluate(innerHTML => { + document.querySelector('#root')!.innerHTML = innerHTML; + }, html); + + const image = await page.screenshot(); + + expect(image).toMatchImageSnapshot(); + }); + }); +}