From 29f4c6544b06070afaf6506e6532674148a1bce8 Mon Sep 17 00:00:00 2001 From: Vladimir Klepov Date: Tue, 1 Dec 2020 13:29:53 +0300 Subject: [PATCH] TEST: Avoid github caching diff images - append hash --- dangerfile.js | 26 +++++++++++--- package.json | 1 + src/components/Button/Button.e2e.tsx | 1 + .../button-android-bright_light-1-snap.png | 4 +-- .../button-android-space_gray-1-snap.png | 4 +-- .../button-ios-bright_light-1-snap.png | 4 +-- .../button-ios-space_gray-1-snap.png | 4 +-- src/testing/e2e/utils.tsx | 36 ++++++++++++++----- yarn.lock | 21 ++++++++++- 9 files changed, 79 insertions(+), 22 deletions(-) diff --git a/dangerfile.js b/dangerfile.js index 6d5c1093595..5216881626c 100644 --- a/dangerfile.js +++ b/dangerfile.js @@ -1,6 +1,7 @@ import { fail, message, warn, danger, markdown } from 'danger'; const dangerJest = require('danger-plugin-jest').default; const { readFile } = require('fs').promises; +const md5 = require('md5'); const path = require('path'); const glob = require('glob'); const { promisify } = require('util') @@ -47,13 +48,15 @@ const s3 = new AWS.S3({ async function uploadFailedScreenshots() { const diffDir = '__diff_output__' const { github } = danger; - const pathPrefix = github ? github.pr.number : 'local'; + const pathPrefix = github ? String(github.pr.number) : 'local'; + await removeDiffs(`${pathPrefix}/`); for (const failedScreen of await pglob(path.join(__dirname, '**', diffDir, '*.png'))) { - const screenName = path.parse(failedScreen).base; - const key = [pathPrefix, screenName].join('/'); + const screenName = path.parse(failedScreen).name; + const fileContents = await readFile(failedScreen); + const key = `${pathPrefix}/${screenName}-${md5(fileContents)}.png`; try { await s3.putObject({ - Body: await readFile(failedScreen), + Body: fileContents, Bucket: UPLOAD_BUCKET, Key: key, ContentType: 'image/png', @@ -71,6 +74,21 @@ async function uploadFailedScreenshots() { } } +async function removeDiffs(prefix) { + const list = (await s3.listObjects({ + Bucket: UPLOAD_BUCKET, + Prefix: prefix, + }).promise()).Contents; + if (list && list.length !== 0) { + await s3.deleteObjects({ + Bucket: UPLOAD_BUCKET, + Delete: { + Objects: list.map(obj => ({ Key: obj.Key })), + }, + }).promise(); + } +} + Promise.all([ dangerJest(), lint(), diff --git a/package.json b/package.json index 498491f9d3e..21fe6a1740b 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "jest-image-snapshot": "^4.2.0", "jest-playwright-preset": "^1.4.1", "jest-silent-reporter": "^0.3.0", + "md5": "^2.3.0", "mini-css-extract-plugin": "^1.3.1", "playwright": "^1.6.2", "postcss": "8.1.4", diff --git a/src/components/Button/Button.e2e.tsx b/src/components/Button/Button.e2e.tsx index 1f09cdc879c..31cb309d97e 100644 --- a/src/components/Button/Button.e2e.tsx +++ b/src/components/Button/Button.e2e.tsx @@ -11,5 +11,6 @@ describe('Button', () => { disabled: [undefined, true], }, { size: ['s', 'm', 'l'], + $adaptivity: 'y', }]); }); diff --git a/src/components/Button/__image_snapshots__/button-android-bright_light-1-snap.png b/src/components/Button/__image_snapshots__/button-android-bright_light-1-snap.png index 7d39ddcb388..75ad8d1e22e 100644 --- a/src/components/Button/__image_snapshots__/button-android-bright_light-1-snap.png +++ b/src/components/Button/__image_snapshots__/button-android-bright_light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c93e8ac91e4626cd70a4f90c71a95402609c25a0b95ef45f72bd25ff330e57c -size 62502 +oid sha256:6de789edce86e276e3ab87a1734fa92f6bab564f19aeb9a3773f560392fa304a +size 75941 diff --git a/src/components/Button/__image_snapshots__/button-android-space_gray-1-snap.png b/src/components/Button/__image_snapshots__/button-android-space_gray-1-snap.png index d947dbee159..459caf52377 100644 --- a/src/components/Button/__image_snapshots__/button-android-space_gray-1-snap.png +++ b/src/components/Button/__image_snapshots__/button-android-space_gray-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5bb817827f173e29b9f9b3daadf60f000dcd237eaebf165d56187dd7ee4663a8 -size 70416 +oid sha256:7bce2c1c043d58c8ab7ea9bd741a403f25c6f8924577fcd3f65fd19fb879dbcc +size 84125 diff --git a/src/components/Button/__image_snapshots__/button-ios-bright_light-1-snap.png b/src/components/Button/__image_snapshots__/button-ios-bright_light-1-snap.png index 3fca6467b30..dbcc86fafc5 100644 --- a/src/components/Button/__image_snapshots__/button-ios-bright_light-1-snap.png +++ b/src/components/Button/__image_snapshots__/button-ios-bright_light-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54be1d2e45849b9d6908dbe84819903d0094cc3cbb630e7a7030cc251ef98fce -size 63421 +oid sha256:e67a01450a58bc33f2938dc12b7e16c688f5ad6907892b63cb94265778ae31e0 +size 77137 diff --git a/src/components/Button/__image_snapshots__/button-ios-space_gray-1-snap.png b/src/components/Button/__image_snapshots__/button-ios-space_gray-1-snap.png index 494931a6883..78a5f7cf244 100644 --- a/src/components/Button/__image_snapshots__/button-ios-space_gray-1-snap.png +++ b/src/components/Button/__image_snapshots__/button-ios-space_gray-1-snap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0419a5ce88cd704f2ac7174314c26d646346a6a6719b5cc1718f183098a55e95 -size 71695 +oid sha256:9bce185c18b4e328e45e77091e1fbe436a441a555f4dfbe93ec9ad550f19350b +size 85734 diff --git a/src/testing/e2e/utils.tsx b/src/testing/e2e/utils.tsx index e182767f13a..28e2880620b 100644 --- a/src/testing/e2e/utils.tsx +++ b/src/testing/e2e/utils.tsx @@ -5,11 +5,28 @@ import ConfigProvider from '../../components/ConfigProvider/ConfigProvider'; import Panel from '../../components/Panel/Panel'; import { Platform } from '../../lib/platform'; import { Scheme } from '../../components/ConfigProvider/ConfigProviderContext'; -import AdaptivityProvider from '../../components/AdaptivityProvider/AdaptivityProvider'; +import AdaptivityProvider, { AdaptivityProviderProps } from '../../components/AdaptivityProvider/AdaptivityProvider'; import { SizeType } from '../../components/AdaptivityProvider/AdaptivityContext'; -type PropDesc = { [K in keyof Props]?: Array }; -function cartesian(propDesc: PropDesc): Props[] { +type AdaptivityFlag = boolean | 'x' | 'y'; +type PropDesc = { [K in keyof Props]?: Array } & { $adaptivity?: AdaptivityFlag }; +type SizeProps = Pick; +type TestProps = Array; +type CartesianOptions = { adaptive: boolean }; + +function getAdaptivity(adaptivity?: AdaptivityFlag) { + const extra: PropDesc = {}; + if (adaptivity && adaptivity !== 'y') { + extra.sizeX = Object.values(SizeType); + } + if (adaptivity && adaptivity !== 'x') { + extra.sizeY = Object.values(SizeType); + } + return extra; +}; + +function cartesian({ $adaptivity, ...propDesc }: PropDesc, ops: CartesianOptions): TestProps { + propDesc = { ...propDesc, ...getAdaptivity(ops.adaptive ? $adaptivity : false) }; return Object.entries(propDesc).reduce((acc, [prop, values]: [string, any[]]) => { const res: any[] = []; acc.forEach((props) => { @@ -21,11 +38,11 @@ function cartesian(propDesc: PropDesc): Props[] { }, [{}]); } -function multiCartesian(propSets: Array>): Props[] { +function multiCartesian(propSets: Array>, ops: CartesianOptions): TestProps { if (propSets.length === 0) { return [{} as any]; } - return propSets.reduce((acc, ortho) => acc.concat(cartesian(ortho)), []); + return propSets.reduce((acc, ortho) => acc.concat(cartesian(ortho, ops)), []); } function prettyProps(props: any) { @@ -63,8 +80,9 @@ export function describeScreenshotFuzz( } = options; platforms.forEach((platform) => { describe(platform, () => { - const width = platform === 'vkcom' ? 'auto' : 320; - const ForceAdaptivity = platform === 'vkcom' ? CompactProvider : Fragment; + const isVkCom = platform === 'vkcom'; + const width = isVkCom ? 'auto' : 320; + const ForceAdaptivity = isVkCom ? CompactProvider : Fragment; schemes.forEach((scheme) => { it(scheme, async () => { expect(await screenshot(( @@ -72,10 +90,10 @@ export function describeScreenshotFuzz(
- {multiCartesian(propSets).map((props, i) => ( + {multiCartesian(propSets, { adaptive: !isVkCom }).map((props, i) => (
{prettyProps(props)}
-
+
))}
diff --git a/yarn.lock b/yarn.lock index b377a596566..f72aecf5ab8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3359,6 +3359,11 @@ chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" +charenc@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= + chokidar@^2.0.4, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -3874,6 +3879,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1: shebang-command "^2.0.0" which "^2.0.1" +crypt@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -6158,7 +6168,7 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -7640,6 +7650,15 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +md5@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" + integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== + dependencies: + charenc "0.0.2" + crypt "0.0.2" + is-buffer "~1.1.6" + mdast-util-compact@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz#d531bb7667b5123abf20859be086c4d06c894593"