creevey 0.9.2 → 0.10.0-beta.0

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.
Files changed (259) hide show
  1. package/chromatic.config.json +5 -0
  2. package/dist/client/addon/components/Addon.d.ts +1 -0
  3. package/dist/client/addon/components/Addon.js.map +1 -1
  4. package/dist/client/addon/components/Icons.d.ts +1 -0
  5. package/dist/client/addon/components/Icons.js.map +1 -1
  6. package/dist/client/addon/components/Panel.d.ts +1 -0
  7. package/dist/client/addon/components/Panel.js.map +1 -1
  8. package/dist/client/addon/components/TestSelect.d.ts +1 -0
  9. package/dist/client/addon/components/TestSelect.js +4 -3
  10. package/dist/client/addon/components/TestSelect.js.map +1 -1
  11. package/dist/client/addon/components/Tools.d.ts +1 -0
  12. package/dist/client/addon/components/Tools.js +7 -8
  13. package/dist/client/addon/components/Tools.js.map +1 -1
  14. package/dist/client/addon/controller.d.ts +1 -1
  15. package/dist/client/addon/controller.js.map +1 -1
  16. package/dist/client/addon/decorator.d.ts +1 -1
  17. package/dist/client/addon/manager.js +3 -2
  18. package/dist/client/addon/manager.js.map +1 -1
  19. package/dist/client/addon/preview.d.ts +1 -1
  20. package/dist/client/addon/withCreevey.d.ts +6 -8
  21. package/dist/client/addon/withCreevey.js +21 -19
  22. package/dist/client/addon/withCreevey.js.map +1 -1
  23. package/dist/client/shared/components/ImagesView/BlendView.d.ts +1 -1
  24. package/dist/client/shared/components/ImagesView/BlendView.js.map +1 -1
  25. package/dist/client/shared/components/ImagesView/ImagesView.d.ts +1 -0
  26. package/dist/client/shared/components/ImagesView/ImagesView.js.map +1 -1
  27. package/dist/client/shared/components/ImagesView/SideBySideView.d.ts +1 -1
  28. package/dist/client/shared/components/ImagesView/SideBySideView.js.map +1 -1
  29. package/dist/client/shared/components/ImagesView/SlideView.d.ts +1 -1
  30. package/dist/client/shared/components/ImagesView/SlideView.js.map +1 -1
  31. package/dist/client/shared/components/ImagesView/SwapView.d.ts +1 -1
  32. package/dist/client/shared/components/ImagesView/SwapView.js.map +1 -1
  33. package/dist/client/shared/components/PageFooter/PageFooter.d.ts +1 -0
  34. package/dist/client/shared/components/PageFooter/PageFooter.js +1 -1
  35. package/dist/client/shared/components/PageFooter/PageFooter.js.map +1 -1
  36. package/dist/client/shared/components/PageFooter/Paging.d.ts +2 -2
  37. package/dist/client/shared/components/PageFooter/Paging.js +8 -6
  38. package/dist/client/shared/components/PageFooter/Paging.js.map +1 -1
  39. package/dist/client/shared/components/PageHeader/ImagePreview.js.map +1 -1
  40. package/dist/client/shared/components/PageHeader/PageHeader.d.ts +1 -0
  41. package/dist/client/shared/components/PageHeader/PageHeader.js +2 -1
  42. package/dist/client/shared/components/PageHeader/PageHeader.js.map +1 -1
  43. package/dist/client/shared/components/ResultsPage.d.ts +2 -2
  44. package/dist/client/shared/components/ResultsPage.js.map +1 -1
  45. package/dist/client/web/CreeveyApp.d.ts +1 -0
  46. package/dist/client/web/CreeveyApp.js.map +1 -1
  47. package/dist/client/web/CreeveyLoader.d.ts +1 -0
  48. package/dist/client/web/CreeveyLoader.js.map +1 -1
  49. package/dist/client/web/CreeveyView/SideBar/Checkbox.d.ts +1 -1
  50. package/dist/client/web/CreeveyView/SideBar/Checkbox.js +4 -4
  51. package/dist/client/web/CreeveyView/SideBar/Checkbox.js.map +1 -1
  52. package/dist/client/web/CreeveyView/SideBar/Search.d.ts +1 -0
  53. package/dist/client/web/CreeveyView/SideBar/Search.js +4 -4
  54. package/dist/client/web/CreeveyView/SideBar/Search.js.map +1 -1
  55. package/dist/client/web/CreeveyView/SideBar/SideBar.d.ts +1 -1
  56. package/dist/client/web/CreeveyView/SideBar/SideBar.js +1 -7
  57. package/dist/client/web/CreeveyView/SideBar/SideBar.js.map +1 -1
  58. package/dist/client/web/CreeveyView/SideBar/SideBarFooter.d.ts +1 -0
  59. package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js +5 -4
  60. package/dist/client/web/CreeveyView/SideBar/SideBarFooter.js.map +1 -1
  61. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.d.ts +1 -0
  62. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js +4 -3
  63. package/dist/client/web/CreeveyView/SideBar/SideBarHeader.js.map +1 -1
  64. package/dist/client/web/CreeveyView/SideBar/SuiteLink.d.ts +3 -7
  65. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js +6 -5
  66. package/dist/client/web/CreeveyView/SideBar/SuiteLink.js.map +1 -1
  67. package/dist/client/web/CreeveyView/SideBar/TestLink.d.ts +1 -0
  68. package/dist/client/web/CreeveyView/SideBar/TestLink.js +5 -1
  69. package/dist/client/web/CreeveyView/SideBar/TestLink.js.map +1 -1
  70. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js +15 -8
  71. package/dist/client/web/CreeveyView/SideBar/TestStatusIcon.js.map +1 -1
  72. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js +5 -4
  73. package/dist/client/web/CreeveyView/SideBar/TestsStatus.js.map +1 -1
  74. package/dist/client/web/CreeveyView/SideBar/Toggle.d.ts +1 -0
  75. package/dist/client/web/CreeveyView/SideBar/Toggle.js.map +1 -1
  76. package/dist/client/web/KeyboardEventsContext.d.ts +3 -4
  77. package/dist/client/web/KeyboardEventsContext.js.map +1 -1
  78. package/dist/client/web/assets/index-DkmZfG9C.js +591 -0
  79. package/dist/client/web/index.html +1 -1
  80. package/dist/client/web/index.js +5 -6
  81. package/dist/client/web/index.js.map +1 -1
  82. package/dist/creevey.js +21 -9
  83. package/dist/creevey.js.map +1 -1
  84. package/dist/index.js +7 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/server/config.d.ts +1 -1
  87. package/dist/server/config.js +9 -5
  88. package/dist/server/config.js.map +1 -1
  89. package/dist/server/docker.d.ts +2 -2
  90. package/dist/server/docker.js +46 -40
  91. package/dist/server/docker.js.map +1 -1
  92. package/dist/server/index.js +54 -15
  93. package/dist/server/index.js.map +1 -1
  94. package/dist/server/master/master.d.ts +1 -5
  95. package/dist/server/master/master.js +3 -3
  96. package/dist/server/master/master.js.map +1 -1
  97. package/dist/server/master/pool.d.ts +2 -1
  98. package/dist/server/master/pool.js +9 -5
  99. package/dist/server/master/pool.js.map +1 -1
  100. package/dist/server/master/runner.d.ts +1 -1
  101. package/dist/server/master/runner.js +2 -2
  102. package/dist/server/master/runner.js.map +1 -1
  103. package/dist/server/master/server.js +1 -0
  104. package/dist/server/master/server.js.map +1 -1
  105. package/dist/server/master/start.d.ts +3 -0
  106. package/dist/server/master/{index.js → start.js} +6 -9
  107. package/dist/server/master/start.js.map +1 -0
  108. package/dist/server/messages.d.ts +4 -10
  109. package/dist/server/messages.js +4 -58
  110. package/dist/server/messages.js.map +1 -1
  111. package/dist/server/playwright/docker-file.d.ts +1 -0
  112. package/dist/server/playwright/docker-file.js +26 -0
  113. package/dist/server/playwright/docker-file.js.map +1 -0
  114. package/dist/server/playwright/docker.d.ts +1 -0
  115. package/dist/server/playwright/docker.js +31 -0
  116. package/dist/server/playwright/docker.js.map +1 -0
  117. package/dist/server/playwright/internal.d.ts +25 -0
  118. package/dist/server/playwright/internal.js +319 -0
  119. package/dist/server/playwright/internal.js.map +1 -0
  120. package/dist/server/playwright/webdriver.d.ts +16 -0
  121. package/dist/server/playwright/webdriver.js +105 -0
  122. package/dist/server/playwright/webdriver.js.map +1 -0
  123. package/dist/server/providers/browser.d.ts +2 -0
  124. package/dist/server/{storybook/providers → providers}/browser.js +6 -7
  125. package/dist/server/providers/browser.js.map +1 -0
  126. package/dist/server/providers/hybrid.d.ts +2 -0
  127. package/dist/server/{storybook/providers → providers}/hybrid.js +8 -8
  128. package/dist/server/providers/hybrid.js.map +1 -0
  129. package/dist/server/reporter.d.ts +26 -0
  130. package/dist/server/{worker/reporter.js → reporter.js} +34 -56
  131. package/dist/server/reporter.js.map +1 -0
  132. package/dist/server/selenium/internal.d.ts +31 -0
  133. package/dist/server/selenium/internal.js +606 -0
  134. package/dist/server/selenium/internal.js.map +1 -0
  135. package/dist/server/selenium/selenoid.js +6 -13
  136. package/dist/server/selenium/selenoid.js.map +1 -1
  137. package/dist/server/selenium/webdriver.d.ts +24 -0
  138. package/dist/server/selenium/webdriver.js +106 -0
  139. package/dist/server/selenium/webdriver.js.map +1 -0
  140. package/dist/server/stories.js +16 -9
  141. package/dist/server/stories.js.map +1 -1
  142. package/dist/server/telemetry.d.ts +1 -1
  143. package/dist/server/telemetry.js +4 -4
  144. package/dist/server/telemetry.js.map +1 -1
  145. package/dist/server/utils.d.ts +3 -4
  146. package/dist/server/utils.js +10 -9
  147. package/dist/server/utils.js.map +1 -1
  148. package/dist/server/webdriver.d.ts +19 -0
  149. package/dist/server/webdriver.js +79 -0
  150. package/dist/server/webdriver.js.map +1 -0
  151. package/dist/server/worker/chai-image.d.ts +2 -5
  152. package/dist/server/worker/chai-image.js +14 -102
  153. package/dist/server/worker/chai-image.js.map +1 -1
  154. package/dist/server/worker/match-image.d.ts +14 -0
  155. package/dist/server/worker/match-image.js +231 -0
  156. package/dist/server/worker/match-image.js.map +1 -0
  157. package/dist/server/worker/start.d.ts +2 -0
  158. package/dist/server/worker/start.js +258 -0
  159. package/dist/server/worker/start.js.map +1 -0
  160. package/dist/types.d.ts +126 -64
  161. package/dist/types.js +15 -9
  162. package/dist/types.js.map +1 -1
  163. package/package.json +108 -110
  164. package/src/client/addon/components/Addon.tsx +1 -1
  165. package/src/client/addon/components/Icons.tsx +1 -1
  166. package/src/client/addon/components/Panel.tsx +1 -1
  167. package/src/client/addon/components/TestSelect.tsx +5 -5
  168. package/src/client/addon/components/Tools.tsx +9 -9
  169. package/src/client/addon/controller.ts +1 -1
  170. package/src/client/addon/manager.ts +4 -4
  171. package/src/client/addon/withCreevey.ts +26 -28
  172. package/src/client/shared/components/ImagesView/BlendView.tsx +1 -1
  173. package/src/client/shared/components/ImagesView/ImagesView.tsx +2 -2
  174. package/src/client/shared/components/ImagesView/SideBySideView.tsx +1 -1
  175. package/src/client/shared/components/ImagesView/SlideView.tsx +1 -1
  176. package/src/client/shared/components/ImagesView/SwapView.tsx +1 -1
  177. package/src/client/shared/components/PageFooter/PageFooter.tsx +2 -2
  178. package/src/client/shared/components/PageFooter/Paging.tsx +13 -13
  179. package/src/client/shared/components/PageHeader/ImagePreview.tsx +1 -1
  180. package/src/client/shared/components/PageHeader/PageHeader.tsx +4 -3
  181. package/src/client/shared/components/ResultsPage.tsx +1 -1
  182. package/src/client/web/CreeveyApp.tsx +1 -1
  183. package/src/client/web/CreeveyLoader.tsx +1 -1
  184. package/src/client/web/CreeveyView/SideBar/Checkbox.tsx +6 -7
  185. package/src/client/web/CreeveyView/SideBar/Search.tsx +4 -4
  186. package/src/client/web/CreeveyView/SideBar/SideBar.tsx +3 -10
  187. package/src/client/web/CreeveyView/SideBar/SideBarFooter.tsx +7 -6
  188. package/src/client/web/CreeveyView/SideBar/SideBarHeader.tsx +7 -6
  189. package/src/client/web/CreeveyView/SideBar/SuiteLink.tsx +8 -6
  190. package/src/client/web/CreeveyView/SideBar/TestLink.tsx +8 -3
  191. package/src/client/web/CreeveyView/SideBar/TestStatusIcon.tsx +18 -10
  192. package/src/client/web/CreeveyView/SideBar/TestsStatus.tsx +7 -10
  193. package/src/client/web/CreeveyView/SideBar/Toggle.tsx +1 -2
  194. package/src/client/web/KeyboardEventsContext.tsx +3 -4
  195. package/src/client/web/index.html +1 -1
  196. package/src/client/web/index.tsx +4 -3
  197. package/src/creevey.ts +25 -8
  198. package/src/index.ts +4 -2
  199. package/src/server/config.ts +12 -8
  200. package/src/server/docker.ts +58 -44
  201. package/src/server/index.ts +57 -18
  202. package/src/server/master/master.ts +3 -6
  203. package/src/server/master/pool.ts +20 -7
  204. package/src/server/master/runner.ts +2 -2
  205. package/src/server/master/server.ts +1 -0
  206. package/src/server/master/{index.ts → start.ts} +13 -11
  207. package/src/server/messages.ts +11 -75
  208. package/src/server/playwright/docker-file.ts +21 -0
  209. package/src/server/playwright/docker.ts +41 -0
  210. package/src/server/playwright/internal.ts +387 -0
  211. package/src/server/playwright/webdriver.ts +126 -0
  212. package/src/server/{storybook/providers → providers}/browser.ts +7 -8
  213. package/src/server/{storybook/providers → providers}/hybrid.ts +19 -19
  214. package/src/server/{worker/reporter.ts → reporter.ts} +40 -72
  215. package/src/server/selenium/internal.ts +785 -0
  216. package/src/server/selenium/selenoid.ts +12 -17
  217. package/src/server/selenium/webdriver.ts +136 -0
  218. package/src/server/stories.ts +18 -11
  219. package/src/server/telemetry.ts +2 -2
  220. package/src/server/utils.ts +9 -9
  221. package/src/server/webdriver.ts +127 -0
  222. package/src/server/worker/chai-image.ts +21 -133
  223. package/src/server/worker/match-image.ts +303 -0
  224. package/src/server/worker/start.ts +303 -0
  225. package/src/types.ts +161 -60
  226. package/dist/client/web/202.js +0 -1
  227. package/dist/client/web/270.js +0 -43
  228. package/dist/client/web/752.js +0 -1
  229. package/dist/client/web/main.js +0 -79
  230. package/dist/client/web/main.js.LICENSE.txt +0 -34
  231. package/dist/server/master/index.d.ts +0 -3
  232. package/dist/server/master/index.js.map +0 -1
  233. package/dist/server/selenium/browser.d.ts +0 -19
  234. package/dist/server/selenium/browser.js +0 -640
  235. package/dist/server/selenium/browser.js.map +0 -1
  236. package/dist/server/selenium/index.d.ts +0 -2
  237. package/dist/server/selenium/index.js +0 -19
  238. package/dist/server/selenium/index.js.map +0 -1
  239. package/dist/server/storybook/providers/browser.d.ts +0 -2
  240. package/dist/server/storybook/providers/browser.js.map +0 -1
  241. package/dist/server/storybook/providers/hybrid.d.ts +0 -2
  242. package/dist/server/storybook/providers/hybrid.js.map +0 -1
  243. package/dist/server/worker/helpers.d.ts +0 -8
  244. package/dist/server/worker/helpers.js +0 -57
  245. package/dist/server/worker/helpers.js.map +0 -1
  246. package/dist/server/worker/index.d.ts +0 -1
  247. package/dist/server/worker/index.js +0 -6
  248. package/dist/server/worker/index.js.map +0 -1
  249. package/dist/server/worker/reporter.d.ts +0 -8
  250. package/dist/server/worker/reporter.js.map +0 -1
  251. package/dist/server/worker/worker.d.ts +0 -4
  252. package/dist/server/worker/worker.js +0 -217
  253. package/dist/server/worker/worker.js.map +0 -1
  254. package/src/server/selenium/browser.ts +0 -840
  255. package/src/server/selenium/index.ts +0 -2
  256. package/src/server/worker/helpers.ts +0 -61
  257. package/src/server/worker/index.ts +0 -1
  258. package/src/server/worker/worker.ts +0 -245
  259. package/types/mocha.d.ts +0 -20
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.start = start;
7
+ const chai_1 = __importDefault(require("chai"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const loglevel_1 = __importDefault(require("loglevel"));
10
+ const events_1 = __importDefault(require("events"));
11
+ const selenium_webdriver_1 = require("selenium-webdriver");
12
+ const types_js_1 = require("../../types.js");
13
+ const messages_js_1 = require("../messages.js");
14
+ const chai_image_js_1 = __importDefault(require("./chai-image.js"));
15
+ const webdriver_js_1 = require("../selenium/webdriver.js");
16
+ const match_image_js_1 = require("./match-image.js");
17
+ const stories_js_1 = require("../stories.js");
18
+ const logger_js_1 = require("../logger.js");
19
+ const utils_js_1 = require("../utils.js");
20
+ async function getTestsFromStories(config, browserName, webdriver) {
21
+ const testsById = new Map();
22
+ const tests = await (0, stories_js_1.loadTestsFromStories)([browserName], (listener) => config.storiesProvider(config, listener, webdriver), (testsDiff) => {
23
+ Object.entries(testsDiff).forEach(([id, newTest]) => {
24
+ if (newTest)
25
+ testsById.set(id, newTest);
26
+ else
27
+ testsById.delete(id);
28
+ });
29
+ });
30
+ Object.values(tests)
31
+ .filter(types_js_1.isDefined)
32
+ .forEach((test) => testsById.set(test.id, test));
33
+ return testsById;
34
+ }
35
+ async function outputTraceLogs(browser, test, logger) {
36
+ const output = [];
37
+ const types = await browser.manage().logs().getAvailableLogTypes();
38
+ for (const type of types) {
39
+ const logs = await browser.manage().logs().get(type);
40
+ output.push(logs.map((log) => JSON.stringify(log.toJSON(), null, 2)).join('\n'));
41
+ }
42
+ logger.debug('----------', (0, utils_js_1.getTestPath)(test).join('/'), '----------\n', output.join('\n'), '\n----------------------------------------------------------------------------------------------------');
43
+ }
44
+ function runHandler(browserName, images, error) {
45
+ // TODO How handle browser corruption?
46
+ if ((0, types_js_1.isImageError)(error)) {
47
+ if (typeof error.images == 'string') {
48
+ const image = images[browserName];
49
+ if (image)
50
+ image.error = error.images;
51
+ }
52
+ else {
53
+ const imageErrors = error.images ?? {};
54
+ Object.keys(imageErrors).forEach((imageName) => {
55
+ const image = images[imageName];
56
+ if (image)
57
+ image.error = imageErrors[imageName];
58
+ });
59
+ }
60
+ }
61
+ if (error || Object.values(images).some((image) => image?.error != null)) {
62
+ const errorMessage = serializeError(error);
63
+ const isUnexpectedError = hasTimeout(errorMessage) ||
64
+ hasDisconnected(errorMessage) ||
65
+ Object.values(images).some((image) => hasTimeout(image?.error));
66
+ if (isUnexpectedError)
67
+ (0, messages_js_1.emitWorkerMessage)({ type: 'error', payload: { subtype: 'unknown', error: errorMessage } });
68
+ else
69
+ (0, messages_js_1.emitTestMessage)({
70
+ type: 'end',
71
+ payload: {
72
+ status: 'failed',
73
+ images,
74
+ error: errorMessage,
75
+ },
76
+ });
77
+ }
78
+ else {
79
+ (0, messages_js_1.emitTestMessage)({ type: 'end', payload: { status: 'success', images } });
80
+ }
81
+ }
82
+ async function setupWebdriver(webdriver) {
83
+ if ((await webdriver.openBrowser(true)) == null) {
84
+ logger_js_1.logger.error('Failed to start browser');
85
+ (0, messages_js_1.emitWorkerMessage)({
86
+ type: 'error',
87
+ payload: { subtype: 'browser', error: 'Failed to start browser' },
88
+ });
89
+ return;
90
+ }
91
+ const sessionId = await webdriver.getSessionId();
92
+ return [sessionId, webdriver];
93
+ }
94
+ function serializeError(error) {
95
+ if (!error)
96
+ return 'Unknown error';
97
+ if (error instanceof Error)
98
+ return error.stack ?? error.message;
99
+ return typeof error === 'object' ? JSON.stringify(error) : error;
100
+ }
101
+ function hasDisconnected(str) {
102
+ return str?.toLowerCase().includes('disconnected') ?? false;
103
+ }
104
+ function hasTimeout(str) {
105
+ return str?.toLowerCase().includes('timeout') ?? false;
106
+ }
107
+ async function start(browser, gridUrl, config, options) {
108
+ let retries = 0;
109
+ const imagesContext = {
110
+ attachments: [],
111
+ testFullPath: [],
112
+ images: {},
113
+ };
114
+ const Webdriver = config.webdriver;
115
+ const [sessionId, webdriver] = (await setupWebdriver(new Webdriver(browser, gridUrl, config, options))) ?? [];
116
+ if (!webdriver || !sessionId)
117
+ return;
118
+ const workerLogger = loglevel_1.default.getLogger(`${browser}:${chalk_1.default.gray(sessionId)}`);
119
+ const reporterOptions = {
120
+ ...config.reporterOptions,
121
+ creevey: {
122
+ sessionId,
123
+ reportDir: config.reportDir,
124
+ browserName: browser,
125
+ get willRetry() {
126
+ return retries < config.maxRetries;
127
+ },
128
+ get images() {
129
+ return imagesContext.images;
130
+ },
131
+ },
132
+ };
133
+ class FakeRunner extends events_1.default {
134
+ }
135
+ const runner = new FakeRunner();
136
+ const Reporter = config.reporter;
137
+ new Reporter(runner, { reporterOptions });
138
+ const { matchImage, matchImages } = options.odiff
139
+ ? (0, match_image_js_1.getOdiffMatchers)(imagesContext, config)
140
+ : await (0, match_image_js_1.getMatchers)(imagesContext, config);
141
+ chai_1.default.use((0, chai_image_js_1.default)(matchImage, matchImages, workerLogger));
142
+ const tests = await (async () => {
143
+ try {
144
+ return await getTestsFromStories(config, browser, webdriver);
145
+ }
146
+ catch (error) {
147
+ workerLogger.error('Failed to get tests from stories:', error);
148
+ (0, messages_js_1.emitWorkerMessage)({
149
+ type: 'error',
150
+ payload: { subtype: 'browser', error: serializeError(error) },
151
+ });
152
+ return null;
153
+ }
154
+ })();
155
+ if (!tests)
156
+ return;
157
+ (0, messages_js_1.subscribeOn)('test', (message) => {
158
+ if (message.type != 'start')
159
+ return;
160
+ const test = tests.get(message.payload.id);
161
+ if (!test) {
162
+ const error = `Test with id ${message.payload.id} not found`;
163
+ workerLogger.error(error);
164
+ (0, messages_js_1.emitWorkerMessage)({
165
+ type: 'error',
166
+ payload: { subtype: 'test', error },
167
+ });
168
+ return;
169
+ }
170
+ const baseContext = {
171
+ browserName: browser,
172
+ // TODO Pass browser instance to test
173
+ // browser: browser,
174
+ screenshots: [],
175
+ matchImage: matchImage,
176
+ matchImages: matchImages,
177
+ // NOTE: Deprecated
178
+ expect: chai_1.default.expect,
179
+ //TODO Move things below to the separate module
180
+ until: selenium_webdriver_1.until,
181
+ keys: selenium_webdriver_1.Key,
182
+ };
183
+ imagesContext.attachments = [];
184
+ imagesContext.testFullPath = (0, utils_js_1.getTestPath)(test);
185
+ imagesContext.images = {};
186
+ retries = message.payload.retries;
187
+ let error = undefined;
188
+ const fakeSuite = {
189
+ title: test.storyPath.slice(0, -1).join('/'),
190
+ fullTitle: () => fakeSuite.title,
191
+ titlePath: () => [fakeSuite.title],
192
+ tests: [],
193
+ };
194
+ const fakeTest = {
195
+ parent: fakeSuite,
196
+ title: [test.story.name, test.testName, test.browser].filter(types_js_1.isDefined).join('/'),
197
+ fullTitle: () => (0, utils_js_1.getTestPath)(test).join('/'),
198
+ titlePath: () => (0, utils_js_1.getTestPath)(test),
199
+ currentRetry: () => retries,
200
+ retires: () => config.maxRetries,
201
+ slow: () => 1000,
202
+ };
203
+ fakeSuite.tests.push(fakeTest);
204
+ void (async () => {
205
+ runner.emit(types_js_1.TEST_EVENTS.RUN_BEGIN);
206
+ runner.emit(types_js_1.TEST_EVENTS.TEST_BEGIN, fakeTest);
207
+ const start = Date.now();
208
+ try {
209
+ await Promise.race([
210
+ new Promise((reject) => setTimeout(() => {
211
+ reject(`Timeout of ${config.testTimeout}ms exceeded`);
212
+ }, config.testTimeout)),
213
+ (async () => {
214
+ const context = await webdriver.switchStory(test.story, baseContext, workerLogger);
215
+ await test.fn(context);
216
+ })(),
217
+ ]);
218
+ }
219
+ catch (testError) {
220
+ error = testError;
221
+ fakeTest.err = error;
222
+ }
223
+ const duration = Date.now() - start;
224
+ fakeTest.attachments = imagesContext.attachments;
225
+ fakeTest.state = error ? 'failed' : 'passed';
226
+ fakeTest.duration = duration;
227
+ fakeTest.speed = duration > fakeTest.slow() ? 'slow' : duration / 2 > fakeTest.slow() ? 'medium' : 'fast';
228
+ if (error) {
229
+ runner.emit(types_js_1.TEST_EVENTS.TEST_FAIL, fakeTest, error);
230
+ }
231
+ else {
232
+ runner.emit(types_js_1.TEST_EVENTS.TEST_PASS, fakeTest);
233
+ }
234
+ runner.emit(types_js_1.TEST_EVENTS.TEST_END, fakeTest);
235
+ runner.emit(types_js_1.TEST_EVENTS.RUN_END);
236
+ if (options.trace) {
237
+ try {
238
+ if (webdriver instanceof webdriver_js_1.SeleniumWebdriver && webdriver.browser) {
239
+ await outputTraceLogs(webdriver.browser, test, workerLogger);
240
+ }
241
+ }
242
+ catch (_) {
243
+ /* noop */
244
+ }
245
+ }
246
+ runHandler(baseContext.browserName, imagesContext.images, error);
247
+ })().catch((error) => {
248
+ workerLogger.error('Unexpected error:', error);
249
+ (0, messages_js_1.emitWorkerMessage)({
250
+ type: 'error',
251
+ payload: { subtype: 'test', error: serializeError(error) },
252
+ });
253
+ });
254
+ });
255
+ workerLogger.info('Browser is ready');
256
+ (0, messages_js_1.emitWorkerMessage)({ type: 'ready' });
257
+ }
258
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/server/worker/start.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import type { StoryContextForEnhancers, DecoratorFunction } from '@storybook/csf';
2
2
  import type { IKey } from 'selenium-webdriver/lib/input.js';
3
3
  import type { Worker as ClusterWorker } from 'cluster';
4
- import type { until, WebDriver, WebElementPromise } from 'selenium-webdriver';
4
+ import type { /*Builder,*/ until } from 'selenium-webdriver';
5
5
  import type Pixelmatch from 'pixelmatch';
6
- import type { Context } from 'mocha';
6
+ import type { ODiffOptions } from 'odiff-bin';
7
7
  import type { expect } from 'chai';
8
+ import type EventEmitter from 'events';
9
+ import type Logger from 'loglevel';
8
10
  export type DiffOptions = typeof Pixelmatch extends (x1: any, x2: any, x3: any, x4: any, x5: any, options?: infer T) => void ? T : never;
9
11
  export interface SetStoriesData {
10
12
  v?: number;
@@ -64,18 +66,21 @@ export interface CreeveyStory {
64
66
  [name: string]: unknown;
65
67
  };
66
68
  }
67
- export interface Capabilities {
69
+ export interface BrowserConfigObject {
68
70
  browserName: string;
71
+ /**
72
+ * Browser version. Ignored with Playwright webdriver
73
+ */
69
74
  browserVersion?: string;
70
- platformName?: string;
71
75
  /**
72
- * @deprecated use `browserVersion` instead
76
+ * Operation system name. Ignored with Playwright webdriver
73
77
  */
74
- version?: string;
75
- [prop: string]: unknown;
76
- }
77
- export type BrowserConfig = Capabilities & {
78
+ platformName?: string;
78
79
  limit?: number;
80
+ /**
81
+ * Selenium grid url
82
+ * @default config.gridUrl
83
+ */
79
84
  gridUrl?: string;
80
85
  storybookUrl?: string;
81
86
  /**
@@ -85,7 +90,7 @@ export type BrowserConfig = Capabilities & {
85
90
  _storybookGlobals?: StorybookGlobals;
86
91
  /**
87
92
  * Specify custom docker image. Used only with `useDocker == true`
88
- * @default `selenoid/${browserName}:${browserVersion ?? 'latest'}`
93
+ * @default `selenoid/${browserName}:${browserVersion ?? 'latest'}` or `mcr.microsoft.com/playwright:${playwrightVersion}`
89
94
  */
90
95
  dockerImage?: string;
91
96
  /**
@@ -97,9 +102,18 @@ export type BrowserConfig = Capabilities & {
97
102
  width: number;
98
103
  height: number;
99
104
  };
100
- };
105
+ [name: string]: unknown;
106
+ }
101
107
  export type StorybookGlobals = Record<string, unknown>;
102
- export type Browser = boolean | string | BrowserConfig;
108
+ export type BrowserConfig = boolean | string | BrowserConfigObject;
109
+ export type CreeveyWebdriverConstructor = new (browser: string, gridUrl: string, config: Config, options: Options) => CreeveyWebdriver;
110
+ export interface CreeveyWebdriver {
111
+ getSessionId(): Promise<string>;
112
+ openBrowser(fresh?: boolean): Promise<CreeveyWebdriver | null>;
113
+ closeBrowser(): Promise<void>;
114
+ loadStoriesFromBrowser(): Promise<StoriesRaw>;
115
+ switchStory(story: StoryInput, context: BaseCreeveyTestContext, logger: Logger.Logger): Promise<CreeveyTestContext>;
116
+ }
103
117
  export interface HookConfig {
104
118
  before?: () => unknown;
105
119
  after?: () => unknown;
@@ -112,6 +126,9 @@ export interface DockerAuth {
112
126
  email?: string;
113
127
  serveraddress?: string;
114
128
  }
129
+ export type BaseReporter = new (runner: EventEmitter, options: {
130
+ reporterOptions: any;
131
+ }) => void;
115
132
  export interface Config {
116
133
  /**
117
134
  * Url to Selenium grid hub or standalone selenium.
@@ -137,21 +154,39 @@ export interface Config {
137
154
  * @default path.join(process.cwd(), './report')
138
155
  */
139
156
  reportDir: string;
157
+ /**
158
+ * Specify a custom reporter for test results. Creevey accepts only mocha-like reporters
159
+ * @optional
160
+ */
161
+ reporter: BaseReporter;
162
+ /**
163
+ * Options which are used by reporter
164
+ */
165
+ reporterOptions?: Record<string, any>;
140
166
  /**
141
167
  * How much test would be retried
142
168
  * @default 0
143
169
  */
144
170
  maxRetries: number;
171
+ /**
172
+ * How much time should be spent on each test
173
+ * @default 30000
174
+ */
175
+ testTimeout: number;
145
176
  /**
146
177
  * Define pixelmatch diff options
147
- * @default { threshold: 0, includeAA: true }
178
+ * @default { threshold: 0.05, includeAA: false }
148
179
  */
149
180
  diffOptions: DiffOptions;
181
+ /**
182
+ *
183
+ */
184
+ odiffOptions: ODiffOptions;
150
185
  /**
151
186
  * Browser capabilities
152
187
  * @default { chrome: true }
153
188
  */
154
- browsers: Record<string, Browser>;
189
+ browsers: Record<string, BrowserConfig>;
155
190
  /**
156
191
  * Hooks that allow run custom script before and after creevey start
157
192
  */
@@ -187,9 +222,9 @@ export interface Config {
187
222
  */
188
223
  storiesProvider: StoriesProvider;
189
224
  /**
190
- * Define custom babel options for load stories transformation
225
+ *
191
226
  */
192
- babelOptions: (options: Record<string, unknown>) => Record<string, unknown>;
227
+ webdriver: CreeveyWebdriverConstructor;
193
228
  /**
194
229
  * Allows you to start selenoid without docker
195
230
  * and use standalone browsers
@@ -221,7 +256,6 @@ export interface Config {
221
256
  dockerImagePlatform: string;
222
257
  testsRegex?: RegExp;
223
258
  testsDir?: string;
224
- tsConfig?: string;
225
259
  /**
226
260
  * Telemetry contains information about Creevey and Storybook versions, used Creevey config, browsers and tests meta.
227
261
  * It's being sent only for projects from git.skbkontur.ru
@@ -229,8 +263,8 @@ export interface Config {
229
263
  */
230
264
  disableTelemetry?: boolean;
231
265
  }
232
- export interface StoriesProvider<T = any> {
233
- (config: Config, options: T, storiesListener: (stories: Map<string, StoryInput[]>) => void): Promise<StoriesRaw>;
266
+ export interface StoriesProvider {
267
+ (config: Config, storiesListener: (stories: Map<string, StoryInput[]>) => void, webdriver?: CreeveyWebdriver): Promise<StoriesRaw>;
234
268
  providerName?: string;
235
269
  }
236
270
  export type CreeveyConfig = Partial<Config>;
@@ -242,21 +276,31 @@ export interface Options {
242
276
  update: boolean | string;
243
277
  debug: boolean;
244
278
  trace: boolean;
245
- tests: boolean;
246
279
  browser?: string;
280
+ /**
281
+ * @deprecated use {@link Config.reporter} instead
282
+ */
247
283
  reporter?: string;
248
284
  screenDir?: string;
249
285
  reportDir?: string;
286
+ gridUrl?: string;
250
287
  storybookUrl?: string;
251
- saveReport: boolean;
252
288
  failFast?: boolean;
289
+ odiff?: boolean;
253
290
  }
291
+ export type WorkerError = 'browser' | 'test' | 'unknown';
254
292
  export type WorkerMessage = {
255
293
  type: 'ready';
256
294
  payload?: never;
295
+ } | {
296
+ type: 'port';
297
+ payload: {
298
+ port: number;
299
+ };
257
300
  } | {
258
301
  type: 'error';
259
302
  payload: {
303
+ subtype: WorkerError;
260
304
  error: string;
261
305
  };
262
306
  };
@@ -287,28 +331,6 @@ export type TestMessage = {
287
331
  type: 'end';
288
332
  payload: TestResult;
289
333
  };
290
- export type WebpackMessage = {
291
- type: 'success';
292
- payload?: never;
293
- } | {
294
- type: 'fail';
295
- payload?: never;
296
- } | {
297
- type: 'rebuild succeeded';
298
- payload?: never;
299
- } | {
300
- type: 'rebuild failed';
301
- payload?: never;
302
- };
303
- export type DockerMessage = {
304
- type: 'start';
305
- payload?: never;
306
- } | {
307
- type: 'success';
308
- payload: {
309
- gridUrl: string;
310
- };
311
- };
312
334
  export type ShutdownMessage = object;
313
335
  export type ProcessMessage = (WorkerMessage & {
314
336
  scope: 'worker';
@@ -316,18 +338,12 @@ export type ProcessMessage = (WorkerMessage & {
316
338
  scope: 'stories';
317
339
  }) | (TestMessage & {
318
340
  scope: 'test';
319
- }) | (WebpackMessage & {
320
- scope: 'webpack';
321
- }) | (DockerMessage & {
322
- scope: 'docker';
323
341
  }) | (ShutdownMessage & {
324
342
  scope: 'shutdown';
325
343
  });
326
344
  export type WorkerHandler = (message: WorkerMessage) => void;
327
345
  export type StoriesHandler = (message: StoriesMessage) => void;
328
346
  export type TestHandler = (message: TestMessage) => void;
329
- export type WebpackHandler = (message: WebpackMessage) => void;
330
- export type DockerHandler = (message: DockerMessage) => void;
331
347
  export type ShutdownHandler = (message: ShutdownMessage) => void;
332
348
  export interface Worker extends ClusterWorker {
333
349
  isRunning?: boolean;
@@ -345,8 +361,8 @@ export interface TestResult {
345
361
  images?: Partial<Record<string, Images>>;
346
362
  error?: string;
347
363
  }
348
- export interface ImagesError extends Error {
349
- images: string | Partial<Record<string, string>>;
364
+ export declare class ImagesError extends Error {
365
+ images?: string | Partial<Record<string, string>>;
350
366
  }
351
367
  export interface TestMeta {
352
368
  id: string;
@@ -362,9 +378,66 @@ export interface TestData extends TestMeta {
362
378
  results?: TestResult[];
363
379
  approved?: Partial<Record<string, number>> | null;
364
380
  }
381
+ export interface BaseCreeveyTestContext {
382
+ browserName: string;
383
+ /**
384
+ * @deprecated In near future Creevey will additionally support Playwright as a webdriver, so any Selenium specific things might not be available. Please import `until` explicitly
385
+ */
386
+ until: typeof until;
387
+ /**
388
+ * @deprecated In near future Creevey will additionally support Playwright as a webdriver, so any Selenium specific things might not be available. Please import `keys` explicitly
389
+ */
390
+ keys: IKey;
391
+ /**
392
+ * @deprecated Usually for screenshot testing you don't need other type of assertions except matching images, but if you really need it, please use external `expect` libs
393
+ */
394
+ expect: typeof expect;
395
+ /**
396
+ * @internal
397
+ */
398
+ screenshots: {
399
+ imageName?: string;
400
+ screenshot: Buffer;
401
+ }[];
402
+ matchImage: (image: Buffer, imageName?: string) => Promise<void>;
403
+ matchImages: (images: Record<string, Buffer>) => Promise<void>;
404
+ }
405
+ export interface CreeveyTestContext extends BaseCreeveyTestContext {
406
+ takeScreenshot: () => Promise<Buffer>;
407
+ updateStoryArgs: (updatedArgs: Record<string, unknown>) => Promise<void>;
408
+ captureElement: string | null;
409
+ }
410
+ export declare enum TEST_EVENTS {
411
+ RUN_BEGIN = "start",
412
+ RUN_END = "end",
413
+ TEST_BEGIN = "test",
414
+ TEST_END = "test end",
415
+ TEST_FAIL = "fail",
416
+ TEST_PASS = "pass"
417
+ }
365
418
  export interface ServerTest extends TestData {
366
419
  story: StoryInput;
367
- fn: (this: Context) => Promise<void>;
420
+ fn: CreeveyTestFunction;
421
+ }
422
+ export interface FakeSuite {
423
+ title: string;
424
+ fullTitle: () => string;
425
+ titlePath: () => string[];
426
+ tests: FakeTest[];
427
+ }
428
+ export interface FakeTest {
429
+ parent: FakeSuite;
430
+ title: string;
431
+ fullTitle: () => string;
432
+ titlePath: () => string[];
433
+ currentRetry: () => number;
434
+ retires: () => number;
435
+ slow: () => number;
436
+ duration?: number;
437
+ state?: 'failed' | 'passed';
438
+ speed?: 'slow' | 'medium' | 'fast';
439
+ err?: unknown;
440
+ attachments?: string[];
368
441
  }
369
442
  export interface CreeveyStatus {
370
443
  isRunning: boolean;
@@ -383,16 +456,7 @@ export interface SkipOption {
383
456
  tests?: string | string[] | RegExp;
384
457
  }
385
458
  export type SkipOptions = boolean | string | Record<string, SkipOption | SkipOption[]>;
386
- export interface CreeveyTestController {
387
- browser: WebDriver;
388
- until: typeof until;
389
- keys: IKey;
390
- expect: typeof expect;
391
- takeScreenshot: () => Promise<string>;
392
- updateStoryArgs: (updatedArgs: Record<string, unknown>) => Promise<void>;
393
- readonly captureElement?: WebElementPromise;
394
- }
395
- export type CreeveyTestFunction = (this: CreeveyTestController) => Promise<void>;
459
+ export type CreeveyTestFunction = (context: CreeveyTestContext) => Promise<void>;
396
460
  export interface CaptureOptions {
397
461
  imageName?: string;
398
462
  captureElement?: string | null;
@@ -458,5 +522,3 @@ export declare function isProcessMessage(message: unknown): message is ProcessMe
458
522
  export declare function isWorkerMessage(message: unknown): message is WorkerMessage;
459
523
  export declare function isStoriesMessage(message: unknown): message is StoriesMessage;
460
524
  export declare function isTestMessage(message: unknown): message is TestMessage;
461
- export declare function isWebpackMessage(message: unknown): message is WebpackMessage;
462
- export declare function isDockerMessage(message: unknown): message is DockerMessage;
package/dist/types.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEST_EVENTS = exports.ImagesError = void 0;
3
4
  exports.noop = noop;
4
5
  exports.isDefined = isDefined;
5
6
  exports.isTest = isTest;
@@ -11,8 +12,19 @@ exports.isProcessMessage = isProcessMessage;
11
12
  exports.isWorkerMessage = isWorkerMessage;
12
13
  exports.isStoriesMessage = isStoriesMessage;
13
14
  exports.isTestMessage = isTestMessage;
14
- exports.isWebpackMessage = isWebpackMessage;
15
- exports.isDockerMessage = isDockerMessage;
15
+ class ImagesError extends Error {
16
+ images;
17
+ }
18
+ exports.ImagesError = ImagesError;
19
+ var TEST_EVENTS;
20
+ (function (TEST_EVENTS) {
21
+ TEST_EVENTS["RUN_BEGIN"] = "start";
22
+ TEST_EVENTS["RUN_END"] = "end";
23
+ TEST_EVENTS["TEST_BEGIN"] = "test";
24
+ TEST_EVENTS["TEST_END"] = "test end";
25
+ TEST_EVENTS["TEST_FAIL"] = "fail";
26
+ TEST_EVENTS["TEST_PASS"] = "pass";
27
+ })(TEST_EVENTS || (exports.TEST_EVENTS = TEST_EVENTS = {}));
16
28
  function noop() {
17
29
  /* noop */
18
30
  }
@@ -38,7 +50,7 @@ function isFunction(x) {
38
50
  return typeof x == 'function';
39
51
  }
40
52
  function isImageError(error) {
41
- return error instanceof Error && 'images' in error;
53
+ return error instanceof ImagesError && 'images' in error;
42
54
  }
43
55
  function isProcessMessage(message) {
44
56
  return isObject(message) && 'scope' in message;
@@ -52,10 +64,4 @@ function isStoriesMessage(message) {
52
64
  function isTestMessage(message) {
53
65
  return isProcessMessage(message) && message.scope == 'test';
54
66
  }
55
- function isWebpackMessage(message) {
56
- return isProcessMessage(message) && message.scope == 'webpack';
57
- }
58
- function isDockerMessage(message) {
59
- return isProcessMessage(message) && message.scope == 'docker';
60
- }
61
67
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AA2bA,oBAEC;AAED,8BAEC;AAED,wBASC;AAED,4BAEC;AAED,4BAEC;AAGD,gCAEC;AAED,oCAEC;AAED,4CAEC;AAED,0CAEC;AAED,4CAEC;AAED,sCAEC;AAED,4CAEC;AAED,0CAEC;AA1DD,SAAgB,IAAI;IAClB,UAAU;AACZ,CAAC;AAED,SAAgB,SAAS,CAAI,KAA2B;IACtD,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AAC/C,CAAC;AAED,SAAgB,MAAM,CAAC,CAA8B;IACnD,OAAO,CACL,SAAS,CAAC,CAAC,CAAC;QACZ,QAAQ,CAAC,CAAC,CAAC;QACX,IAAI,IAAI,CAAC;QACT,SAAS,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,EAAE,IAAI,QAAQ;QACvB,OAAO,CAAC,CAAC,OAAO,IAAI,QAAQ,CAC7B,CAAC;AACJ,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAC9B,CAAC;AAED,8DAA8D;AAC9D,SAAgB,UAAU,CAAC,CAAU;IACnC,OAAO,OAAO,CAAC,IAAI,UAAU,CAAC;AAChC,CAAC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,CAAC;AACrD,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC;AACjD,CAAC;AAED,SAAgB,eAAe,CAAC,OAAgB;IAC9C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;AAChE,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;AACjE,CAAC;AAED,SAAgB,aAAa,CAAC,OAAgB;IAC5C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;AAC9D,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;AACjE,CAAC;AAED,SAAgB,eAAe,CAAC,OAAgB;IAC9C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;AAChE,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAwiBA,oBAEC;AAED,8BAEC;AAED,wBASC;AAED,4BAEC;AAED,4BAEC;AAGD,gCAEC;AAED,oCAEC;AAED,4CAEC;AAED,0CAEC;AAED,4CAEC;AAED,sCAEC;AAjND,MAAa,WAAY,SAAQ,KAAK;IACpC,MAAM,CAA4C;CACnD;AAFD,kCAEC;AA8CD,IAAY,WAOX;AAPD,WAAY,WAAW;IACrB,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,iCAAkB,CAAA;IAClB,iCAAkB,CAAA;AACpB,CAAC,EAPW,WAAW,2BAAX,WAAW,QAOtB;AAwGD,SAAgB,IAAI;IAClB,UAAU;AACZ,CAAC;AAED,SAAgB,SAAS,CAAI,KAA2B;IACtD,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AAC/C,CAAC;AAED,SAAgB,MAAM,CAAC,CAA8B;IACnD,OAAO,CACL,SAAS,CAAC,CAAC,CAAC;QACZ,QAAQ,CAAC,CAAC,CAAC;QACX,IAAI,IAAI,CAAC;QACT,SAAS,IAAI,CAAC;QACd,OAAO,CAAC,CAAC,EAAE,IAAI,QAAQ;QACvB,OAAO,CAAC,CAAC,OAAO,IAAI,QAAQ,CAC7B,CAAC;AACJ,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED,SAAgB,QAAQ,CAAC,CAAU;IACjC,OAAO,OAAO,CAAC,IAAI,QAAQ,CAAC;AAC9B,CAAC;AAED,8DAA8D;AAC9D,SAAgB,UAAU,CAAC,CAAU;IACnC,OAAO,OAAO,CAAC,IAAI,UAAU,CAAC;AAChC,CAAC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,WAAW,IAAI,QAAQ,IAAI,KAAK,CAAC;AAC3D,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC;AACjD,CAAC;AAED,SAAgB,eAAe,CAAC,OAAgB;IAC9C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC;AAChE,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC;AACjE,CAAC;AAED,SAAgB,aAAa,CAAC,OAAgB;IAC5C,OAAO,gBAAgB,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;AAC9D,CAAC"}