creevey 0.7.39 → 0.9.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.
- package/CHANGELOG.md +12 -2
- package/README.md +1 -1
- package/docs/config.md +37 -5
- package/docs/grid.md +2 -1
- package/lib/cjs/client/addon/Manager.js +3 -2
- package/lib/cjs/client/addon/preset.js +1 -0
- package/lib/cjs/client/addon/readyForCapture.js +12 -0
- package/lib/cjs/client/addon/utils.js +1 -41
- package/lib/cjs/client/addon/withCreevey.js +313 -41
- package/lib/cjs/client/shared/components/ImagesView/BlendView.js +3 -3
- package/lib/cjs/client/shared/components/ImagesView/SideBySideView.js +3 -3
- package/lib/cjs/client/shared/components/ImagesView/SlideView.js +4 -3
- package/lib/cjs/client/shared/components/ImagesView/SwapView.js +3 -3
- package/lib/cjs/client/shared/helpers.js +1 -1
- package/lib/cjs/client/web/1.js +2 -2
- package/lib/cjs/client/web/2.js +1 -1
- package/lib/cjs/client/web/main.js +6 -6
- package/lib/cjs/index.js +27 -9
- package/lib/cjs/server/config.js +7 -3
- package/lib/cjs/server/extract.js +11 -4
- package/lib/cjs/server/index.js +2 -4
- package/lib/cjs/server/loaders/babel/register.js +2 -1
- package/lib/cjs/server/master/index.js +3 -9
- package/lib/cjs/server/master/master.js +1 -0
- package/lib/cjs/server/master/pool.js +29 -29
- package/lib/cjs/server/master/server.js +75 -3
- package/lib/cjs/server/messages.js +124 -12
- package/lib/cjs/server/parser.js +85 -0
- package/lib/cjs/server/selenium/browser.js +119 -21
- package/lib/cjs/server/selenium/selenoid.js +1 -1
- package/lib/cjs/server/stories.js +49 -58
- package/lib/cjs/server/storybook/entry.js +5 -4
- package/lib/cjs/server/storybook/helpers.js +11 -3
- package/lib/cjs/server/storybook/providers/browser.js +78 -0
- package/lib/cjs/server/storybook/providers/hybrid.js +79 -0
- package/lib/cjs/server/storybook/{nodejs-provider.js → providers/nodejs.js} +42 -18
- package/lib/cjs/server/utils.js +32 -2
- package/lib/cjs/server/worker/helpers.js +2 -6
- package/lib/cjs/server/worker/worker.js +15 -3
- package/lib/cjs/shared.js +107 -0
- package/lib/cjs/types.js +5 -0
- package/lib/esm/client/addon/Manager.js +3 -3
- package/lib/esm/client/addon/preset.js +1 -0
- package/lib/esm/client/addon/readyForCapture.js +5 -0
- package/lib/esm/client/addon/utils.js +1 -33
- package/lib/esm/client/addon/withCreevey.js +303 -41
- package/lib/esm/client/shared/components/ImagesView/BlendView.js +2 -3
- package/lib/esm/client/shared/components/ImagesView/SideBySideView.js +2 -3
- package/lib/esm/client/shared/components/ImagesView/SlideView.js +3 -3
- package/lib/esm/client/shared/components/ImagesView/SwapView.js +2 -3
- package/lib/esm/client/shared/helpers.js +1 -1
- package/lib/esm/index.js +6 -3
- package/lib/esm/server/config.js +7 -5
- package/lib/esm/server/extract.js +8 -4
- package/lib/esm/server/index.js +2 -3
- package/lib/esm/server/loaders/babel/register.js +3 -2
- package/lib/esm/server/master/index.js +4 -10
- package/lib/esm/server/master/master.js +1 -0
- package/lib/esm/server/master/pool.js +31 -31
- package/lib/esm/server/master/server.js +73 -5
- package/lib/esm/server/messages.js +118 -12
- package/lib/esm/server/parser.js +63 -0
- package/lib/esm/server/selenium/browser.js +116 -23
- package/lib/esm/server/selenium/selenoid.js +1 -1
- package/lib/esm/server/stories.js +51 -58
- package/lib/esm/server/storybook/entry.js +4 -4
- package/lib/esm/server/storybook/helpers.js +9 -3
- package/lib/esm/server/storybook/providers/browser.js +61 -0
- package/lib/esm/server/storybook/providers/hybrid.js +63 -0
- package/lib/esm/server/storybook/{nodejs-provider.js → providers/nodejs.js} +40 -18
- package/lib/esm/server/utils.js +29 -2
- package/lib/esm/server/worker/helpers.js +2 -6
- package/lib/esm/server/worker/worker.js +16 -4
- package/lib/esm/shared.js +76 -0
- package/lib/esm/types.js +3 -0
- package/lib/types/client/addon/preset.d.ts +2 -0
- package/lib/types/client/addon/readyForCapture.d.ts +6 -0
- package/lib/types/client/addon/utils.d.ts +1 -5
- package/lib/types/client/addon/withCreevey.d.ts +13 -2
- package/lib/types/client/web/CreeveyView/SideBar/SuiteLink.d.ts +2 -2
- package/lib/types/index.d.ts +2 -1
- package/lib/types/server/config.d.ts +1 -1
- package/lib/types/server/master/master.d.ts +1 -0
- package/lib/types/server/master/pool.d.ts +1 -0
- package/lib/types/server/master/server.d.ts +1 -1
- package/lib/types/server/messages.d.ts +12 -2
- package/lib/types/server/parser.d.ts +12 -0
- package/lib/types/server/selenium/browser.d.ts +5 -2
- package/lib/types/server/stories.d.ts +1 -2
- package/lib/types/server/storybook/entry.d.ts +13 -9
- package/lib/types/server/storybook/helpers.d.ts +1 -0
- package/lib/types/server/storybook/providers/browser.d.ts +4 -0
- package/lib/types/server/storybook/providers/hybrid.d.ts +4 -0
- package/lib/types/server/storybook/providers/nodejs.d.ts +9 -0
- package/lib/types/server/utils.d.ts +2 -0
- package/lib/types/server/worker/helpers.d.ts +2 -1
- package/lib/types/shared.d.ts +16 -0
- package/lib/types/types.d.ts +33 -4
- package/package.json +28 -18
- package/storybook-static/stories.json +4 -513
- package/types/mocha.d.ts +1 -0
- package/lib/types/server/storybook/nodejs-provider.d.ts +0 -5
@@ -3,8 +3,11 @@
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
4
4
|
value: true
|
5
5
|
});
|
6
|
+
exports.takeScreenshot = takeScreenshot;
|
6
7
|
exports.updateStorybookGlobals = updateStorybookGlobals;
|
8
|
+
exports.loadStoriesFromBrowser = loadStoriesFromBrowser;
|
7
9
|
exports.getBrowser = getBrowser;
|
10
|
+
exports.closeBrowser = closeBrowser;
|
8
11
|
exports.switchStory = switchStory;
|
9
12
|
|
10
13
|
var _chalk = _interopRequireDefault(require("chalk"));
|
@@ -39,6 +42,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
39
42
|
|
40
43
|
const DOCKER_INTERNAL = 'host.docker.internal';
|
41
44
|
let browserLogger = _logger.logger;
|
45
|
+
let browserName = '';
|
46
|
+
let browser = null;
|
47
|
+
let creeveyServerHost = null;
|
42
48
|
|
43
49
|
function getSessionData(grid, sessionId = '') {
|
44
50
|
const gridUrl = new URL(grid);
|
@@ -65,9 +71,13 @@ function getSessionData(grid, sessionId = '') {
|
|
65
71
|
}));
|
66
72
|
}
|
67
73
|
|
74
|
+
function getAddresses() {
|
75
|
+
return [DOCKER_INTERNAL].concat(...Object.values((0, _os.networkInterfaces)()).filter(_types.isDefined).map(network => network.filter(info => info.family == 'IPv4').map(info => info.address)));
|
76
|
+
}
|
77
|
+
|
68
78
|
async function resolveStorybookUrl(storybookUrl, checkUrl) {
|
69
79
|
browserLogger.debug('Resolving storybook url');
|
70
|
-
const addresses =
|
80
|
+
const addresses = getAddresses();
|
71
81
|
|
72
82
|
for (const ip of addresses) {
|
73
83
|
const resolvedUrl = storybookUrl.replace(_utils.LOCALHOST_REGEXP, ip);
|
@@ -366,14 +376,16 @@ async function selectStory(browser, {
|
|
366
376
|
name
|
367
377
|
}, waitForReady = false) {
|
368
378
|
browserLogger.debug(`Triggering 'SetCurrentStory' event with storyId ${_chalk.default.magenta(id)}`);
|
369
|
-
const
|
379
|
+
const result = await browser.executeAsyncScript(function (id, kind, name, shouldWaitForReady, callback) {
|
370
380
|
if (typeof window.__CREEVEY_SELECT_STORY__ == 'undefined') {
|
371
|
-
return callback("Creevey can't switch story. This may happened if forget to add `creevey` addon to your storybook config, or storybook not loaded in browser due syntax error.");
|
381
|
+
return callback(["Creevey can't switch story. This may happened if forget to add `creevey` addon to your storybook config, or storybook not loaded in browser due syntax error."]);
|
372
382
|
}
|
373
383
|
|
374
384
|
window.__CREEVEY_SELECT_STORY__(id, kind, name, shouldWaitForReady, callback);
|
375
385
|
}, id, kind, name, waitForReady);
|
386
|
+
const [errorMessage, isCaptureCalled = false] = result || [];
|
376
387
|
if (errorMessage) throw new Error(errorMessage);
|
388
|
+
return isCaptureCalled;
|
377
389
|
}
|
378
390
|
|
379
391
|
async function updateStorybookGlobals(browser, globals) {
|
@@ -413,7 +425,48 @@ async function openStorybookPage(browser, storybookUrl, resolver) {
|
|
413
425
|
}
|
414
426
|
}
|
415
427
|
|
416
|
-
async function
|
428
|
+
async function resolveCreeveyHost(browser, port) {
|
429
|
+
if (creeveyServerHost != null) return creeveyServerHost;
|
430
|
+
const addresses = getAddresses();
|
431
|
+
creeveyServerHost = await browser.executeAsyncScript(function (hosts, port, callback) {
|
432
|
+
void Promise.all(hosts.map(function (host) {
|
433
|
+
return new Promise(function (resolve, reject) {
|
434
|
+
setTimeout(reject, 10000); // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
435
|
+
|
436
|
+
fetch('http://' + host + ':' + port + '/ping').then(resolve).catch(reject);
|
437
|
+
}).then(function (response) {
|
438
|
+
return response.text();
|
439
|
+
}).then(function (pong) {
|
440
|
+
return pong == 'pong' ? host : null;
|
441
|
+
}).catch(function () {
|
442
|
+
return null;
|
443
|
+
});
|
444
|
+
})).then(function (hosts) {
|
445
|
+
callback(hosts.find(function (host) {
|
446
|
+
return host != null;
|
447
|
+
}));
|
448
|
+
});
|
449
|
+
}, addresses, port);
|
450
|
+
if (creeveyServerHost == null) throw new Error("Can't reach creevey server from a browser");
|
451
|
+
return creeveyServerHost;
|
452
|
+
}
|
453
|
+
|
454
|
+
async function loadStoriesFromBrowser(port) {
|
455
|
+
if (!browser) throw new Error("Can't get stories from browser if webdriver isn't connected");
|
456
|
+
const host = await resolveCreeveyHost(browser, port);
|
457
|
+
const stories = await browser.executeAsyncScript(function (creeveyHost, creeveyPort, callback) {
|
458
|
+
window.__CREEVEY_SERVER_HOST__ = creeveyHost;
|
459
|
+
window.__CREEVEY_SERVER_PORT__ = creeveyPort;
|
460
|
+
void window.__CREEVEY_GET_STORIES__().then(callback);
|
461
|
+
}, host, port);
|
462
|
+
if (!stories) throw new Error("Can't get stories, it seems creevey or storybook API isn't available");
|
463
|
+
return stories;
|
464
|
+
}
|
465
|
+
|
466
|
+
async function getBrowser(config, name) {
|
467
|
+
if (browser) return browser;
|
468
|
+
browserName = name;
|
469
|
+
const browserConfig = config.browsers[browserName];
|
417
470
|
const {
|
418
471
|
gridUrl = config.gridUrl,
|
419
472
|
storybookUrl: address = config.storybookUrl,
|
@@ -423,14 +476,11 @@ async function getBrowser(config, browserConfig) {
|
|
423
476
|
...userCapabilities
|
424
477
|
} = browserConfig;
|
425
478
|
void limit;
|
426
|
-
const
|
427
|
-
browserName
|
428
|
-
} = userCapabilities;
|
429
|
-
const realAddress = address;
|
430
|
-
let browser = null; // TODO Define some capabilities explicitly and define typings
|
479
|
+
const realAddress = address; // TODO Define some capabilities explicitly and define typings
|
431
480
|
|
432
|
-
const capabilities = new _seleniumWebdriver.Capabilities(userCapabilities
|
433
|
-
|
481
|
+
const capabilities = new _seleniumWebdriver.Capabilities({ ...userCapabilities,
|
482
|
+
pageLoadStrategy: _capabilities.PageLoadStrategy.NONE
|
483
|
+
});
|
434
484
|
(0, _messages.subscribeOn)('shutdown', () => {
|
435
485
|
var _browser;
|
436
486
|
|
@@ -445,7 +495,7 @@ async function getBrowser(config, browserConfig) {
|
|
445
495
|
const url = new URL(gridUrl);
|
446
496
|
url.username = url.username ? '********' : '';
|
447
497
|
url.password = url.password ? '********' : '';
|
448
|
-
browserLogger.debug(`(${
|
498
|
+
browserLogger.debug(`(${name}) Connecting to Selenium ${_chalk.default.magenta(url.toString())}`);
|
449
499
|
browser = await new _seleniumWebdriver.Builder().usingServer(gridUrl).withCapabilities(capabilities).build();
|
450
500
|
const sessionId = (_await$browser$getSes = await browser.getSession()) === null || _await$browser$getSes === void 0 ? void 0 : _await$browser$getSes.getId();
|
451
501
|
let browserHost = '';
|
@@ -459,14 +509,14 @@ async function getBrowser(config, browserConfig) {
|
|
459
509
|
/* noop */
|
460
510
|
}
|
461
511
|
|
462
|
-
browserLogger.debug(`(${
|
512
|
+
browserLogger.debug(`(${name}) Connected successful with ${[_chalk.default.green(browserHost), _chalk.default.magenta(sessionId)].filter(Boolean).join(':')}`);
|
463
513
|
browserLogger = (0, _loglevel.getLogger)(sessionId);
|
464
514
|
|
465
515
|
_loglevelPluginPrefix.default.apply(browserLogger, {
|
466
516
|
format(level) {
|
467
517
|
const levelColor = _logger.colors[level.toUpperCase()];
|
468
518
|
|
469
|
-
return `[${
|
519
|
+
return `[${name}:${_chalk.default.gray(sessionId)}] ${levelColor(level)} =>`;
|
470
520
|
}
|
471
521
|
|
472
522
|
});
|
@@ -486,6 +536,7 @@ async function getBrowser(config, browserConfig) {
|
|
486
536
|
var _browser3;
|
487
537
|
|
488
538
|
(_browser3 = browser) === null || _browser3 === void 0 ? void 0 : _browser3.quit().catch(_types.noop);
|
539
|
+
browser = null;
|
489
540
|
return null;
|
490
541
|
}
|
491
542
|
|
@@ -499,6 +550,9 @@ async function getBrowser(config, browserConfig) {
|
|
499
550
|
await updateStorybookGlobals(browser, _storybookGlobals);
|
500
551
|
}
|
501
552
|
|
553
|
+
await browser.executeScript(function (workerId) {
|
554
|
+
window.__CREEVEY_WORKER_ID__ = workerId;
|
555
|
+
}, process.pid);
|
502
556
|
return browser;
|
503
557
|
}
|
504
558
|
|
@@ -514,12 +568,23 @@ async function updateStoryArgs(browser, story, updatedArgs) {
|
|
514
568
|
}, story.id, updatedArgs, Events.UPDATE_STORY_ARGS, Events.STORY_RENDERED);
|
515
569
|
}
|
516
570
|
|
571
|
+
async function closeBrowser() {
|
572
|
+
if (!browser) return;
|
573
|
+
|
574
|
+
try {
|
575
|
+
await browser.quit();
|
576
|
+
} finally {
|
577
|
+
browser = null;
|
578
|
+
}
|
579
|
+
}
|
580
|
+
|
517
581
|
async function switchStory() {
|
518
582
|
var _this$currentTest, _this$currentTest$ctx, _parameters$creevey;
|
519
583
|
|
520
584
|
let testOrSuite = this.currentTest;
|
521
585
|
if (!testOrSuite) throw new Error("Can't switch story, because test context doesn't have 'currentTest' field");
|
522
586
|
this.testScope.length = 0;
|
587
|
+
this.screenshots.length = 0;
|
523
588
|
this.testScope.push(this.browserName);
|
524
589
|
|
525
590
|
while ((_testOrSuite = testOrSuite) !== null && _testOrSuite !== void 0 && _testOrSuite.title) {
|
@@ -543,13 +608,6 @@ async function switchStory() {
|
|
543
608
|
ignoreElements
|
544
609
|
} = (_parameters$creevey = parameters.creevey) !== null && _parameters$creevey !== void 0 ? _parameters$creevey : {};
|
545
610
|
browserLogger.debug(`Switching to story ${_chalk.default.cyan(kind)}/${_chalk.default.cyan(name)} by id ${_chalk.default.magenta(id)}`);
|
546
|
-
await resetMousePosition(this.browser);
|
547
|
-
await selectStory(this.browser, {
|
548
|
-
id,
|
549
|
-
kind,
|
550
|
-
name
|
551
|
-
}, waitForReady);
|
552
|
-
browserLogger.debug(`Story ${_chalk.default.magenta(id)} ready for capturing`);
|
553
611
|
if (captureElement) Object.defineProperty(this, 'captureElement', {
|
554
612
|
enumerable: true,
|
555
613
|
configurable: true,
|
@@ -561,6 +619,46 @@ async function switchStory() {
|
|
561
619
|
this.updateStoryArgs = updatedArgs => updateStoryArgs(this.browser, story, updatedArgs);
|
562
620
|
|
563
621
|
this.testScope.reverse();
|
622
|
+
let storyPlayResolver;
|
623
|
+
let waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
|
624
|
+
const unsubscribe = (0, _messages.subscribeOn)('stories', message => {
|
625
|
+
var _payload$captureEleme, _payload$ignoreElemen;
|
626
|
+
|
627
|
+
if (message.type != 'capture') return;
|
628
|
+
const {
|
629
|
+
payload = {},
|
630
|
+
payload: {
|
631
|
+
imageName
|
632
|
+
} = {}
|
633
|
+
} = message;
|
634
|
+
void takeScreenshot(this.browser, (_payload$captureEleme = payload.captureElement) !== null && _payload$captureEleme !== void 0 ? _payload$captureEleme : captureElement, (_payload$ignoreElemen = payload.ignoreElements) !== null && _payload$ignoreElemen !== void 0 ? _payload$ignoreElemen : ignoreElements).then(screenshot => {
|
635
|
+
this.screenshots.push({
|
636
|
+
imageName,
|
637
|
+
screenshot
|
638
|
+
});
|
639
|
+
void this.browser.executeAsyncScript(function (callback) {
|
640
|
+
window.__CREEVEY_HAS_PLAY_COMPLETED_YET__(callback);
|
641
|
+
}).then(isCompleted => storyPlayResolver(isCompleted));
|
642
|
+
(0, _messages.emitStoriesMessage)({
|
643
|
+
type: 'capture'
|
644
|
+
});
|
645
|
+
});
|
646
|
+
});
|
647
|
+
await resetMousePosition(this.browser);
|
648
|
+
const isCaptureCalled = await selectStory(this.browser, {
|
649
|
+
id,
|
650
|
+
kind,
|
651
|
+
name
|
652
|
+
}, waitForReady);
|
653
|
+
|
654
|
+
if (isCaptureCalled) {
|
655
|
+
while (!(await waitForComplete)) {
|
656
|
+
waitForComplete = new Promise(resolve => storyPlayResolver = resolve);
|
657
|
+
}
|
658
|
+
}
|
659
|
+
|
660
|
+
unsubscribe();
|
661
|
+
browserLogger.debug(`Story ${_chalk.default.magenta(id)} ready for capturing`);
|
564
662
|
}
|
565
663
|
|
566
664
|
async function insertIgnoreStyles(browser, ignoreElements) {
|
@@ -51,7 +51,7 @@ async function createSelenoidConfig(browsers, {
|
|
51
51
|
selenoidConfig[browserName].versions[version] = {
|
52
52
|
image: useDocker ? dockerImage : webdriverCommand,
|
53
53
|
port: '4444',
|
54
|
-
path: !useDocker || ['chrome', 'opera', 'webkit'].includes(browserName) ? '/' : '/wd/hub'
|
54
|
+
path: !useDocker || ['chrome', 'opera', 'webkit', 'MicrosoftEdge'].includes(browserName) ? '/' : '/wd/hub'
|
55
55
|
};
|
56
56
|
});
|
57
57
|
await mkdirAsync(selenoidConfigDir, {
|
@@ -3,7 +3,6 @@
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
4
4
|
value: true
|
5
5
|
});
|
6
|
-
exports.flatStories = flatStories;
|
7
6
|
exports.loadTestsFromStories = loadTestsFromStories;
|
8
7
|
exports.saveStoriesJson = saveStoriesJson;
|
9
8
|
exports.saveTestsJson = saveTestsJson;
|
@@ -29,7 +28,12 @@ function storyTestFabric(delay, testFn) {
|
|
29
28
|
var _testFn$call;
|
30
29
|
|
31
30
|
delay ? await new Promise(resolve => setTimeout(resolve, delay)) : void 0;
|
32
|
-
await ((_testFn$call = testFn === null || testFn === void 0 ? void 0 : testFn.call(this)) !== null && _testFn$call !== void 0 ? _testFn$call : this.
|
31
|
+
await ((_testFn$call = testFn === null || testFn === void 0 ? void 0 : testFn.call(this)) !== null && _testFn$call !== void 0 ? _testFn$call : this.screenshots.length > 0 ? this.expect(this.screenshots.reduce((screenshots, {
|
32
|
+
imageName,
|
33
|
+
screenshot
|
34
|
+
}, index) => ({ ...screenshots,
|
35
|
+
[imageName !== null && imageName !== void 0 ? imageName : `screenshot_${index}`]: screenshot
|
36
|
+
}), {})).to.matchImages() : this.expect(await this.takeScreenshot()).to.matchImage());
|
33
37
|
};
|
34
38
|
}
|
35
39
|
|
@@ -55,78 +59,65 @@ function createCreeveyTest(browser, storyMeta, skipOptions, testName) {
|
|
55
59
|
};
|
56
60
|
}
|
57
61
|
|
58
|
-
function convertStories(
|
62
|
+
function convertStories(browserName, stories) {
|
59
63
|
const tests = {};
|
60
64
|
(Array.isArray(stories) ? stories : Object.values(stories)).forEach(storyMeta => {
|
65
|
+
var _storyMeta$parameters;
|
66
|
+
|
61
67
|
// TODO Skip docsOnly stories for now
|
62
68
|
if (storyMeta.parameters.docsOnly) return;
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
};
|
83
|
-
return;
|
84
|
-
}
|
69
|
+
const {
|
70
|
+
delay: delayParam,
|
71
|
+
tests: storyTests,
|
72
|
+
skip
|
73
|
+
} = (_storyMeta$parameters = storyMeta.parameters.creevey) !== null && _storyMeta$parameters !== void 0 ? _storyMeta$parameters : {};
|
74
|
+
const delay = typeof delayParam == 'number' ? delayParam : delayParam !== null && delayParam !== void 0 && delayParam.for.includes(browserName) ? delayParam.ms : 0; // typeof tests === "undefined" => rootSuite -> kindSuite -> storyTest -> [browsers.png]
|
75
|
+
// typeof tests === "function" => rootSuite -> kindSuite -> storyTest -> browser -> [images.png]
|
76
|
+
// typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> [browsers.png]
|
77
|
+
// typeof tests === "object" => rootSuite -> kindSuite -> storySuite -> test -> browser -> [images.png]
|
78
|
+
|
79
|
+
if (!storyTests) {
|
80
|
+
const test = createCreeveyTest(browserName, storyMeta, skip);
|
81
|
+
tests[test.id] = { ...test,
|
82
|
+
storyId: storyMeta.id,
|
83
|
+
story: storyMeta,
|
84
|
+
fn: storyTestFabric(delay)
|
85
|
+
};
|
86
|
+
return;
|
87
|
+
}
|
85
88
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
});
|
89
|
+
Object.entries(storyTests).forEach(([testName, testFn]) => {
|
90
|
+
const test = createCreeveyTest(browserName, storyMeta, skip, testName);
|
91
|
+
tests[test.id] = { ...test,
|
92
|
+
storyId: storyMeta.id,
|
93
|
+
story: storyMeta,
|
94
|
+
fn: storyTestFabric(delay, testFn)
|
95
|
+
};
|
94
96
|
});
|
95
97
|
});
|
96
98
|
return tests;
|
97
|
-
} // TODO use the storybook version, after the fix of skip option API
|
98
|
-
|
99
|
-
|
100
|
-
function flatStories({
|
101
|
-
globalParameters,
|
102
|
-
kindParameters,
|
103
|
-
stories
|
104
|
-
}) {
|
105
|
-
Object.values(stories).forEach(story => {
|
106
|
-
// NOTE: Copy-paste merge parameters from storybook
|
107
|
-
story.parameters = (0, _lodash.mergeWith)({}, globalParameters, kindParameters[story.kind], story.parameters, (objValue, srcValue) => Array.isArray(objValue) ? objValue.concat(srcValue) : undefined);
|
108
|
-
});
|
109
|
-
return stories;
|
110
99
|
}
|
111
100
|
|
112
101
|
async function loadTestsFromStories(browsers, provider, update) {
|
113
102
|
const testIdsByFiles = new Map();
|
114
|
-
const
|
103
|
+
const stories = await provider(storiesByFiles => {
|
115
104
|
const testsDiff = {};
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
105
|
+
const tests = {};
|
106
|
+
browsers.forEach(browser => {
|
107
|
+
Array.from(storiesByFiles.entries()).forEach(([filename, stories]) => {
|
108
|
+
var _testIdsByFiles$get$f, _testIdsByFiles$get;
|
109
|
+
|
110
|
+
Object.assign(tests, convertStories(browser, stories));
|
111
|
+
const changed = Object.keys(tests);
|
112
|
+
const removed = (_testIdsByFiles$get$f = (_testIdsByFiles$get = testIdsByFiles.get(filename)) === null || _testIdsByFiles$get === void 0 ? void 0 : _testIdsByFiles$get.filter(testId => !tests[testId])) !== null && _testIdsByFiles$get$f !== void 0 ? _testIdsByFiles$get$f : [];
|
113
|
+
if (changed.length == 0) testIdsByFiles.delete(filename);else testIdsByFiles.set(filename, changed);
|
114
|
+
Object.assign(testsDiff, tests);
|
115
|
+
removed.forEach(testId => testsDiff[testId] = undefined);
|
116
|
+
});
|
125
117
|
});
|
126
118
|
update === null || update === void 0 ? void 0 : update(testsDiff);
|
127
119
|
});
|
128
|
-
const
|
129
|
-
const tests = convertStories(browsers, stories);
|
120
|
+
const tests = browsers.reduce((tests, browser) => Object.assign(tests, convertStories(browser, stories)), {});
|
130
121
|
Object.values(tests).filter(_types.isDefined).forEach(({
|
131
122
|
id,
|
132
123
|
story: {
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
});
|
6
6
|
exports.raw = exports.getStorybook = exports.setAddon = exports.clearDecorators = exports.addParameters = exports.addDecorator = exports.configure = exports.storiesOf = exports.forceReRender = exports.clientApi = exports.channel = void 0;
|
7
7
|
|
8
|
+
var _addons = require("@storybook/addons");
|
9
|
+
|
8
10
|
var _helpers = require("./helpers");
|
9
11
|
|
10
12
|
var _api$channel, _api$context;
|
@@ -16,10 +18,8 @@ const core = require((0, _helpers.resolveFromStorybook)('@storybook/core')); //@
|
|
16
18
|
|
17
19
|
|
18
20
|
const start = (0, _helpers.isStorybookVersionLessThan)(6, 2) ? core.default.start : core.start;
|
19
|
-
const api = start(() => void 0);
|
20
|
-
|
21
|
-
|
22
|
-
const channel = (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel;
|
21
|
+
const api = start(() => void 0);
|
22
|
+
const channel = (0, _helpers.isStorybookVersionLessThan)(6, 4) ? (_api$channel = api.channel) !== null && _api$channel !== void 0 ? _api$channel : (_api$context = api.context) === null || _api$context === void 0 ? void 0 : _api$context.channel : _addons.addons.getChannel();
|
23
23
|
exports.channel = channel;
|
24
24
|
const clientApi = api.clientApi;
|
25
25
|
exports.clientApi = clientApi;
|
@@ -38,6 +38,7 @@ const configure = (...args) => {
|
|
38
38
|
if ((0, _helpers.isStorybookVersionLessThan)(5, 2)) {
|
39
39
|
//NOTE: Storybook <= 5.1 pass args as is
|
40
40
|
//@ts-expect-error: ignore it
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
41
42
|
return api.configApi.configure(...args);
|
42
43
|
}
|
43
44
|
|
@@ -7,6 +7,7 @@ exports.hasDocsAddon = hasDocsAddon;
|
|
7
7
|
exports.hasSvelteCSFAddon = hasSvelteCSFAddon;
|
8
8
|
exports.getStorybookVersion = getStorybookVersion;
|
9
9
|
exports.isStorybookVersionLessThan = isStorybookVersionLessThan;
|
10
|
+
exports.isStorybookVersionGreaterThan = isStorybookVersionGreaterThan;
|
10
11
|
exports.isStorybookVersion = isStorybookVersion;
|
11
12
|
exports.getStorybookFramework = getStorybookFramework;
|
12
13
|
exports.importStorybookConfig = importStorybookConfig;
|
@@ -97,17 +98,24 @@ function isStorybookVersionLessThan(major, minor) {
|
|
97
98
|
return Number(sbMajor) < major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) < minor;
|
98
99
|
}
|
99
100
|
|
100
|
-
function
|
101
|
+
function isStorybookVersionGreaterThan(major, minor) {
|
101
102
|
var _process$env$__CREEVE2;
|
102
103
|
|
103
104
|
const [sbMajor, sbMinor] = ((_process$env$__CREEVE2 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE2 !== void 0 ? _process$env$__CREEVE2 : getStorybookVersion()).split('.');
|
105
|
+
return Number(sbMajor) > major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) > minor;
|
106
|
+
}
|
107
|
+
|
108
|
+
function isStorybookVersion(major, minor) {
|
109
|
+
var _process$env$__CREEVE3;
|
110
|
+
|
111
|
+
const [sbMajor, sbMinor] = ((_process$env$__CREEVE3 = process.env.__CREEVEY_STORYBOOK_VERSION__) !== null && _process$env$__CREEVE3 !== void 0 ? _process$env$__CREEVE3 : getStorybookVersion()).split('.');
|
104
112
|
return Number(sbMajor) == major || minor != undefined && Number(sbMajor) == major && Number(sbMinor) == minor;
|
105
113
|
}
|
106
114
|
|
107
115
|
function getStorybookFramework() {
|
108
|
-
var _process$env$
|
116
|
+
var _process$env$__CREEVE4;
|
109
117
|
|
110
|
-
const framework = (_process$env$
|
118
|
+
const framework = (_process$env$__CREEVE4 = process.env.__CREEVEY_STORYBOOK_FRAMEWORK__) !== null && _process$env$__CREEVE4 !== void 0 ? _process$env$__CREEVE4 : supportedFrameworks.find(framework => {
|
111
119
|
try {
|
112
120
|
return require.resolve(resolveFromStorybook(`@storybook/${framework}`));
|
113
121
|
} catch (_) {
|
@@ -0,0 +1,78 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.loadStories = loadStories;
|
7
|
+
|
8
|
+
var _cluster = _interopRequireWildcard(require("cluster"));
|
9
|
+
|
10
|
+
var _selenium = require("../../selenium");
|
11
|
+
|
12
|
+
var _messages = require("../../messages");
|
13
|
+
|
14
|
+
var _shared = require("../../../shared");
|
15
|
+
|
16
|
+
var _types = require("../../../types");
|
17
|
+
|
18
|
+
var _logger = require("../../logger");
|
19
|
+
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
21
|
+
|
22
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
23
|
+
|
24
|
+
async function loadStories(_config, {
|
25
|
+
port
|
26
|
+
}, storiesListener) {
|
27
|
+
if (_cluster.isMaster) {
|
28
|
+
return new Promise(resolve => {
|
29
|
+
const worker = Object.values(_cluster.default.workers).filter(_types.isDefined).find(worker => worker.isConnected());
|
30
|
+
|
31
|
+
if (worker) {
|
32
|
+
const unsubscribe = (0, _messages.subscribeOnWorker)(worker, 'stories', message => {
|
33
|
+
if (message.type == 'set') {
|
34
|
+
const {
|
35
|
+
stories,
|
36
|
+
oldTests
|
37
|
+
} = message.payload;
|
38
|
+
if (oldTests.length > 0) _logger.logger.warn(`If you use browser stories provider of CSFv3 Storybook feature\n` + `Creevey will not load tests defined in story parameters from following stories:\n` + oldTests.join('\n'));
|
39
|
+
unsubscribe();
|
40
|
+
resolve(stories);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
(0, _messages.sendStoriesMessage)(worker, {
|
44
|
+
type: 'get'
|
45
|
+
});
|
46
|
+
}
|
47
|
+
|
48
|
+
(0, _messages.subscribeOn)('stories', message => {
|
49
|
+
// TODO updates only one browser :(
|
50
|
+
if (message.type == 'update') storiesListener(new Map(message.payload));
|
51
|
+
});
|
52
|
+
});
|
53
|
+
} else {
|
54
|
+
(0, _messages.subscribeOn)('stories', message => {
|
55
|
+
if (message.type == 'get') (0, _messages.emitStoriesMessage)({
|
56
|
+
type: 'set',
|
57
|
+
payload: {
|
58
|
+
stories,
|
59
|
+
oldTests: storiesWithOldTests
|
60
|
+
}
|
61
|
+
});
|
62
|
+
if (message.type == 'update') storiesListener(new Map(message.payload));
|
63
|
+
});
|
64
|
+
const stories = (0, _shared.deserializeRawStories)(await (0, _selenium.loadStoriesFromBrowser)(port));
|
65
|
+
const storiesWithOldTests = [];
|
66
|
+
Object.values(stories).forEach(story => {
|
67
|
+
var _parameters, _parameters$creevey;
|
68
|
+
|
69
|
+
if ((_parameters = story.parameters) !== null && _parameters !== void 0 && (_parameters$creevey = _parameters.creevey) !== null && _parameters$creevey !== void 0 && _parameters$creevey.tests) {
|
70
|
+
var _parameters2, _parameters2$creevey;
|
71
|
+
|
72
|
+
(_parameters2 = story.parameters) === null || _parameters2 === void 0 ? true : (_parameters2$creevey = _parameters2.creevey) === null || _parameters2$creevey === void 0 ? true : delete _parameters2$creevey.tests;
|
73
|
+
storiesWithOldTests.push(`${story.kind}/${story.name}`);
|
74
|
+
}
|
75
|
+
});
|
76
|
+
return stories;
|
77
|
+
}
|
78
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.loadStories = loadStories;
|
7
|
+
|
8
|
+
var _chokidar = _interopRequireDefault(require("chokidar"));
|
9
|
+
|
10
|
+
var _browser = require("./browser");
|
11
|
+
|
12
|
+
var _logger = require("../../logger");
|
13
|
+
|
14
|
+
var _parser = _interopRequireDefault(require("../../parser"));
|
15
|
+
|
16
|
+
var _utils = require("../../../server/utils");
|
17
|
+
|
18
|
+
var _shared = require("../../../shared");
|
19
|
+
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21
|
+
|
22
|
+
async function loadStories(_config, {
|
23
|
+
port
|
24
|
+
}, storiesListener) {
|
25
|
+
let creeveyParamsByStoryId = {};
|
26
|
+
|
27
|
+
const mergeParamsFromTestsToStory = (story, creeveyParams) => {
|
28
|
+
if (story.parameters) {
|
29
|
+
story.parameters.creevey = (0, _shared.combineParameters)(story.parameters.creevey || {}, creeveyParams);
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
const stories = await (0, _browser.loadStories)(_config, {
|
34
|
+
port
|
35
|
+
}, updatedStoriesByFiles => {
|
36
|
+
Array.from(updatedStoriesByFiles.entries()).forEach(([, storiesArray]) => {
|
37
|
+
storiesArray.forEach(story => {
|
38
|
+
const creeveyParams = creeveyParamsByStoryId[story.id];
|
39
|
+
|
40
|
+
if (creeveyParams) {
|
41
|
+
mergeParamsFromTestsToStory(story, creeveyParams);
|
42
|
+
}
|
43
|
+
});
|
44
|
+
});
|
45
|
+
storiesListener(updatedStoriesByFiles);
|
46
|
+
}); // TODO fix test files hot reloading
|
47
|
+
|
48
|
+
creeveyParamsByStoryId = await parseParams(_config
|
49
|
+
/*, (data) => console.log(data) */
|
50
|
+
);
|
51
|
+
Object.entries(stories).forEach(([storyId, story]) => {
|
52
|
+
mergeParamsFromTestsToStory(story, creeveyParamsByStoryId[storyId]);
|
53
|
+
});
|
54
|
+
return stories;
|
55
|
+
}
|
56
|
+
|
57
|
+
function parseParams(config, listener) {
|
58
|
+
if (!config.testDir) {
|
59
|
+
return Promise.resolve({});
|
60
|
+
}
|
61
|
+
|
62
|
+
const testFiles = (0, _utils.readDirRecursive)(config.testDir).filter(file => {
|
63
|
+
var _config$testRegex;
|
64
|
+
|
65
|
+
return (_config$testRegex = config.testRegex) === null || _config$testRegex === void 0 ? void 0 : _config$testRegex.test(file);
|
66
|
+
});
|
67
|
+
|
68
|
+
if (listener) {
|
69
|
+
_chokidar.default.watch(testFiles).on('change', filePath => {
|
70
|
+
_logger.logger.debug(`changed: ${filePath}`); // doesn't work, always returns {} due modules caching
|
71
|
+
// see https://github.com/nodejs/modules/issues/307
|
72
|
+
|
73
|
+
|
74
|
+
void (0, _parser.default)(testFiles).then(data => listener(data));
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
78
|
+
return (0, _parser.default)(testFiles);
|
79
|
+
}
|