diff --git a/package.json b/package.json index 128a7d33..286a40d5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@percy/storybook", - "version": "5.0.1", + "version": "5.0.1-alpha.1", "license": "MIT", "repository": { "type": "git", @@ -8,7 +8,7 @@ }, "publishConfig": { "access": "public", - "tag": "latest" + "tag": "alpha" }, "engine": { "node": ">=14" @@ -39,7 +39,7 @@ ] }, "dependencies": { - "@percy/cli-command": "^1.24.0", + "@percy/cli-command": "^1.27.4", "cross-spawn": "^7.0.3", "qs": "^6.11.0" }, diff --git a/packageV6.json b/packageV6.json index 98be9086..45d4e763 100644 --- a/packageV6.json +++ b/packageV6.json @@ -36,7 +36,7 @@ ] }, "dependencies": { - "@percy/cli-command": "^1.24.0", + "@percy/cli-command": "^1.27.4", "cross-spawn": "^7.0.3", "qs": "^6.11.0" }, diff --git a/src/snapshots.js b/src/snapshots.js index d02fad32..35a7d0ae 100644 --- a/src/snapshots.js +++ b/src/snapshots.js @@ -213,19 +213,36 @@ export async function* takeStorybookSnapshots(percy, callback, { baseUrl, flags log.debug(`Loading story via previewResource: ${options.name}`); // when dry-running or when javascript is enabled, use the preview dom options.domSnapshot = previewResource.content; + // validate without logging to prune all other options + PercyConfig.validate(options, '/snapshot/dom'); + // snapshots are queued and do not need to be awaited on + percy.snapshot(options); } else { log.debug(`Loading story: ${options.name}`); // when not dry-running and javascript is not enabled, capture the story dom yield page.eval(evalSetCurrentStory, { id, args, globals, queryParams }); /* istanbul ignore next: tested, but coverage is stripped */ - let { dom, domSnapshot = dom } = yield page.snapshot(options); - options.domSnapshot = domSnapshot; + if (percy.config?.percy?.deferUploads) { + for (let i = 0; i < percy.config.snapshot.widths.length; i++) { + let w = percy.config.snapshot.widths[i]; + log.debug(`Capturing snapshot for width - ${w}`); + yield page.resize({ width: w, height: percy.config.snapshot.minHeight }); + let { dom, domSnapshot = dom } = yield page.snapshot(options); + options.domSnapshot = domSnapshot; + // validate without logging to prune all other options + PercyConfig.validate(options, '/snapshot/dom'); + // snapshots are queued and do not need to be awaited on + percy.snapshot({ ...options, widths: [w] }); + } + } else { + let { dom, domSnapshot = dom } = yield page.snapshot(options); + options.domSnapshot = domSnapshot; + // validate without logging to prune all other options + PercyConfig.validate(options, '/snapshot/dom'); + // snapshots are queued and do not need to be awaited on + percy.snapshot({ ...options }); + } } - - // validate without logging to prune all other options - PercyConfig.validate(options, '/snapshot/dom'); - // snapshots are queued and do not need to be awaited on - percy.snapshot(options); // discard this story snapshot when done snapshots.shift(); } diff --git a/test/storybook.test.js b/test/storybook.test.js index d652ddef..5dc779cc 100644 --- a/test/storybook.test.js +++ b/test/storybook.test.js @@ -154,6 +154,15 @@ describe('percy storybook', () => { ])} }` ].join('')]); + server.reply('/iframe.html?id=1&viewMode=story', () => [200, 'text/html', [ + ``, + `` + ].join('')]); + await expectAsync(storybook(['http://localhost:8000'])) // message contains the client stack trace .toBeRejectedWithError(/^Story Error\n.*\/iframe\.html.*$/s); @@ -184,6 +193,15 @@ describe('percy storybook', () => { ])} }` ].join('')]); + server.reply('/iframe.html?id=1&viewMode=story', () => [200, 'text/html', [ + ``, + `` + ].join('')]); + // does not reject await storybook(['http://localhost:8000']); @@ -215,6 +233,7 @@ describe('percy storybook', () => { // respond with the preview dom only for the first request server.reply('/iframe.html', () => [200, 'text/html', i++ ? storyDOM : previewDOM]); + server.reply('/iframe.html?id=1&viewMode=story', () => [200, 'text/html', i++ ? storyDOM : previewDOM]); // eslint-disable-next-line import/no-extraneous-dependencies let { Percy } = await import('@percy/core'); @@ -497,6 +516,29 @@ describe('percy storybook', () => { ])); }); + it('takes multiple snapshots with defer-uploads and multiple widths', async () => { + fs.writeFileSync('.percy.yml', [ + 'version: 2', + 'percy:', + ' defer-uploads: true', + 'snapshot:', + ' widths:', + ' - 1000', + ' - 500' + ].join('\n')); + + await storybook(['http://localhost:9000', '--verbose']); + + expect(logger.stderr).toEqual(jasmine.arrayContaining([ + '[percy:storybook] Capturing snapshot for width - 1000', + '[percy:storybook] Capturing snapshot for width - 500' + ])); + expect(logger.stdout).toEqual(jasmine.arrayContaining([ + '[percy:core] Snapshot uploaded: Snapshot: First', + '[percy:core] Snapshot uploaded: Snapshot: Second', + '[percy:core] Snapshot uploaded: Skip: But Not Me' + ])); + }); describe('with protected urls', () => { beforeAll(() => { let auth = [ @@ -521,6 +563,17 @@ describe('percy storybook', () => { `` ].join('')]; }); + + server.reply('/iframe.html?id=test--test&viewMode=story', req => { + if (!auth.includes(req.headers.authorization)) { + return [403, 'text/plain', 'Invalid auth']; + } + + return [200, 'text/html', [ + ``, + `` + ].join('')]; + }); }); it('takes snapshots with discovery auth username & password', async () => { diff --git a/yarn.lock b/yarn.lock index bf74f080..2e2e2200 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1485,42 +1485,43 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@percy/cli-command@^1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/cli-command/-/cli-command-1.24.0.tgz" - integrity sha512-n4qyDdUc+TiX/YykGg59IS1DBmm4UdA7ZaiTdw/D5AZohzwwVbwL+Q4QMYqcohtfYZ/F8UT7Qy3Jma3+YKTnxw== +"@percy/cli-command@^1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/cli-command/-/cli-command-1.27.4.tgz#c3537260909957b165b81766e6d1771dc2496942" + integrity sha512-YDKeeOr1MvksDOnc2ZKQ/XuERGrWwzuT/vWZ9it8L+0SyPj28UbklDu0e9zBgPsSDfxJlIvsWXRuHNGHsweKXg== dependencies: - "@percy/config" "1.24.0" - "@percy/core" "1.24.0" - "@percy/logger" "1.24.0" + "@percy/config" "1.27.4" + "@percy/core" "1.27.4" + "@percy/logger" "1.27.4" -"@percy/client@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/client/-/client-1.24.0.tgz" - integrity sha512-mCMIGryE+0oxJN6v+riZ+XqnubEL9rajLOJI7xNOj5gNBNNvwgvkpTiNId9d6LNZVhA7dN9ZHTW+zFK+i4nU8A== +"@percy/client@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/client/-/client-1.27.4.tgz#a6901e93e56245170e23b24bdf906fdfdb066956" + integrity sha512-1F8ulTJhfk4/Lgj1Cn0blaRd8vTRJDxahAGseTbfrnZ2PHsftPZ65/5nCHPtpdD/2CE8N5COBQscGTMQQO+hBA== dependencies: - "@percy/env" "1.24.0" - "@percy/logger" "1.24.0" + "@percy/env" "1.27.4" + "@percy/logger" "1.27.4" -"@percy/config@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/config/-/config-1.24.0.tgz" - integrity sha512-FOV8VkW/MjLI7PXzKSjxFBK7z0ND1s8LtXuLQNIrux3oiCKHIVBAQWIV86LLnXSSn+G5i3tfQua9YED5ATyNFQ== +"@percy/config@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/config/-/config-1.27.4.tgz#83bde546be17c801305e63b0cf84ed04fe748fba" + integrity sha512-mlgiOdzdSfUSx9FskVIjmbT/iHbTif0Ow5evZQJTT1W0xgHOBWDCZyhINdsqulSBw+K1PNhHsu1J0h2ijxF4uA== dependencies: - "@percy/logger" "1.24.0" + "@percy/logger" "1.27.4" ajv "^8.6.2" - cosmiconfig "^7.0.0" + cosmiconfig "^8.0.0" yaml "^2.0.0" -"@percy/core@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/core/-/core-1.24.0.tgz" - integrity sha512-wys1k3RmENOWT4MeS2+8yGHNqzYuy64lqPi36dFoHwZHzSGHH52+6EPPDb+gXLFIxBUHVTwbdaNimstIO3F9Ww== +"@percy/core@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/core/-/core-1.27.4.tgz#673ea19be0b9e435e3ec2419505e9d9adbab5d6e" + integrity sha512-WdsA4zlPgXl9xj+a5WW2wA20iU6VTDmRq5sgsYNSuPzZfQB2I5Cecgvb55p86dhlUTbPJrC76daQKzDTGe0hfA== dependencies: - "@percy/client" "1.24.0" - "@percy/config" "1.24.0" - "@percy/dom" "1.24.0" - "@percy/logger" "1.24.0" + "@percy/client" "1.27.4" + "@percy/config" "1.27.4" + "@percy/dom" "1.27.4" + "@percy/logger" "1.27.4" + "@percy/webdriver-utils" "1.27.4" content-disposition "^0.5.4" cross-spawn "^7.0.3" extract-zip "^2.0.1" @@ -1531,20 +1532,35 @@ rimraf "^3.0.2" ws "^8.0.0" -"@percy/dom@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/dom/-/dom-1.24.0.tgz" - integrity sha512-URMLvsOPkCKayx/Wtyj5IymmIhzrtf4en6IKeW2sSTsm7X+kJQ+3wOa3017mX3HXJPIS5xEJKpiCR7hP9BtcUA== +"@percy/dom@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/dom/-/dom-1.27.4.tgz#199597ca6107c16ca452a640e9d1bfe2f65f6820" + integrity sha512-pwPDx3e9y7uRobVlEya8xu3BB3GeXbC74kQ6pPM/wFYDwi/Dg8DJywCsj5Nko/7QuhXP02rYgatkbREOIRxDnA== -"@percy/env@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/env/-/env-1.24.0.tgz" - integrity sha512-fUUWWDZJ71kv+Po5yOaoS8t7eLmQL5NN6hqRdLhgqN9PZnu+OKIGaeK1GNaTWiHL9+zANRBc1pZjQWhRlleWVA== +"@percy/env@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/env/-/env-1.27.4.tgz#8c308c470dae5fb970d858703e1f49aff266e791" + integrity sha512-Xl2VUpljOrlCvAp/+KfmN9NUcTGpRdXPa1U9zSIyBnV/oAksp3/CK5EPpKZX/f8xUUkTp78UPaG99sEMA8VvXQ== + dependencies: + "@percy/logger" "1.27.4" + +"@percy/logger@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/logger/-/logger-1.27.4.tgz#8d493299e219d971a92052b5998177697191dd05" + integrity sha512-AwXqYaDkHaq1TPkP+ByB8rjvH9ddvkAH9tFd2kmq8AeFFXZ0amAPSbm6u090OUtdHWjRmKQK9JjSouBxEh0aRw== -"@percy/logger@1.24.0": - version "1.24.0" - resolved "https://registry.npmjs.org/@percy/logger/-/logger-1.24.0.tgz" - integrity sha512-yaAo08FMED1o8jZycTEnTob1CZIVGaNluJc4R9fCRw7wWS88IAu4F9sdbzUZQZwZ/QGvtfI+55dNQaaesk69Bw== +"@percy/sdk-utils@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/sdk-utils/-/sdk-utils-1.27.4.tgz#7396d743aa6916ae7fad639b0fa86f206a9b2aca" + integrity sha512-vhPcdtmJlvTYJ5VOqiVzo02ujdtBFNw1/Bj+2ybiZgn7PkCDPFcITfXoWWPea319EIibGC4ZHjWHctRBgtW/tQ== + +"@percy/webdriver-utils@1.27.4": + version "1.27.4" + resolved "https://registry.yarnpkg.com/@percy/webdriver-utils/-/webdriver-utils-1.27.4.tgz#35ce3054bcd0a0f21262ab885ee33a51d0df6f0e" + integrity sha512-pZOOYns8Fikh2qlbxO16DxFEnCrnFIoLpE7iz4M9jXxOfk16VZF1PWknMChSr5NqG2I9k2OMjizUE2j8zvtl2Q== + dependencies: + "@percy/config" "1.27.4" + "@percy/sdk-utils" "1.27.4" "@pkgjs/parseargs@^0.11.0": version "0.11.0" @@ -3358,7 +3374,7 @@ core-util-is@~1.0.0: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: +cosmiconfig@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== @@ -3369,6 +3385,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.0.0: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + cross-env@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" @@ -4923,9 +4949,9 @@ ignore@^5.1.1, ignore@^5.2.0: resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -import-fresh@^3.2.1: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -6189,9 +6215,9 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0"