creevey 0.10.0-beta.4 → 0.10.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -41
- package/dist/client/addon/components/Addon.js +17 -7
- package/dist/client/addon/components/Addon.js.map +1 -1
- package/dist/client/addon/components/Panel.js +2 -2
- package/dist/client/addon/components/Panel.js.map +1 -1
- package/dist/client/addon/components/Tools.js +17 -7
- package/dist/client/addon/components/Tools.js.map +1 -1
- package/dist/client/addon/withCreevey.d.ts +2 -1
- package/dist/client/addon/withCreevey.js +11 -1
- package/dist/client/addon/withCreevey.js.map +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.d.ts +1 -1
- package/dist/client/shared/components/ImagesView/BlendView.js +17 -7
- package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +1 -1
- package/dist/client/shared/components/ImagesView/SideBySideView.js +17 -7
- package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SlideView.d.ts +1 -1
- package/dist/client/shared/components/ImagesView/SlideView.js +17 -7
- package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
- package/dist/client/shared/components/ImagesView/SwapView.d.ts +1 -1
- package/dist/client/shared/components/ImagesView/SwapView.js +29 -7
- package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.d.ts +1 -1
- package/dist/client/shared/components/PageHeader/ImagePreview.js +1 -0
- package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
- package/dist/client/shared/components/PageHeader/PageHeader.js +20 -8
- package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
- package/dist/client/shared/components/ResultsPage.d.ts +1 -1
- package/dist/client/shared/components/ResultsPage.js +43 -13
- package/dist/client/shared/components/ResultsPage.js.map +1 -1
- package/dist/client/shared/creeveyClientApi.js +8 -1
- package/dist/client/shared/creeveyClientApi.js.map +1 -1
- package/dist/client/shared/helpers.d.ts +1 -3
- package/dist/client/shared/helpers.js +4 -19
- package/dist/client/shared/helpers.js.map +1 -1
- package/dist/client/web/CreeveyApp.js +42 -14
- package/dist/client/web/CreeveyApp.js.map +1 -1
- package/dist/client/web/CreeveyContext.d.ts +5 -0
- package/dist/client/web/CreeveyContext.js +20 -7
- package/dist/client/web/CreeveyContext.js.map +1 -1
- package/dist/client/web/CreeveyLoader.js +2 -2
- package/dist/client/web/CreeveyLoader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/Search.js +19 -9
- package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBar.js +18 -7
- package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +60 -7
- package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +17 -7
- package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +2 -2
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +18 -10
- package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestLink.js +18 -10
- package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.d.ts +1 -1
- package/dist/client/web/CreeveyView/SideBar/TestsStatus.d.ts +1 -1
- package/dist/client/web/KeyboardEventsContext.d.ts +1 -8
- package/dist/client/web/KeyboardEventsContext.js +79 -64
- package/dist/client/web/KeyboardEventsContext.js.map +1 -1
- package/dist/client/web/assets/index-C47njyZV.js +802 -0
- package/dist/client/web/index.html +1 -1
- package/dist/client/web/index.js +17 -7
- package/dist/client/web/index.js.map +1 -1
- package/dist/client/web/themes.d.ts +2 -0
- package/dist/client/web/themes.js +22 -0
- package/dist/client/web/themes.js.map +1 -0
- package/dist/creevey.js +16 -9
- package/dist/creevey.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/server/config.d.ts +1 -1
- package/dist/server/config.js +30 -7
- package/dist/server/config.js.map +1 -1
- package/dist/server/connection.d.ts +3 -0
- package/dist/server/connection.js +28 -0
- package/dist/server/connection.js.map +1 -0
- package/dist/server/docker.d.ts +1 -1
- package/dist/server/docker.js +56 -32
- package/dist/server/docker.js.map +1 -1
- package/dist/server/index.js +64 -11
- package/dist/server/index.js.map +1 -1
- package/dist/server/logger.d.ts +2 -1
- package/dist/server/logger.js +7 -3
- package/dist/server/logger.js.map +1 -1
- package/dist/server/master/api.js +1 -1
- package/dist/server/master/api.js.map +1 -1
- package/dist/server/master/pool.d.ts +4 -3
- package/dist/server/master/pool.js +13 -66
- package/dist/server/master/pool.js.map +1 -1
- package/dist/server/master/queue.d.ts +13 -0
- package/dist/server/master/queue.js +71 -0
- package/dist/server/master/queue.js.map +1 -0
- package/dist/server/master/runner.d.ts +3 -0
- package/dist/server/master/runner.js +78 -10
- package/dist/server/master/runner.js.map +1 -1
- package/dist/server/master/server.js +1 -1
- package/dist/server/master/server.js.map +1 -1
- package/dist/server/master/start.js +13 -11
- package/dist/server/master/start.js.map +1 -1
- package/dist/server/playwright/docker-file.d.ts +1 -1
- package/dist/server/playwright/docker-file.js +15 -6
- package/dist/server/playwright/docker-file.js.map +1 -1
- package/dist/server/playwright/docker.d.ts +2 -1
- package/dist/server/playwright/docker.js +10 -2
- package/dist/server/playwright/docker.js.map +1 -1
- package/dist/server/playwright/index-source.mjs +16 -0
- package/dist/server/playwright/internal.d.ts +6 -6
- package/dist/server/playwright/internal.js +143 -91
- package/dist/server/playwright/internal.js.map +1 -1
- package/dist/server/playwright/webdriver.d.ts +1 -1
- package/dist/server/playwright/webdriver.js +5 -8
- package/dist/server/playwright/webdriver.js.map +1 -1
- package/dist/server/providers/browser.js +6 -4
- package/dist/server/providers/browser.js.map +1 -1
- package/dist/server/providers/hybrid.js +1 -1
- package/dist/server/providers/hybrid.js.map +1 -1
- package/dist/server/reporters/creevey.d.ts +7 -0
- package/dist/server/reporters/creevey.js +63 -0
- package/dist/server/reporters/creevey.js.map +1 -0
- package/dist/server/reporters/index.d.ts +2 -0
- package/dist/server/reporters/index.js +16 -0
- package/dist/server/reporters/index.js.map +1 -0
- package/dist/server/reporters/junit.d.ts +16 -0
- package/dist/server/reporters/junit.js +165 -0
- package/dist/server/reporters/junit.js.map +1 -0
- package/dist/server/reporters/teamcity.d.ts +7 -0
- package/dist/server/reporters/teamcity.js +60 -0
- package/dist/server/reporters/teamcity.js.map +1 -0
- package/dist/server/selenium/internal.d.ts +3 -4
- package/dist/server/selenium/internal.js +127 -108
- package/dist/server/selenium/internal.js.map +1 -1
- package/dist/server/selenium/selenoid.js +8 -6
- package/dist/server/selenium/selenoid.js.map +1 -1
- package/dist/server/selenium/webdriver.d.ts +1 -1
- package/dist/server/selenium/webdriver.js +5 -9
- package/dist/server/selenium/webdriver.js.map +1 -1
- package/dist/server/telemetry.js +2 -2
- package/dist/server/testsFiles/parser.js +45 -5
- package/dist/server/testsFiles/parser.js.map +1 -1
- package/dist/server/utils.d.ts +19 -1
- package/dist/server/utils.js +87 -8
- package/dist/server/utils.js.map +1 -1
- package/dist/server/webdriver.d.ts +5 -4
- package/dist/server/webdriver.js +23 -10
- package/dist/server/webdriver.js.map +1 -1
- package/dist/server/worker/chai-image.d.ts +1 -2
- package/dist/server/worker/chai-image.js +4 -3
- package/dist/server/worker/chai-image.js.map +1 -1
- package/dist/server/worker/context.d.ts +3 -0
- package/dist/server/worker/context.js +15 -0
- package/dist/server/worker/context.js.map +1 -0
- package/dist/server/worker/match-image.d.ts +4 -4
- package/dist/server/worker/match-image.js +7 -4
- package/dist/server/worker/match-image.js.map +1 -1
- package/dist/server/worker/start.js +47 -73
- package/dist/server/worker/start.js.map +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/types.d.ts +46 -10
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/docs/cli.md +12 -0
- package/docs/config.md +179 -165
- package/docs/storybook.md +60 -0
- package/docs/tests.md +50 -45
- package/package.json +64 -63
- package/src/client/addon/components/Panel.tsx +2 -2
- package/src/client/addon/withCreevey.ts +10 -2
- package/src/client/shared/components/ImagesView/SwapView.tsx +18 -0
- package/src/client/shared/components/PageHeader/ImagePreview.tsx +1 -0
- package/src/client/shared/components/PageHeader/PageHeader.tsx +4 -2
- package/src/client/shared/components/ResultsPage.tsx +31 -8
- package/src/client/shared/creeveyClientApi.ts +9 -1
- package/src/client/shared/helpers.ts +4 -24
- package/src/client/web/CreeveyApp.tsx +27 -8
- package/src/client/web/CreeveyContext.tsx +9 -0
- package/src/client/web/CreeveyLoader.tsx +1 -1
- package/src/client/web/CreeveyView/SideBar/Search.tsx +3 -3
- package/src/client/web/CreeveyView/SideBar/SideBar.tsx +1 -0
- package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +37 -6
- package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +3 -5
- package/src/client/web/CreeveyView/SideBar/TestLink.tsx +2 -4
- package/src/client/web/KeyboardEventsContext.tsx +61 -73
- package/src/client/web/themes.ts +24 -0
- package/src/creevey.ts +16 -10
- package/src/server/config.ts +30 -7
- package/src/server/connection.ts +26 -0
- package/src/server/docker.ts +63 -34
- package/src/server/index.ts +72 -14
- package/src/server/logger.ts +6 -2
- package/src/server/master/api.ts +1 -1
- package/src/server/master/pool.ts +23 -59
- package/src/server/master/queue.ts +77 -0
- package/src/server/master/runner.ts +96 -10
- package/src/server/master/server.ts +1 -1
- package/src/server/master/start.ts +16 -11
- package/src/server/playwright/docker-file.ts +18 -6
- package/src/server/playwright/docker.ts +16 -3
- package/src/server/playwright/index-source.mjs +16 -0
- package/src/server/playwright/internal.ts +182 -111
- package/src/server/playwright/webdriver.ts +6 -9
- package/src/server/providers/browser.ts +6 -4
- package/src/server/providers/hybrid.ts +1 -1
- package/src/server/reporters/creevey.ts +71 -0
- package/src/server/reporters/index.ts +11 -0
- package/src/server/reporters/junit.ts +205 -0
- package/src/server/reporters/teamcity.ts +74 -0
- package/src/server/selenium/internal.ts +131 -116
- package/src/server/selenium/selenoid.ts +8 -6
- package/src/server/selenium/webdriver.ts +6 -10
- package/src/server/telemetry.ts +2 -2
- package/src/server/testsFiles/parser.ts +52 -4
- package/src/server/utils.ts +97 -9
- package/src/server/webdriver.ts +24 -16
- package/src/server/worker/chai-image.ts +4 -4
- package/src/server/worker/context.ts +14 -0
- package/src/server/worker/match-image.ts +12 -8
- package/src/server/worker/start.ts +51 -86
- package/src/shared/index.ts +1 -1
- package/src/types.ts +50 -11
- package/types/global.d.ts +1 -0
- package/.yarnrc.yml +0 -1
- package/chromatic.config.json +0 -5
- package/dist/client/web/assets/index-DkmZfG9C.js +0 -591
- package/dist/server/reporter.d.ts +0 -26
- package/dist/server/reporter.js +0 -108
- package/dist/server/reporter.js.map +0 -1
- package/src/server/reporter.ts +0 -138
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "creevey",
|
3
3
|
"description": "Cross-browser screenshot testing tool for Storybook with fancy UI Runner",
|
4
|
-
"version": "0.10.0-beta.
|
4
|
+
"version": "0.10.0-beta.41",
|
5
5
|
"type": "commonjs",
|
6
6
|
"bin": "dist/cli.js",
|
7
7
|
"main": "./dist/index.js",
|
@@ -64,7 +64,7 @@
|
|
64
64
|
"build": "yarn prebuild && yarn build:client && yarn build:creevey && yarn postbuild",
|
65
65
|
"build:client": "vite build",
|
66
66
|
"build:creevey": "tsc --build tsconfig.prod.json",
|
67
|
-
"postbuild": "cp \"\"scripts/dist/*.d.ts\"\" dist/",
|
67
|
+
"postbuild": "cp \"\"scripts/dist/*.d.ts\"\" dist/ && cp \"\"src/server/playwright/index-source.mjs\"\" dist/server/playwright/index-source.mjs",
|
68
68
|
"version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md",
|
69
69
|
"build-storybook": "storybook build",
|
70
70
|
"chromatic": "chromatic --project-token=chpt_80df83ca94e6fb4",
|
@@ -74,11 +74,11 @@
|
|
74
74
|
"node": ">=18.0"
|
75
75
|
},
|
76
76
|
"peerDependencies": {
|
77
|
-
"playwright": "*",
|
77
|
+
"playwright-core": "*",
|
78
78
|
"selenium-webdriver": "*"
|
79
79
|
},
|
80
80
|
"peerDependenciesMeta": {
|
81
|
-
"playwright": {
|
81
|
+
"playwright-core": {
|
82
82
|
"optional": true
|
83
83
|
},
|
84
84
|
"selenium-webdriver": {
|
@@ -87,33 +87,33 @@
|
|
87
87
|
},
|
88
88
|
"dependencies": {
|
89
89
|
"@koa/cors": "^5.0.0",
|
90
|
-
"@octokit/core": "^6.1.
|
91
|
-
"@storybook/icons": "^1.
|
90
|
+
"@octokit/core": "^6.1.4",
|
91
|
+
"@storybook/icons": "^1.4.0",
|
92
92
|
"@types/chai": "^4.3.20",
|
93
|
-
"@types/dockerode": "^3.3.
|
93
|
+
"@types/dockerode": "^3.3.37",
|
94
94
|
"@types/koa": "^2.15.0",
|
95
95
|
"@types/koa-bodyparser": "^4.3.12",
|
96
96
|
"@types/koa-mount": "^4.0.5",
|
97
97
|
"@types/koa-static": "^4.0.4",
|
98
98
|
"@types/koa__cors": "^5.0.0",
|
99
|
-
"@types/lodash": "^4.17.
|
99
|
+
"@types/lodash": "^4.17.16",
|
100
100
|
"@types/micromatch": "^4.0.9",
|
101
101
|
"@types/minimist": "^1.2.5",
|
102
102
|
"@types/pixelmatch": "^5.2.6",
|
103
103
|
"@types/pngjs": "^6.0.5",
|
104
|
-
"@types/qs": "^6.9.
|
105
|
-
"@types/react": "^18.3.
|
106
|
-
"@types/react-dom": "^18.3.
|
107
|
-
"@types/selenium-webdriver": "^4.1.
|
104
|
+
"@types/qs": "^6.9.18",
|
105
|
+
"@types/react": "^18.3.20",
|
106
|
+
"@types/react-dom": "^18.3.6",
|
107
|
+
"@types/selenium-webdriver": "^4.1.28",
|
108
108
|
"@types/shelljs": "^0.8.15",
|
109
|
-
"@types/ws": "^8.
|
109
|
+
"@types/ws": "^8.18.1",
|
110
110
|
"chai": "^4.5.0",
|
111
111
|
"chalk": "^4.1.2",
|
112
|
-
"chokidar": "^4.0.
|
113
|
-
"dockerode": "^4.0.
|
112
|
+
"chokidar": "^4.0.3",
|
113
|
+
"dockerode": "^4.0.5",
|
114
114
|
"find-cache-dir": "^5.0.0",
|
115
115
|
"get-port": "^7.1.0",
|
116
|
-
"koa": "^2.
|
116
|
+
"koa": "^2.16.0",
|
117
117
|
"koa-bodyparser": "^4.4.1",
|
118
118
|
"koa-mount": "^4.0.0",
|
119
119
|
"koa-static": "^5.0.0",
|
@@ -122,72 +122,73 @@
|
|
122
122
|
"loglevel-plugin-prefix": "^0.8.4",
|
123
123
|
"micromatch": "^4.0.8",
|
124
124
|
"minimist": "^1.2.8",
|
125
|
-
"odiff-bin": "^3.1
|
125
|
+
"odiff-bin": "^3.2.1",
|
126
|
+
"package-manager-detector": "^0.2.11",
|
127
|
+
"pidtree": "^0.6.0",
|
126
128
|
"pixelmatch": "^6.0.0",
|
127
129
|
"pngjs": "^7.0.0",
|
128
130
|
"polished": "^4.3.1",
|
129
|
-
"qs": "^6.
|
130
|
-
"semver": "^7.
|
131
|
-
"shelljs": "^0.
|
131
|
+
"qs": "^6.14.0",
|
132
|
+
"semver": "^7.7.1",
|
133
|
+
"shelljs": "^0.9.2",
|
132
134
|
"tar-stream": "^3.1.7",
|
133
|
-
"tsx": "^4.19.
|
134
|
-
"uuid": "^11.0
|
135
|
-
"ws": "^8.18.
|
136
|
-
"yocto-spinner": "^0.
|
135
|
+
"tsx": "^4.19.3",
|
136
|
+
"uuid": "^11.1.0",
|
137
|
+
"ws": "^8.18.1",
|
138
|
+
"yocto-spinner": "^0.2.1"
|
137
139
|
},
|
138
140
|
"devDependencies": {
|
139
|
-
"@chromatic-com/storybook": "^3.2.
|
140
|
-
"@eslint/js": "^9.
|
141
|
-
"@storybook/addon-essentials": "^8.
|
142
|
-
"@storybook/addon-interactions": "^8.
|
143
|
-
"@storybook/blocks": "^8.
|
144
|
-
"@storybook/channels": "^8.
|
145
|
-
"@storybook/components": "^8.
|
146
|
-
"@storybook/
|
147
|
-
"@storybook/
|
148
|
-
"@storybook/
|
149
|
-
"@storybook/react": "^8.
|
150
|
-
"@storybook/
|
151
|
-
"@storybook/
|
152
|
-
"@storybook/
|
153
|
-
"@storybook/types": "^8.4.1",
|
141
|
+
"@chromatic-com/storybook": "^3.2.6",
|
142
|
+
"@eslint/js": "^9.23.0",
|
143
|
+
"@storybook/addon-essentials": "^8.6.12",
|
144
|
+
"@storybook/addon-interactions": "^8.6.12",
|
145
|
+
"@storybook/blocks": "^8.6.12",
|
146
|
+
"@storybook/channels": "^8.6.12",
|
147
|
+
"@storybook/components": "^8.6.12",
|
148
|
+
"@storybook/manager-api": "^8.6.12",
|
149
|
+
"@storybook/preview-api": "^8.6.12",
|
150
|
+
"@storybook/react": "^8.6.12",
|
151
|
+
"@storybook/react-vite": "^8.6.12",
|
152
|
+
"@storybook/test": "^8.6.12",
|
153
|
+
"@storybook/theming": "^8.6.12",
|
154
|
+
"@storybook/types": "^8.6.12",
|
154
155
|
"@types/eslint": "^9.6.1",
|
155
156
|
"@types/eslint__js": "^8.42.3",
|
156
|
-
"@types/node": "^18.19.
|
157
|
+
"@types/node": "^18.19.86",
|
157
158
|
"@types/resize-observer-browser": "^0.1.11",
|
158
|
-
"@types/semver": "^7",
|
159
|
+
"@types/semver": "^7.7.0",
|
159
160
|
"@types/tar-stream": "^3.1.3",
|
160
161
|
"@types/tmp": "^0.2.6",
|
161
|
-
"@vitejs/plugin-react-swc": "^3.
|
162
|
-
"browserstack-local": "^1.5.
|
163
|
-
"chromatic": "^11.
|
164
|
-
"concurrently": "^9.
|
162
|
+
"@vitejs/plugin-react-swc": "^3.8.1",
|
163
|
+
"browserstack-local": "^1.5.6",
|
164
|
+
"chromatic": "^11.28.0",
|
165
|
+
"concurrently": "^9.1.2",
|
165
166
|
"conventional-changelog-cli": "^5.0.0",
|
166
|
-
"dotenv": "^16.4.
|
167
|
-
"eslint": "^9.
|
168
|
-
"eslint-config-prettier": "^
|
169
|
-
"eslint-plugin-prettier": "^5.2.
|
170
|
-
"eslint-plugin-react": "^7.37.
|
171
|
-
"eslint-plugin-react-hooks": "^5.
|
167
|
+
"dotenv": "^16.4.7",
|
168
|
+
"eslint": "^9.23.0",
|
169
|
+
"eslint-config-prettier": "^10.1.1",
|
170
|
+
"eslint-plugin-prettier": "^5.2.6",
|
171
|
+
"eslint-plugin-react": "^7.37.5",
|
172
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
172
173
|
"git-cz": "^4.9.0",
|
173
|
-
"globals": "^
|
174
|
-
"husky": "^9.1.
|
174
|
+
"globals": "^16.0.0",
|
175
|
+
"husky": "^9.1.7",
|
175
176
|
"immer": "^10.1.1",
|
176
|
-
"lint-staged": "^15.
|
177
|
+
"lint-staged": "^15.5.0",
|
177
178
|
"pinst": "^3.0.0",
|
178
|
-
"playwright-core": "^1.
|
179
|
-
"prettier": "^3.
|
179
|
+
"playwright-core": "^1.51.1",
|
180
|
+
"prettier": "^3.5.3",
|
180
181
|
"react": "^18.3.1",
|
181
182
|
"react-dom": "^18.3.1",
|
182
183
|
"react-is": "^18.3.1",
|
183
|
-
"selenium-webdriver": "^4.
|
184
|
-
"storybook": "^8.
|
184
|
+
"selenium-webdriver": "^4.30.0",
|
185
|
+
"storybook": "^8.6.12",
|
185
186
|
"tmp": "^0.2.3",
|
186
|
-
"typescript": "^5.
|
187
|
-
"typescript-eslint": "^8.
|
188
|
-
"use-immer": "^0.
|
189
|
-
"vite": "^5.4.
|
190
|
-
"vitest": "^2.1.
|
187
|
+
"typescript": "^5.8.2",
|
188
|
+
"typescript-eslint": "^8.29.0",
|
189
|
+
"use-immer": "^0.11.0",
|
190
|
+
"vite": "^5.4.17",
|
191
|
+
"vitest": "^2.1.9"
|
191
192
|
},
|
192
193
|
"config": {
|
193
194
|
"commitizen": {
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import React, { JSX } from 'react';
|
2
2
|
import { Loader } from '@storybook/components';
|
3
3
|
import { styled } from '@storybook/theming';
|
4
|
-
import { TestData } from '../../../types.js';
|
4
|
+
import { noop, TestData } from '../../../types.js';
|
5
5
|
import { ResultsPage } from '../../shared/components/ResultsPage.js';
|
6
6
|
import { getTestPath } from '../../shared/helpers.js';
|
7
7
|
import TestSelect from './TestSelect.js';
|
8
|
-
|
8
|
+
|
9
9
|
interface PanelProps {
|
10
10
|
tests: TestData[];
|
11
11
|
selectedTestId: string;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { Renderer, StoryContextForEnhancers } from '@storybook/
|
1
|
+
import type { Renderer, StoryContextForEnhancers } from '@storybook/types';
|
2
2
|
import { makeDecorator, PreviewWeb, StoryStore } from '@storybook/preview-api';
|
3
3
|
import { Channel } from '@storybook/channels';
|
4
4
|
import {
|
@@ -12,9 +12,11 @@ import {
|
|
12
12
|
} from '../../types.js';
|
13
13
|
import { serializeRawStories } from '../../shared/index.js';
|
14
14
|
import { getConnectionUrl } from '../shared/helpers.js';
|
15
|
+
import isEqual from 'lodash/isEqual.js';
|
15
16
|
|
16
17
|
declare global {
|
17
18
|
interface Window {
|
19
|
+
__CREEVEY_ENV__: boolean;
|
18
20
|
__CREEVEY_SERVER_HOST__: string;
|
19
21
|
__CREEVEY_SERVER_PORT__: number;
|
20
22
|
__CREEVEY_WORKER_ID__: number;
|
@@ -139,6 +141,7 @@ let captureResolver: () => void;
|
|
139
141
|
let waitForCreevey: Promise<void>;
|
140
142
|
let creeveyReady: () => void;
|
141
143
|
let setStoriesCounter = 0;
|
144
|
+
let globals = {};
|
142
145
|
|
143
146
|
export function withCreevey(): ReturnType<typeof makeDecorator> {
|
144
147
|
const addonsChannel = (): Channel => window.__STORYBOOK_ADDONS_CHANNEL__;
|
@@ -225,7 +228,10 @@ export function withCreevey(): ReturnType<typeof makeDecorator> {
|
|
225
228
|
}
|
226
229
|
}
|
227
230
|
|
228
|
-
function updateGlobals(
|
231
|
+
function updateGlobals(newGlobals: StorybookGlobals): void {
|
232
|
+
if (isEqual(globals, newGlobals)) return;
|
233
|
+
|
234
|
+
globals = newGlobals;
|
229
235
|
addonsChannel().emit(StorybookEvents.UPDATE_GLOBALS, { globals });
|
230
236
|
}
|
231
237
|
|
@@ -274,6 +280,7 @@ export function withCreevey(): ReturnType<typeof makeDecorator> {
|
|
274
280
|
});
|
275
281
|
}
|
276
282
|
|
283
|
+
window.__CREEVEY_ENV__ = false;
|
277
284
|
window.__CREEVEY_GET_STORIES__ = getStories;
|
278
285
|
window.__CREEVEY_SELECT_STORY__ = selectStory;
|
279
286
|
window.__CREEVEY_UPDATE_GLOBALS__ = updateGlobals;
|
@@ -315,6 +322,7 @@ export function withCreevey(): ReturnType<typeof makeDecorator> {
|
|
315
322
|
});
|
316
323
|
}
|
317
324
|
|
325
|
+
// TODO It's not accessible from the outside the package
|
318
326
|
export async function capture(options?: CaptureOptions): Promise<void> {
|
319
327
|
if (!isTestBrowser) return;
|
320
328
|
|
@@ -46,6 +46,24 @@ export const SwapView = withTheme(({ theme, expect, actual, diff }: ViewPropsWit
|
|
46
46
|
setImage((prevImage) => (prevImage == 'actual' ? 'expect' : 'actual'));
|
47
47
|
}, []);
|
48
48
|
|
49
|
+
const handleKeyDown = useCallback(
|
50
|
+
(e: KeyboardEvent) => {
|
51
|
+
if (e.code === 'Space' && e.altKey) {
|
52
|
+
e.preventDefault();
|
53
|
+
handleChangeView();
|
54
|
+
}
|
55
|
+
},
|
56
|
+
[handleChangeView],
|
57
|
+
);
|
58
|
+
|
59
|
+
useEffect(() => {
|
60
|
+
document.addEventListener('keydown', handleKeyDown, false);
|
61
|
+
|
62
|
+
return () => {
|
63
|
+
document.removeEventListener('keydown', handleKeyDown, false);
|
64
|
+
};
|
65
|
+
}, [handleKeyDown]);
|
66
|
+
|
49
67
|
useEffect(() => {
|
50
68
|
if (loaded) readyForCapture();
|
51
69
|
}, [loaded]);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { JSX, useEffect } from 'react';
|
1
|
+
import React, { JSX, useContext, useEffect } from 'react';
|
2
2
|
import { Tabs } from '@storybook/components';
|
3
3
|
import { CloseAltIcon } from '@storybook/icons';
|
4
4
|
import { styled, withTheme, Theme } from '@storybook/theming';
|
@@ -6,6 +6,7 @@ import { ImagesViewMode, Images } from '../../../../types.js';
|
|
6
6
|
import { getImageUrl } from '../../helpers.js';
|
7
7
|
import { ImagePreview } from './ImagePreview.js';
|
8
8
|
import { viewModes } from '../../viewMode.js';
|
9
|
+
import { CreeveyContext } from '../../../web/CreeveyContext.js';
|
9
10
|
|
10
11
|
interface PageHeaderProps {
|
11
12
|
title: string[];
|
@@ -76,6 +77,7 @@ export function PageHeader({
|
|
76
77
|
onImageChange,
|
77
78
|
onViewModeChange,
|
78
79
|
}: PageHeaderProps): JSX.Element | null {
|
80
|
+
const { isReport } = useContext(CreeveyContext);
|
79
81
|
const imageEntires = Object.entries(images) as [string, Images][];
|
80
82
|
|
81
83
|
const handleViewModeChange = (mode: string): void => {
|
@@ -110,7 +112,7 @@ export function PageHeader({
|
|
110
112
|
<ImagePreview
|
111
113
|
key={name}
|
112
114
|
imageName={name}
|
113
|
-
url={`${getImageUrl(title, name)}/${image.actual}`}
|
115
|
+
url={`${getImageUrl(title, name, isReport)}/${image.actual}`}
|
114
116
|
isActive={name === imageName}
|
115
117
|
onClick={onImageChange}
|
116
118
|
error={imagesWithError.includes(name)}
|
@@ -1,12 +1,13 @@
|
|
1
|
-
import React, { JSX, useState } from 'react';
|
1
|
+
import React, { JSX, useCallback, useContext, useEffect, useState } from 'react';
|
2
2
|
import { Placeholder, ScrollArea } from '@storybook/components';
|
3
3
|
import { styled, withTheme, Theme } from '@storybook/theming';
|
4
4
|
import { ImagesView } from './ImagesView/ImagesView.js';
|
5
5
|
import { PageHeader } from './PageHeader/PageHeader.js';
|
6
6
|
import { PageFooter } from './PageFooter/PageFooter.js';
|
7
7
|
import { getImageUrl } from '../helpers.js';
|
8
|
-
import { getViewMode, VIEW_MODE_KEY } from '../viewMode.js';
|
8
|
+
import { getViewMode, VIEW_MODE_KEY, viewModes } from '../viewMode.js';
|
9
9
|
import { ImagesViewMode, TestResult } from '../../../types.js';
|
10
|
+
import { CreeveyContext } from '../../web/CreeveyContext.js';
|
10
11
|
|
11
12
|
interface ResultsPageProps {
|
12
13
|
path: string[];
|
@@ -65,8 +66,9 @@ export function ResultsPageInternal({
|
|
65
66
|
onRetryChange,
|
66
67
|
}: ResultsPageProps): JSX.Element {
|
67
68
|
const result = results[retry - 1] ?? {};
|
69
|
+
const { isReport } = useContext(CreeveyContext);
|
68
70
|
const [viewMode, setViewMode] = useState<ImagesViewMode>(getViewMode());
|
69
|
-
const url = getImageUrl(path, imageName);
|
71
|
+
const url = getImageUrl(path, imageName, isReport);
|
70
72
|
const image = result.images?.[imageName];
|
71
73
|
const canApprove = Boolean(image && approved?.[imageName] != retry - 1 && result.status != 'success');
|
72
74
|
const hasDiffAndExpect = canApprove && Boolean(image?.diff && image.expect);
|
@@ -77,10 +79,31 @@ export function ResultsPageInternal({
|
|
77
79
|
)
|
78
80
|
: [];
|
79
81
|
|
80
|
-
const
|
81
|
-
|
82
|
-
|
83
|
-
|
82
|
+
const handleKeyDown = useCallback(
|
83
|
+
(e: KeyboardEvent) => {
|
84
|
+
if (!canApprove) return;
|
85
|
+
if (e.code === 'Tab') {
|
86
|
+
e.preventDefault();
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
88
|
+
if (e.shiftKey) setViewMode((mode) => viewModes.at((viewModes.indexOf(mode) - 1) % viewModes.length)!);
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
90
|
+
else setViewMode((mode) => viewModes.at((viewModes.indexOf(mode) + 1) % viewModes.length)!);
|
91
|
+
}
|
92
|
+
},
|
93
|
+
[canApprove],
|
94
|
+
);
|
95
|
+
|
96
|
+
useEffect(() => {
|
97
|
+
localStorage.setItem(VIEW_MODE_KEY, viewMode);
|
98
|
+
}, [viewMode]);
|
99
|
+
|
100
|
+
useEffect(() => {
|
101
|
+
document.addEventListener('keydown', handleKeyDown, false);
|
102
|
+
|
103
|
+
return () => {
|
104
|
+
document.removeEventListener('keydown', handleKeyDown, false);
|
105
|
+
};
|
106
|
+
}, [handleKeyDown]);
|
84
107
|
|
85
108
|
return (
|
86
109
|
<Container height={height}>
|
@@ -92,7 +115,7 @@ export function ResultsPageInternal({
|
|
92
115
|
errorMessage={result.error}
|
93
116
|
showViewModes={hasDiffAndExpect}
|
94
117
|
viewMode={viewMode}
|
95
|
-
onViewModeChange={
|
118
|
+
onViewModeChange={setViewMode}
|
96
119
|
onImageChange={onImageChange}
|
97
120
|
imagesWithError={imagesWithError}
|
98
121
|
/>
|
@@ -12,6 +12,7 @@ export interface CreeveyClientApi {
|
|
12
12
|
|
13
13
|
export async function initCreeveyClientApi(): Promise<CreeveyClientApi> {
|
14
14
|
let clientApiResolver: (api: CreeveyClientApi) => void = noop;
|
15
|
+
let clientApiRejecter: (error: Error | Event) => void = noop;
|
15
16
|
const updateListeners = new Set<(update: CreeveyUpdate) => void>();
|
16
17
|
let statusRequest: Promise<CreeveyStatus> | null = null;
|
17
18
|
let statusResolver: (status: CreeveyStatus) => void = noop;
|
@@ -22,6 +23,10 @@ export async function initCreeveyClientApi(): Promise<CreeveyClientApi> {
|
|
22
23
|
ws.send(JSON.stringify(request));
|
23
24
|
}
|
24
25
|
|
26
|
+
ws.addEventListener('error', (event) => {
|
27
|
+
clientApiRejecter(event);
|
28
|
+
});
|
29
|
+
|
25
30
|
ws.addEventListener('open', () => {
|
26
31
|
clientApiResolver({
|
27
32
|
start(ids: string[]) {
|
@@ -64,5 +69,8 @@ export async function initCreeveyClientApi(): Promise<CreeveyClientApi> {
|
|
64
69
|
});
|
65
70
|
// TODO Reconnect
|
66
71
|
|
67
|
-
return new Promise((resolve) =>
|
72
|
+
return new Promise((resolve, reject) => {
|
73
|
+
clientApiResolver = resolve;
|
74
|
+
clientApiRejecter = reject;
|
75
|
+
});
|
68
76
|
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { themes, ThemeVars } from '@storybook/theming';
|
2
1
|
import { parse, stringify } from 'qs';
|
3
2
|
import { RefObject, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
4
3
|
import { TestData, isTest, isDefined, TestStatus, CreeveySuite, CreeveyTest, CreeveyStatus } from '../../types.js';
|
@@ -300,12 +299,14 @@ export function getConnectionUrl(): string {
|
|
300
299
|
.join(':');
|
301
300
|
}
|
302
301
|
|
303
|
-
export function getImageUrl(path: string[], imageName: string): string {
|
302
|
+
export function getImageUrl(path: string[], imageName: string, isReport?: boolean): string {
|
304
303
|
// path => [title, story, test, browser]
|
305
304
|
const browser = path.slice(-1)[0];
|
306
305
|
const imagesUrl = window.location.host
|
307
306
|
? `${window.location.protocol}//${getConnectionUrl()}${
|
308
|
-
window.location.pathname == '/'
|
307
|
+
window.location.pathname == '/' && !isReport
|
308
|
+
? '/report'
|
309
|
+
: window.location.pathname.split('/').slice(0, -1).join('/')
|
309
310
|
}/${encodeURI(path.slice(0, -1).join('/'))}`
|
310
311
|
: encodeURI(path.slice(0, -1).join('/'));
|
311
312
|
|
@@ -393,27 +394,6 @@ export function useCalcScale(diffImageRef: RefObject<HTMLImageElement>, loaded:
|
|
393
394
|
return scale;
|
394
395
|
}
|
395
396
|
|
396
|
-
const CREEVEY_THEME = 'Creevey_theme';
|
397
|
-
|
398
|
-
function isTheme(theme?: string | null): theme is ThemeVars['base'] {
|
399
|
-
return isDefined(theme) && Object.prototype.hasOwnProperty.call(themes, theme);
|
400
|
-
}
|
401
|
-
|
402
|
-
function initialTheme(): ThemeVars['base'] {
|
403
|
-
const theme = localStorage.getItem(CREEVEY_THEME);
|
404
|
-
return isTheme(theme) ? theme : 'light';
|
405
|
-
}
|
406
|
-
|
407
|
-
export function useTheme(): [ThemeVars['base'], (theme: ThemeVars['base']) => void] {
|
408
|
-
const [theme, setTheme] = useState<ThemeVars['base']>(initialTheme());
|
409
|
-
|
410
|
-
useEffect(() => {
|
411
|
-
localStorage.setItem(CREEVEY_THEME, theme);
|
412
|
-
}, [theme]);
|
413
|
-
|
414
|
-
return [theme, setTheme];
|
415
|
-
}
|
416
|
-
|
417
397
|
export function setSearchParams(testPath: string[]): void {
|
418
398
|
const pageUrl = `?${stringify({ testPath })}`;
|
419
399
|
window.history.pushState({ testPath }, '', pageUrl);
|
@@ -11,17 +11,17 @@ import {
|
|
11
11
|
getTestByPath,
|
12
12
|
removeTests,
|
13
13
|
getTestPath,
|
14
|
-
useTheme,
|
15
14
|
setSearchParams,
|
16
15
|
getTestPathFromSearch,
|
17
16
|
CreeveyViewFilter,
|
18
17
|
getFailedTests,
|
19
18
|
} from '../shared/helpers.js';
|
20
|
-
import { CreeveyContext } from './CreeveyContext.js';
|
19
|
+
import { CreeveyContext, FocusableItem } from './CreeveyContext.js';
|
21
20
|
import { KeyboardEvents } from './KeyboardEventsContext.js';
|
22
21
|
import { SideBar } from './CreeveyView/SideBar/index.js';
|
23
22
|
import { ResultsPage } from '../shared/components/ResultsPage.js';
|
24
23
|
import { Toggle } from './CreeveyView/SideBar/Toggle.js';
|
24
|
+
import { useTheme } from './themes.js';
|
25
25
|
|
26
26
|
export interface CreeveyAppProps {
|
27
27
|
api?: CreeveyClientApi;
|
@@ -59,8 +59,9 @@ export function CreeveyApp({ api, initialState }: CreeveyAppProps): JSX.Element
|
|
59
59
|
const failedTests = useMemo(() => getFailedTests(tests), [tests]);
|
60
60
|
|
61
61
|
const [retry, setRetry] = useState(openedTest?.results?.length ?? 0);
|
62
|
-
const result = openedTest?.results?.[retry - 1]
|
63
|
-
const [imageName, setImageName] = useState(Object.keys(result
|
62
|
+
const result = useMemo(() => openedTest?.results?.[retry - 1], [openedTest, retry]);
|
63
|
+
const [imageName, setImageName] = useState(Object.keys(result?.images ?? {})[0] ?? '');
|
64
|
+
const [sidebarFocusedItem, setSidebarFocusedItem] = useState<FocusableItem>([]);
|
64
65
|
const canApprove = useMemo(
|
65
66
|
() =>
|
66
67
|
Boolean(
|
@@ -94,6 +95,7 @@ export function CreeveyApp({ api, initialState }: CreeveyAppProps): JSX.Element
|
|
94
95
|
(test: CreeveyTest): void => {
|
95
96
|
const testPath = getTestPath(test);
|
96
97
|
setSearchParams(testPath);
|
98
|
+
setSidebarFocusedItem(testPath);
|
97
99
|
updateTests((draft) => {
|
98
100
|
openSuite(draft, testPath, true);
|
99
101
|
openTest(testPath);
|
@@ -103,11 +105,24 @@ export function CreeveyApp({ api, initialState }: CreeveyAppProps): JSX.Element
|
|
103
105
|
);
|
104
106
|
|
105
107
|
const handleGoToNextFailedTest = useCallback(() => {
|
106
|
-
if (failedTests.length
|
108
|
+
if (failedTests.length == 0) return;
|
107
109
|
const currentTest = failedTests.findIndex((t) => t.id === openedTest?.id);
|
108
|
-
const
|
109
|
-
|
110
|
-
|
110
|
+
const failedImages = Object.entries(result?.images ?? {})
|
111
|
+
.filter(([name, image]) =>
|
112
|
+
// TODO Move to helpers, it duplicates in a few places
|
113
|
+
Boolean(image?.error != null && openedTest?.approved?.[name] != retry - 1 && result?.status != 'success'),
|
114
|
+
)
|
115
|
+
.map(([name]) => name);
|
116
|
+
if (
|
117
|
+
failedImages.length > 1 &&
|
118
|
+
(failedTests.length == 1 || failedImages.indexOf(imageName) < failedImages.length - 1)
|
119
|
+
) {
|
120
|
+
setImageName((name) => failedImages[failedImages.indexOf(name) + 1] ?? failedImages[0]);
|
121
|
+
} else {
|
122
|
+
const nextFailedTest = failedTests[currentTest + 1] ?? failedTests[0];
|
123
|
+
handleOpenTest(nextFailedTest);
|
124
|
+
}
|
125
|
+
}, [failedTests, handleOpenTest, openedTest, retry, result, imageName]);
|
111
126
|
|
112
127
|
const handleImageApproveNew = useCallback((): void => {
|
113
128
|
const id = openedTest?.id;
|
@@ -122,6 +137,7 @@ export function CreeveyApp({ api, initialState }: CreeveyAppProps): JSX.Element
|
|
122
137
|
}, [handleImageApproveNew, handleGoToNextFailedTest]);
|
123
138
|
|
124
139
|
const handleApproveAll = useCallback(() => {
|
140
|
+
// TODO Update handled incorrectly
|
125
141
|
api?.approveAll();
|
126
142
|
}, [api]);
|
127
143
|
|
@@ -189,12 +205,15 @@ export function CreeveyApp({ api, initialState }: CreeveyAppProps): JSX.Element
|
|
189
205
|
value={{
|
190
206
|
isReport: initialState.isReport,
|
191
207
|
isRunning,
|
208
|
+
onImageNext: canApprove ? handleGoToNextFailedTest : undefined,
|
192
209
|
onImageApprove: canApprove ? handleImageApproveAndGoNext : undefined,
|
193
210
|
onApproveAll: handleApproveAll,
|
194
211
|
onStart: handleStart,
|
195
212
|
onStop: handleStop,
|
196
213
|
onSuiteOpen: handleSuiteOpen,
|
197
214
|
onSuiteToggle: handleSuiteToggle,
|
215
|
+
sidebarFocusedItem,
|
216
|
+
setSidebarFocusedItem,
|
198
217
|
}}
|
199
218
|
>
|
200
219
|
<ThemeProvider theme={ensure(themes[theme])}>
|
@@ -1,26 +1,35 @@
|
|
1
1
|
import React, { useContext } from 'react';
|
2
2
|
import { CreeveySuite, noop } from '../../types.js';
|
3
3
|
|
4
|
+
export type SuitePath = string[];
|
5
|
+
export type FocusableItem = null | SuitePath;
|
6
|
+
|
4
7
|
export interface CreeveyContextType {
|
5
8
|
isReport: boolean;
|
6
9
|
isRunning: boolean;
|
7
10
|
onStop: () => void;
|
11
|
+
onImageNext?: () => void;
|
8
12
|
onImageApprove?: () => void;
|
9
13
|
onApproveAll: () => void;
|
10
14
|
onStart: (rootSuite: CreeveySuite) => void;
|
11
15
|
onSuiteOpen: (path: string[], opened: boolean) => void;
|
12
16
|
onSuiteToggle: (path: string[], checked: boolean) => void;
|
17
|
+
sidebarFocusedItem: FocusableItem;
|
18
|
+
setSidebarFocusedItem: (item: FocusableItem) => void;
|
13
19
|
}
|
14
20
|
|
15
21
|
export const CreeveyContext = React.createContext<CreeveyContextType>({
|
16
22
|
isReport: true,
|
17
23
|
isRunning: false,
|
24
|
+
onImageNext: noop,
|
18
25
|
onImageApprove: noop,
|
19
26
|
onApproveAll: noop,
|
20
27
|
onStop: noop,
|
21
28
|
onStart: noop,
|
22
29
|
onSuiteOpen: noop,
|
23
30
|
onSuiteToggle: noop,
|
31
|
+
sidebarFocusedItem: [],
|
32
|
+
setSidebarFocusedItem: noop,
|
24
33
|
});
|
25
34
|
|
26
35
|
export const useCreeveyContext = () => useContext(CreeveyContext);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React, { JSX } from 'react';
|
2
2
|
import { styled, withTheme, Theme, keyframes, ensure, ThemeProvider, themes, Keyframes } from '@storybook/theming';
|
3
|
-
import { useTheme } from '
|
3
|
+
import { useTheme } from './themes.js';
|
4
4
|
|
5
5
|
const Container = withTheme(
|
6
6
|
styled.div(({ theme }) => ({
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import React, { JSX, ChangeEvent,
|
1
|
+
import React, { JSX, ChangeEvent, useRef, useState } from 'react';
|
2
2
|
import { SearchIcon, CloseAltIcon } from '@storybook/icons';
|
3
3
|
import { styled, Theme, withTheme } from '@storybook/theming';
|
4
|
-
import {
|
4
|
+
import { useCreeveyContext } from '../../CreeveyContext.js';
|
5
5
|
|
6
6
|
interface SearchProps {
|
7
7
|
onChange: (arg: string) => void;
|
@@ -100,7 +100,7 @@ const FilterForm = withTheme(
|
|
100
100
|
);
|
101
101
|
|
102
102
|
export const Search = ({ onChange, value }: SearchProps): JSX.Element => {
|
103
|
-
const { setSidebarFocusedItem } =
|
103
|
+
const { setSidebarFocusedItem } = useCreeveyContext();
|
104
104
|
const [focussed, onSetFocussed] = useState(false);
|
105
105
|
const searchRef = useRef<HTMLInputElement>(null);
|
106
106
|
|