UNPKG

62.4 kBJavaScriptView Raw
1module.exports =
2/******/ (function(modules) { // webpackBootstrap
3/******/ // The module cache
4/******/ var installedModules = {};
5/******/
6/******/ // The require function
7/******/ function __webpack_require__(moduleId) {
8/******/
9/******/ // Check if module is in cache
10/******/ if(installedModules[moduleId]) {
11/******/ return installedModules[moduleId].exports;
12/******/ }
13/******/ // Create a new module (and put it into the cache)
14/******/ var module = installedModules[moduleId] = {
15/******/ i: moduleId,
16/******/ l: false,
17/******/ exports: {}
18/******/ };
19/******/
20/******/ // Execute the module function
21/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22/******/
23/******/ // Flag the module as loaded
24/******/ module.l = true;
25/******/
26/******/ // Return the exports of the module
27/******/ return module.exports;
28/******/ }
29/******/
30/******/
31/******/ // expose the modules object (__webpack_modules__)
32/******/ __webpack_require__.m = modules;
33/******/
34/******/ // expose the module cache
35/******/ __webpack_require__.c = installedModules;
36/******/
37/******/ // identity function for calling harmony imports with the correct context
38/******/ __webpack_require__.i = function(value) { return value; };
39/******/
40/******/ // define getter function for harmony exports
41/******/ __webpack_require__.d = function(exports, name, getter) {
42/******/ if(!__webpack_require__.o(exports, name)) {
43/******/ Object.defineProperty(exports, name, {
44/******/ configurable: false,
45/******/ enumerable: true,
46/******/ get: getter
47/******/ });
48/******/ }
49/******/ };
50/******/
51/******/ // getDefaultExport function for compatibility with non-harmony modules
52/******/ __webpack_require__.n = function(module) {
53/******/ var getter = module && module.__esModule ?
54/******/ function getDefault() { return module['default']; } :
55/******/ function getModuleExports() { return module; };
56/******/ __webpack_require__.d(getter, 'a', getter);
57/******/ return getter;
58/******/ };
59/******/
60/******/ // Object.prototype.hasOwnProperty.call
61/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
62/******/
63/******/ // __webpack_public_path__
64/******/ __webpack_require__.p = "dist";
65/******/
66/******/ // Load entry module and return exports
67/******/ return __webpack_require__(__webpack_require__.s = 20);
68/******/ })
69/************************************************************************/
70/******/ ([
71/* 0 */
72/***/ (function(module, exports) {
73
74module.exports = require("babel-runtime/helpers/asyncToGenerator");
75
76/***/ }),
77/* 1 */
78/***/ (function(module, exports) {
79
80module.exports = require("babel-runtime/regenerator");
81
82/***/ }),
83/* 2 */
84/***/ (function(module, exports) {
85
86module.exports = require("babel-runtime/core-js/promise");
87
88/***/ }),
89/* 3 */
90/***/ (function(module, exports) {
91
92module.exports = require("denodeify");
93
94/***/ }),
95/* 4 */
96/***/ (function(module, exports) {
97
98module.exports = require("debug");
99
100/***/ }),
101/* 5 */
102/***/ (function(module, exports) {
103
104module.exports = require("babel-runtime/helpers/classCallCheck");
105
106/***/ }),
107/* 6 */
108/***/ (function(module, exports) {
109
110module.exports = require("babel-runtime/helpers/createClass");
111
112/***/ }),
113/* 7 */
114/***/ (function(module, exports) {
115
116module.exports = require("babel-runtime/helpers/extends");
117
118/***/ }),
119/* 8 */
120/***/ (function(module, exports) {
121
122module.exports = require("child_process");
123
124/***/ }),
125/* 9 */
126/***/ (function(module, exports, __webpack_require__) {
127
128"use strict";
129
130
131Object.defineProperty(exports, "__esModule", {
132 value: true
133});
134
135var _regenerator = __webpack_require__(1);
136
137var _regenerator2 = _interopRequireDefault(_regenerator);
138
139var _asyncToGenerator2 = __webpack_require__(0);
140
141var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
142
143var _extends2 = __webpack_require__(7);
144
145var _extends3 = _interopRequireDefault(_extends2);
146
147var _classCallCheck2 = __webpack_require__(5);
148
149var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
150
151var _createClass2 = __webpack_require__(6);
152
153var _createClass3 = _interopRequireDefault(_createClass2);
154
155var _apolloFetch = __webpack_require__(21);
156
157function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
158
159var GraphQLClient = function () {
160 function GraphQLClient(_ref) {
161 var uri = _ref.uri,
162 jwtToken = _ref.jwtToken,
163 headers = _ref.headers;
164 (0, _classCallCheck3.default)(this, GraphQLClient);
165
166 this.apolloFetch = (0, _apolloFetch.createApolloFetch)({ uri: uri });
167 this.headers = headers;
168
169 if (jwtToken) {
170 this.setJwtToken(jwtToken);
171 }
172 }
173
174 (0, _createClass3.default)(GraphQLClient, [{
175 key: 'setJwtToken',
176 value: function setJwtToken(jwtToken) {
177 var _this = this;
178
179 this.apolloFetch.use(function (_ref2, next) {
180 var options = _ref2.options;
181
182 if (jwtToken) {
183 // eslint-disable-next-line no-param-reassign
184 options.headers = (0, _extends3.default)({}, options.headers, _this.headers, {
185 authorization: 'bearer ' + jwtToken
186 });
187 }
188
189 next();
190 });
191 }
192 }, {
193 key: 'runQuery',
194 value: function () {
195 var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(query, variables) {
196 var _ref4, data, errors;
197
198 return _regenerator2.default.wrap(function _callee$(_context) {
199 while (1) {
200 switch (_context.prev = _context.next) {
201 case 0:
202 _context.next = 2;
203 return this.apolloFetch({ query: query, variables: variables });
204
205 case 2:
206 _ref4 = _context.sent;
207 data = _ref4.data;
208 errors = _ref4.errors;
209
210 if (!errors) {
211 _context.next = 7;
212 break;
213 }
214
215 throw errors;
216
217 case 7:
218 return _context.abrupt('return', data);
219
220 case 8:
221 case 'end':
222 return _context.stop();
223 }
224 }
225 }, _callee, this);
226 }));
227
228 function runQuery(_x, _x2) {
229 return _ref3.apply(this, arguments);
230 }
231
232 return runQuery;
233 }()
234
235 // Convenience static method
236
237 }], [{
238 key: 'runQuery',
239 value: function () {
240 var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(options, query, variables) {
241 return _regenerator2.default.wrap(function _callee2$(_context2) {
242 while (1) {
243 switch (_context2.prev = _context2.next) {
244 case 0:
245 return _context2.abrupt('return', new GraphQLClient(options).runQuery(query, variables));
246
247 case 1:
248 case 'end':
249 return _context2.stop();
250 }
251 }
252 }, _callee2, this);
253 }));
254
255 function runQuery(_x3, _x4, _x5) {
256 return _ref5.apply(this, arguments);
257 }
258
259 return runQuery;
260 }()
261 }]);
262 return GraphQLClient;
263}();
264
265exports.default = GraphQLClient;
266
267/***/ }),
268/* 10 */
269/***/ (function(module, exports, __webpack_require__) {
270
271"use strict";
272
273
274Object.defineProperty(exports, "__esModule", {
275 value: true
276});
277// Note this file differs from our usual convention because it is packaged
278var _process$env = process.env,
279 _process$env$CHROMATI = _process$env.CHROMATIC_SERVER_PORT,
280 CHROMATIC_SERVER_PORT = _process$env$CHROMATI === undefined ? 3004 : _process$env$CHROMATI,
281 _process$env$CHROMATI2 = _process$env.CHROMATIC_INDEX_URL,
282 CHROMATIC_INDEX_URL = _process$env$CHROMATI2 === undefined ? 'https://index.chromaticqa.com' : _process$env$CHROMATI2,
283 _process$env$CHROMATI3 = _process$env.CHROMATIC_TUNNEL_URL,
284 CHROMATIC_TUNNEL_URL = _process$env$CHROMATI3 === undefined ? 'https://tunnel.chromaticqa.com' : _process$env$CHROMATI3,
285 _process$env$CHROMATI4 = _process$env.CHROMATIC_CREATE_TUNNEL,
286 CHROMATIC_CREATE_TUNNEL = _process$env$CHROMATI4 === undefined ? 'true' : _process$env$CHROMATI4,
287 CHROMATIC_APP_CODE = _process$env.CHROMATIC_APP_CODE;
288exports.CHROMATIC_SERVER_PORT = CHROMATIC_SERVER_PORT;
289exports.CHROMATIC_INDEX_URL = CHROMATIC_INDEX_URL;
290exports.CHROMATIC_TUNNEL_URL = CHROMATIC_TUNNEL_URL;
291exports.CHROMATIC_CREATE_TUNNEL = CHROMATIC_CREATE_TUNNEL;
292exports.CHROMATIC_APP_CODE = CHROMATIC_APP_CODE;
293
294/***/ }),
295/* 11 */
296/***/ (function(module, exports, __webpack_require__) {
297
298"use strict";
299
300
301Object.defineProperty(exports, "__esModule", {
302 value: true
303});
304
305var _regenerator = __webpack_require__(1);
306
307var _regenerator2 = _interopRequireDefault(_regenerator);
308
309var _asyncToGenerator2 = __webpack_require__(0);
310
311var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
312
313var _localtunnel = __webpack_require__(29);
314
315var _localtunnel2 = _interopRequireDefault(_localtunnel);
316
317var _denodeify = __webpack_require__(3);
318
319var _denodeify2 = _interopRequireDefault(_denodeify);
320
321function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
322
323exports.default = function () {
324 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(_ref) {
325 var tunnelUrl = _ref.tunnelUrl,
326 port = _ref.port;
327 return _regenerator2.default.wrap(function _callee$(_context) {
328 while (1) {
329 switch (_context.prev = _context.next) {
330 case 0:
331 if (port) {
332 _context.next = 2;
333 break;
334 }
335
336 throw new Error('Need to pass a port into `openTunnel`');
337
338 case 2:
339 return _context.abrupt('return', (0, _denodeify2.default)(_localtunnel2.default)(port, {
340 local_host: 'localhost',
341 host: tunnelUrl
342 }));
343
344 case 3:
345 case 'end':
346 return _context.stop();
347 }
348 }
349 }, _callee, this);
350 }));
351
352 function openTunnel(_x) {
353 return _ref2.apply(this, arguments);
354 }
355
356 return openTunnel;
357}();
358
359/***/ }),
360/* 12 */
361/***/ (function(module, exports, __webpack_require__) {
362
363"use strict";
364
365
366Object.defineProperty(exports, "__esModule", {
367 value: true
368});
369exports.getBaselineCommits = exports.getBranch = exports.getCommit = exports.LIMIT_HISTORY_TO_N_COMMITS = exports.MAX_N_FETCHES = exports.FETCH_N_INITIAL_BUILD_COMMITS = undefined;
370
371var _toConsumableArray2 = __webpack_require__(25);
372
373var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
374
375var _slicedToArray2 = __webpack_require__(24);
376
377var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
378
379var _regenerator = __webpack_require__(1);
380
381var _regenerator2 = _interopRequireDefault(_regenerator);
382
383var _asyncToGenerator2 = __webpack_require__(0);
384
385var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
386
387var execGitCommand = function () {
388 var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(command) {
389 return _regenerator2.default.wrap(function _callee$(_context) {
390 while (1) {
391 switch (_context.prev = _context.next) {
392 case 0:
393 _context.prev = 0;
394 _context.next = 3;
395 return (0, _denodeify2.default)(_child_process.exec)(command);
396
397 case 3:
398 return _context.abrupt('return', _context.sent.trim());
399
400 case 6:
401 _context.prev = 6;
402 _context.t0 = _context['catch'](0);
403
404 // eslint-disable-next-line no-console
405 if (_context.t0.message && _context.t0.message.match('Not a git repository')) {
406 console.error('Unable to execute git command \'' + command + '\'.\n');
407 // eslint-disable-next-line no-console
408 console.error('Chromatic only works in git projects.\n' + 'Contact us at support@hichroma.com if you need to use Chromatic outside of one.\n\n');
409 }
410 throw _context.t0;
411
412 case 10:
413 case 'end':
414 return _context.stop();
415 }
416 }
417 }, _callee, this, [[0, 6]]);
418 }));
419
420 return function execGitCommand(_x) {
421 return _ref.apply(this, arguments);
422 };
423}();
424
425// NOTE: At some point we should check that the commit has been pushed to the
426// remote and the branch matches with origin/REF, but for now we are naive about
427// adhoc builds.
428
429var getCommit = exports.getCommit = function () {
430 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
431 var _trim$split, _trim$split2, commit, committedAtSeconds;
432
433 return _regenerator2.default.wrap(function _callee2$(_context2) {
434 while (1) {
435 switch (_context2.prev = _context2.next) {
436 case 0:
437 _context2.next = 2;
438 return execGitCommand('git log -n 1 --format="%H %ct"');
439
440 case 2:
441 _trim$split = _context2.sent.trim().split(' ');
442 _trim$split2 = (0, _slicedToArray3.default)(_trim$split, 2);
443 commit = _trim$split2[0];
444 committedAtSeconds = _trim$split2[1];
445 return _context2.abrupt('return', { commit: commit, committedAt: committedAtSeconds * 1000 });
446
447 case 7:
448 case 'end':
449 return _context2.stop();
450 }
451 }
452 }, _callee2, this);
453 }));
454
455 return function getCommit() {
456 return _ref2.apply(this, arguments);
457 };
458}();
459
460var getBranch = exports.getBranch = function () {
461 var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3() {
462 var branch;
463 return _regenerator2.default.wrap(function _callee3$(_context3) {
464 while (1) {
465 switch (_context3.prev = _context3.next) {
466 case 0:
467 _context3.next = 2;
468 return execGitCommand('git rev-parse --abbrev-ref HEAD');
469
470 case 2:
471 branch = _context3.sent.trim();
472
473 if (!(branch === 'HEAD')) {
474 _context3.next = 5;
475 break;
476 }
477
478 return _context3.abrupt('return', process.env.CI_BRANCH || branch);
479
480 case 5:
481 return _context3.abrupt('return', branch);
482
483 case 6:
484 case 'end':
485 return _context3.stop();
486 }
487 }
488 }, _callee3, this);
489 }));
490
491 return function getBranch() {
492 return _ref3.apply(this, arguments);
493 };
494}();
495
496// Given a list of commit hashes, ensure that at least one of them is from our
497// current git history
498var checkSomeCommitsAreInHistory = function () {
499 var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(commits) {
500 return _regenerator2.default.wrap(function _callee4$(_context4) {
501 while (1) {
502 switch (_context4.prev = _context4.next) {
503 case 0:
504 _context4.prev = 0;
505 _context4.next = 3;
506 return execGitCommand('git rev-list -n 1 --ignore-missing ' + commitsForCLI(commits));
507
508 case 3:
509 return _context4.abrupt('return', true);
510
511 case 6:
512 _context4.prev = 6;
513 _context4.t0 = _context4['catch'](0);
514
515 if (!(_context4.t0.code === 129)) {
516 _context4.next = 10;
517 break;
518 }
519
520 return _context4.abrupt('return', false);
521
522 case 10:
523 throw _context4.t0;
524
525 case 11:
526 case 'end':
527 return _context4.stop();
528 }
529 }
530 }, _callee4, this, [[0, 6]]);
531 }));
532
533 return function checkSomeCommitsAreInHistory(_x2) {
534 return _ref4.apply(this, arguments);
535 };
536}();
537
538// Get (at most) FETCH_N_INITIAL_BUILD_COMMITS most recent commits from this,
539// with a guarantee that at least *one* of the commits exists in this repository
540// (i.e. hasn't been rebased or squashed out of the repo)
541// If we need to do more than MAX_N_FETCHES to get them (i.e. the most recent
542// FETCH_N_INITIAL_BUILD_COMMITS * MAX_N_FETCHES commits are all gone), we throw
543
544
545var getRecentCommits = function () {
546 var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(client, newestCommittedAt) {
547 var getSince = function () {
548 var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(skip) {
549 var recentCommits;
550 return _regenerator2.default.wrap(function _callee5$(_context5) {
551 while (1) {
552 switch (_context5.prev = _context5.next) {
553 case 0:
554 if (!(skip >= max)) {
555 _context5.next = 2;
556 break;
557 }
558
559 return _context5.abrupt('return', fail(max));
560
561 case 2:
562 _context5.next = 4;
563 return client.runQuery(TesterGetRecentBuildCommitsQuery, {
564 newestCommittedAt: newestCommittedAt,
565 skip: skip
566 });
567
568 case 4:
569 recentCommits = _context5.sent.app.buildCommits;
570
571 debug(FETCH_N_INITIAL_BUILD_COMMITS + ' after ' + skip + ' commits: ' + recentCommits);
572
573 if (!(recentCommits.length === 0)) {
574 _context5.next = 10;
575 break;
576 }
577
578 if (!(skip === 0)) {
579 _context5.next = 9;
580 break;
581 }
582
583 return _context5.abrupt('return', recentCommits);
584
585 case 9:
586 return _context5.abrupt('return', fail(skip));
587
588 case 10:
589 _context5.next = 12;
590 return checkSomeCommitsAreInHistory(recentCommits);
591
592 case 12:
593 if (!_context5.sent) {
594 _context5.next = 14;
595 break;
596 }
597
598 return _context5.abrupt('return', recentCommits);
599
600 case 14:
601 return _context5.abrupt('return', getSince(skip + recentCommits.length));
602
603 case 15:
604 case 'end':
605 return _context5.stop();
606 }
607 }
608 }, _callee5, this);
609 }));
610
611 return function getSince(_x5) {
612 return _ref6.apply(this, arguments);
613 };
614 }();
615
616 var max, fail;
617 return _regenerator2.default.wrap(function _callee6$(_context6) {
618 while (1) {
619 switch (_context6.prev = _context6.next) {
620 case 0:
621 fail = function fail(count) {
622 throw new Error('Didn\'t find any commits in this git repository in the last ' + count + ' builds.\n\nAre you sure you are running this command against the correct app-code?\n\nPlease find out more here: http://docs.chromaticqa.com/branching-and-baselines');
623 };
624
625 max = FETCH_N_INITIAL_BUILD_COMMITS * MAX_N_FETCHES;
626 return _context6.abrupt('return', getSince(0));
627
628 case 3:
629 case 'end':
630 return _context6.stop();
631 }
632 }
633 }, _callee6, this);
634 }));
635
636 return function getRecentCommits(_x3, _x4) {
637 return _ref5.apply(this, arguments);
638 };
639}();
640
641// We use rev-list to get all the commits that are ancestors of HEAD but not
642// ancestors of any of the <commits>.
643//
644// These commits naturally form a tree that meets up to the complete history of
645// <commits> (call that the "known" history, from chromatic's perspective).
646// git calls the commits in the known history where the tree joins the "boundary".
647// Of the boundary commits:
648// - Those that are actually members of <commits> correspond to builds that
649// we want to use as a baseline
650// - Otherwise they correspond to commits in the known history that we have
651// commit path to but no known build on that path.
652//
653// We are just going to follow a simple algorithm: on the first pass, grab
654// X commits, check which are boundaries. If there are boundaries not in those
655// commits, choose the *oldest*, and grab all builds that are more recent.
656// In the second pass we do not care which
657
658
659var getBaselinesFromCommits = function () {
660 var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(commits) {
661 var boundaryData, boundaryLines, baselineCommits, oldestCommittedAt;
662 return _regenerator2.default.wrap(function _callee7$(_context7) {
663 while (1) {
664 switch (_context7.prev = _context7.next) {
665 case 0:
666 _context7.next = 2;
667 return execGitCommand('git rev-list HEAD --boundary --format=\'%m%H %ct\' --ignore-missing -n ' + LIMIT_HISTORY_TO_N_COMMITS + ' --not ' + commitsForCLI(commits));
668
669 case 2:
670 boundaryData = _context7.sent;
671 boundaryLines = boundaryData.trim().split('\n');
672
673 // If we don't find commit history within LIMIT_HISTORY_TO_N_COMMITS commits
674 // we assume we never will. Otherwise commits that are detached from the
675 // history can cause us to crash
676
677 if (!(boundaryLines.length >= LIMIT_HISTORY_TO_N_COMMITS * 2)) {
678 _context7.next = 6;
679 break;
680 }
681
682 throw new Error('Failed to find common ancestors with most recent builds within ' + LIMIT_HISTORY_TO_N_COMMITS + ' commits.\n\nPrevious builds used commits: ' + commits + '.\nAre you sure you are running this command against the correct app-code?\n\nPlease find out more here: http://docs.chromaticqa.com/branching-and-baselines');
683
684 case 6:
685 baselineCommits = [];
686 oldestCommittedAt = null;
687
688 // rev-list lists each commit like:
689 // commit 4a1c922edd61fa0e9d3cb25d4e205816701557a5
690 // >4a1c922edd61fa0e9d3cb25d4e205816701557a5 1495065352
691 // We want the second line if it matches ("-")
692
693 boundaryLines.filter(function (l) {
694 return !l.match('commit') && l.match('-');
695 }).forEach(function (rawRow) {
696 var _rawRow$trim$split = rawRow.trim().split(' '),
697 _rawRow$trim$split2 = (0, _slicedToArray3.default)(_rawRow$trim$split, 2),
698 commitWithDash = _rawRow$trim$split2[0],
699 committedAtSeconds = _rawRow$trim$split2[1];
700
701 var commit = commitWithDash.slice(1);
702
703 if (commits.find(function (c) {
704 return c === commit;
705 })) {
706 baselineCommits.push(commit);
707 } else if (oldestCommittedAt === null) {
708 oldestCommittedAt = committedAtSeconds * 1000;
709 } else {
710 oldestCommittedAt = Math.min(oldestCommittedAt, committedAtSeconds * 1000);
711 }
712 });
713
714 return _context7.abrupt('return', {
715 baselineCommits: baselineCommits,
716 oldestCommittedAt: oldestCommittedAt
717 });
718
719 case 10:
720 case 'end':
721 return _context7.stop();
722 }
723 }
724 }, _callee7, this);
725 }));
726
727 return function getBaselinesFromCommits(_x6) {
728 return _ref7.apply(this, arguments);
729 };
730}();
731
732// eslint-disable-next-line import/prefer-default-export
733
734
735var getBaselineCommits = exports.getBaselineCommits = function () {
736 var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(client) {
737 var _ref9, currentCommit, committedAt, recentCommits, _ref10, recentBaselineCommits, oldestCommittedAt, allPossibleCommits, _ref11, baselineCommits;
738
739 return _regenerator2.default.wrap(function _callee8$(_context8) {
740 while (1) {
741 switch (_context8.prev = _context8.next) {
742 case 0:
743 _context8.next = 2;
744 return getCommit();
745
746 case 2:
747 _ref9 = _context8.sent;
748 currentCommit = _ref9.commit;
749 committedAt = _ref9.committedAt;
750 _context8.next = 7;
751 return getRecentCommits(client, committedAt);
752
753 case 7:
754 recentCommits = _context8.sent;
755
756 debug('Found commits: ' + recentCommits);
757
758 // Short-circuit: on first run, there's definitely no baseline!
759
760 if (!(recentCommits.length === 0)) {
761 _context8.next = 11;
762 break;
763 }
764
765 return _context8.abrupt('return', []);
766
767 case 11:
768 if (!recentCommits.find(function (c) {
769 return c === currentCommit;
770 })) {
771 _context8.next = 13;
772 break;
773 }
774
775 return _context8.abrupt('return', [currentCommit]);
776
777 case 13:
778 _context8.next = 15;
779 return getBaselinesFromCommits(recentCommits);
780
781 case 15:
782 _ref10 = _context8.sent;
783 recentBaselineCommits = _ref10.baselineCommits;
784 oldestCommittedAt = _ref10.oldestCommittedAt;
785
786 debug('Baselines from initial commits: ' + recentBaselineCommits + ' [' + oldestCommittedAt + ']');
787
788 // console.log(recentBaselineCommits, oldestCommittedAt);
789 // Important optimization. If we are sure that there aren't any older relevant
790 // builds, we can avoid an extra query
791
792 if (!(oldestCommittedAt === null || recentCommits.length < FETCH_N_INITIAL_BUILD_COMMITS)) {
793 _context8.next = 21;
794 break;
795 }
796
797 return _context8.abrupt('return', recentBaselineCommits);
798
799 case 21:
800 _context8.next = 23;
801 return client.runQuery(TesterGetAllPossibleBuildCommitsQuery, {
802 newestCommittedAt: committedAt,
803 oldestCommittedAt: oldestCommittedAt
804 });
805
806 case 23:
807 allPossibleCommits = _context8.sent.app.buildCommits;
808
809 debug('allPossibleCommits: ' + allPossibleCommits);
810
811 _context8.next = 27;
812 return getBaselinesFromCommits([].concat((0, _toConsumableArray3.default)(recentCommits), (0, _toConsumableArray3.default)(allPossibleCommits)));
813
814 case 27:
815 _ref11 = _context8.sent;
816 baselineCommits = _ref11.baselineCommits;
817
818 debug('allPossible baselineCommits: ' + baselineCommits);
819 return _context8.abrupt('return', baselineCommits);
820
821 case 31:
822 case 'end':
823 return _context8.stop();
824 }
825 }
826 }, _callee8, this);
827 }));
828
829 return function getBaselineCommits(_x7) {
830 return _ref8.apply(this, arguments);
831 };
832}();
833
834var _child_process = __webpack_require__(8);
835
836var _denodeify = __webpack_require__(3);
837
838var _denodeify2 = _interopRequireDefault(_denodeify);
839
840var _debug = __webpack_require__(4);
841
842var _debug2 = _interopRequireDefault(_debug);
843
844function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
845
846var debug = (0, _debug2.default)('react-chromatic:tester:git');
847
848var FETCH_N_INITIAL_BUILD_COMMITS = exports.FETCH_N_INITIAL_BUILD_COMMITS = 20;
849var MAX_N_FETCHES = exports.MAX_N_FETCHES = 5;
850var LIMIT_HISTORY_TO_N_COMMITS = exports.LIMIT_HISTORY_TO_N_COMMITS = 1000;
851
852var TesterGetRecentBuildCommitsQuery = '\n query TesterGetRecentBuildCommitsQuery($skip: Int!, $newestCommittedAt: Float!) {\n app {\n buildCommits(skip: $skip, limit: ' + FETCH_N_INITIAL_BUILD_COMMITS + ', newestCommittedAt: $newestCommittedAt)\n }\n }\n';
853
854var TesterGetAllPossibleBuildCommitsQuery = '\n query TesterGetAllPossibleBuildCommitsQuery($newestCommittedAt: Float!, $oldestCommittedAt: Float!) {\n app {\n buildCommits(skip: ' + FETCH_N_INITIAL_BUILD_COMMITS + ', newestCommittedAt: $newestCommittedAt, oldestCommittedAt: $oldestCommittedAt)\n }\n }\n';
855
856function commitsForCLI(commits) {
857 return commits.map(function (c) {
858 return c.trim();
859 }).join(' ');
860}
861
862/***/ }),
863/* 13 */
864/***/ (function(module, exports, __webpack_require__) {
865
866"use strict";
867
868
869Object.defineProperty(exports, "__esModule", {
870 value: true
871});
872
873var _values = __webpack_require__(23);
874
875var _values2 = _interopRequireDefault(_values);
876
877exports.checkPackageJson = checkPackageJson;
878exports.addScriptToPackageJson = addScriptToPackageJson;
879
880var _path = __webpack_require__(30);
881
882var _path2 = _interopRequireDefault(_path);
883
884var _jsonfile = __webpack_require__(28);
885
886function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
887
888function checkPackageJson() {
889 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
890 _ref$appDir = _ref.appDir,
891 appDir = _ref$appDir === undefined ? process.cwd() : _ref$appDir;
892
893 var packageJson = (0, _jsonfile.readFileSync)(_path2.default.resolve(appDir, './package.json'));
894
895 return (0, _values2.default)(packageJson.scripts || {}).find(function (script) {
896 return script.match('chromatic test');
897 });
898}
899
900function addScriptToPackageJson(scriptName, scriptCommand) {
901 var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
902 _ref2$appDir = _ref2.appDir,
903 appDir = _ref2$appDir === undefined ? process.cwd() : _ref2$appDir;
904
905 var filename = _path2.default.resolve(appDir, './package.json');
906 var packageJson = (0, _jsonfile.readFileSync)(filename);
907
908 if (packageJson[scriptName]) {
909 throw new Error('Script named \'' + scriptName + '\' already exists in package.json');
910 }
911
912 if (!packageJson.scripts) {
913 packageJson.scripts = {};
914 }
915 packageJson.scripts[scriptName] = scriptCommand;
916 (0, _jsonfile.writeFileSync)(filename, packageJson, { spaces: 2 });
917}
918
919/***/ }),
920/* 14 */
921/***/ (function(module, exports, __webpack_require__) {
922
923"use strict";
924
925
926Object.defineProperty(exports, "__esModule", {
927 value: true
928});
929
930var _regenerator = __webpack_require__(1);
931
932var _regenerator2 = _interopRequireDefault(_regenerator);
933
934var _promise = __webpack_require__(2);
935
936var _promise2 = _interopRequireDefault(_promise);
937
938var _keys = __webpack_require__(22);
939
940var _keys2 = _interopRequireDefault(_keys);
941
942var _asyncToGenerator2 = __webpack_require__(0);
943
944var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
945
946var _classCallCheck2 = __webpack_require__(5);
947
948var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
949
950var _createClass2 = __webpack_require__(6);
951
952var _createClass3 = _interopRequireDefault(_createClass2);
953
954var _jsdom = __webpack_require__(27);
955
956function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
957
958function addShimsToJSDOM(dom) {
959 Object.defineProperty(dom.window, 'matchMedia', {
960 value: function value() {
961 return {
962 matches: true,
963 addListener: function addListener() {},
964 removeListener: function removeListener() {}
965 };
966 }
967 });
968
969 var LocalStorageMock = function () {
970 function LocalStorageMock() {
971 (0, _classCallCheck3.default)(this, LocalStorageMock);
972
973 this.store = {};
974 }
975
976 (0, _createClass3.default)(LocalStorageMock, [{
977 key: 'getItem',
978 value: function getItem(key) {
979 return this.store[key];
980 }
981 }, {
982 key: 'removeItem',
983 value: function removeItem(key) {
984 delete this.store[key];
985 }
986 }, {
987 key: 'setItem',
988 value: function setItem(key, value) {
989 this.store[key] = value.toString();
990 }
991 }, {
992 key: 'clear',
993 value: function clear() {
994 this.store = {};
995 }
996 }]);
997 return LocalStorageMock;
998 }();
999
1000 Object.defineProperty(dom.window, 'localStorage', {
1001 value: new LocalStorageMock()
1002 });
1003
1004 var WorkerMock = function () {
1005 function WorkerMock() {
1006 (0, _classCallCheck3.default)(this, WorkerMock);
1007 }
1008
1009 (0, _createClass3.default)(WorkerMock, [{
1010 key: 'addEventListener',
1011 value: function addEventListener() {}
1012 }, {
1013 key: 'removeEventLister',
1014 value: function removeEventLister() {}
1015 }, {
1016 key: 'postMessage',
1017 value: function postMessage() {}
1018 }, {
1019 key: 'terminate',
1020 value: function terminate() {}
1021 }]);
1022 return WorkerMock;
1023 }();
1024
1025 Object.defineProperty(dom.window, 'Worker', WorkerMock);
1026
1027 Object.defineProperty(dom.window, 'crypto', {
1028 value: {
1029 getRandomValues: function getRandomValues() {
1030 return 0;
1031 }
1032 }
1033 });
1034} /* eslint-disable no-console, class-methods-use-this */
1035
1036exports.default = function () {
1037 var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(url) {
1038 var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
1039 _ref2$verbose = _ref2.verbose,
1040 verbose = _ref2$verbose === undefined ? false : _ref2$verbose;
1041
1042 var logs, virtualConsole, dom;
1043 return _regenerator2.default.wrap(function _callee$(_context) {
1044 while (1) {
1045 switch (_context.prev = _context.next) {
1046 case 0:
1047 logs = [];
1048 virtualConsole = new _jsdom.VirtualConsole();
1049
1050 (0, _keys2.default)(console).forEach(function (logType) {
1051 virtualConsole.on(logType, function (log) {
1052 return logs.push({ logType: logType, log: log });
1053 });
1054 });
1055 virtualConsole.on('jsdomError', function (log) {
1056 return logs.push({ logType: 'error', log: log });
1057 });
1058
1059 if (verbose) {
1060 virtualConsole.sendTo(console);
1061 }
1062
1063 _context.next = 7;
1064 return _jsdom.JSDOM.fromURL(url, {
1065 userAgent: 'Chromatic',
1066 // We need to execute the scripts on the page
1067 runScripts: 'dangerously',
1068 // We need to load scripts that are loaded via script tags
1069 resources: 'usable',
1070 // Send console.logs -> /dev/null (so to speak)
1071 virtualConsole: virtualConsole,
1072 // Add a requestAnimationFrame polyfill, react@16 warns about it
1073 pretendToBeVisual: true
1074 });
1075
1076 case 7:
1077 dom = _context.sent;
1078
1079
1080 // NOTE: this line runs immediately after the HTML for the page has been loaded
1081 // it's not possible that any external script tags have been executed.
1082 // It is possible that they have a <script> tag that need these shims, but
1083 // I highly doubt it. If we run into this we can always use JSDOM's old API
1084 // to inject our own scripts at 'create' time
1085 addShimsToJSDOM(dom);
1086
1087 return _context.abrupt('return', new _promise2.default(function (resolve, reject) {
1088 return dom.window.document.addEventListener('DOMContentLoaded', function () {
1089 var separator = '=========================';
1090
1091 if (!dom.window.__chromaticRuntimeSpecs__) {
1092 console.error('Didn\'t find \'window.__chromaticRuntimeSpecs__\' at ' + url + '.\n' + 'Have you installed the Chromatic widget or addon correctly?\n');
1093
1094 if (!verbose && logs.length) {
1095 console.error('Your app\'s output:\n' + separator + '\n');
1096 logs.forEach(function (_ref3) {
1097 var logType = _ref3.logType,
1098 log = _ref3.log;
1099 return console[logType](log);
1100 });
1101 console.error('\n' + separator + '\n');
1102 }
1103 reject(new Error('Didn\'t find \'window.__chromaticRuntimeSpecs__\' at ' + url + '.'));
1104 }
1105
1106 // If their app logged something to console.error, it's probably, but
1107 // not definitely an issue. See https://github.com/hichroma/chromatic/issues/757
1108 if (logs.find(function (log) {
1109 return log.logType === 'error';
1110 })) {
1111 console.error('\nYour app logged the following to the error console:\n' + separator);
1112 logs.filter(function (log) {
1113 return log.logType === 'error';
1114 }).forEach(function (_ref4) {
1115 var logType = _ref4.logType,
1116 log = _ref4.log;
1117 return console[logType](log);
1118 });
1119 console.error('\n' + separator + '\nThis may lead to some stories not working right or getting detected by Chromatic' + '\nWe suggest you fix the errors, but we will continue anyway..\n');
1120 }
1121
1122 var specs = dom.window.__chromaticRuntimeSpecs__();
1123 dom.window.close();
1124 resolve(specs);
1125 });
1126 }));
1127
1128 case 10:
1129 case 'end':
1130 return _context.stop();
1131 }
1132 }
1133 }, _callee, this);
1134 }));
1135
1136 function getRuntimeSpecs(_x2) {
1137 return _ref.apply(this, arguments);
1138 }
1139
1140 return getRuntimeSpecs;
1141}();
1142
1143/***/ }),
1144/* 15 */
1145/***/ (function(module, exports, __webpack_require__) {
1146
1147"use strict";
1148
1149
1150Object.defineProperty(exports, "__esModule", {
1151 value: true
1152});
1153exports.checkResponse = undefined;
1154
1155var _extends2 = __webpack_require__(7);
1156
1157var _extends3 = _interopRequireDefault(_extends2);
1158
1159var _promise = __webpack_require__(2);
1160
1161var _promise2 = _interopRequireDefault(_promise);
1162
1163var _regenerator = __webpack_require__(1);
1164
1165var _regenerator2 = _interopRequireDefault(_regenerator);
1166
1167var _asyncToGenerator2 = __webpack_require__(0);
1168
1169var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
1170
1171var checkResponse = exports.checkResponse = function () {
1172 var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(url) {
1173 return _regenerator2.default.wrap(function _callee$(_context) {
1174 while (1) {
1175 switch (_context.prev = _context.next) {
1176 case 0:
1177 _context.prev = 0;
1178 _context.next = 3;
1179 return (0, _isomorphicFetch2.default)(url);
1180
1181 case 3:
1182 return _context.abrupt('return', true);
1183
1184 case 6:
1185 _context.prev = 6;
1186 _context.t0 = _context['catch'](0);
1187 return _context.abrupt('return', false);
1188
1189 case 9:
1190 case 'end':
1191 return _context.stop();
1192 }
1193 }
1194 }, _callee, this, [[0, 6]]);
1195 }));
1196
1197 return function checkResponse(_x) {
1198 return _ref.apply(this, arguments);
1199 };
1200}();
1201
1202var waitForResponse = function () {
1203 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(child, url) {
1204 var timeoutAt;
1205 return _regenerator2.default.wrap(function _callee3$(_context3) {
1206 while (1) {
1207 switch (_context3.prev = _context3.next) {
1208 case 0:
1209 timeoutAt = Date.now() + TIMEOUT;
1210 return _context3.abrupt('return', new _promise2.default(function (resolve, reject) {
1211 var check = function () {
1212 var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
1213 return _regenerator2.default.wrap(function _callee2$(_context2) {
1214 while (1) {
1215 switch (_context2.prev = _context2.next) {
1216 case 0:
1217 if (!(Date.now() > timeoutAt)) {
1218 _context2.next = 4;
1219 break;
1220 }
1221
1222 resolved = true;
1223 reject(new Error('No server responding at ' + url + ' within ' + TIMEOUT / 1000 + ' seconds.'));
1224 return _context2.abrupt('return');
1225
1226 case 4:
1227 _context2.next = 6;
1228 return checkResponse(url);
1229
1230 case 6:
1231 if (!_context2.sent) {
1232 _context2.next = 10;
1233 break;
1234 }
1235
1236 resolved = true;
1237 resolve();
1238 return _context2.abrupt('return');
1239
1240 case 10:
1241 setTimeout(check, CHECK_EVERY);
1242
1243 case 11:
1244 case 'end':
1245 return _context2.stop();
1246 }
1247 }
1248 }, _callee2, this);
1249 }));
1250
1251 return function check() {
1252 return _ref3.apply(this, arguments);
1253 };
1254 }();
1255
1256 var resolved = false;
1257
1258 check();
1259
1260 if (child) {
1261 var output = '';
1262 child.stderr.on('data', function (e) {
1263 output += e.toString();
1264 });
1265 child.stdout.on('data', function (o) {
1266 output += o.toString();
1267 });
1268
1269 child.on('close', function () {
1270 if (!resolved) {
1271 reject(new Error('Script failed to start: ' + output + '\n'));
1272 }
1273 });
1274 }
1275 }));
1276
1277 case 2:
1278 case 'end':
1279 return _context3.stop();
1280 }
1281 }
1282 }, _callee3, this);
1283 }));
1284
1285 return function waitForResponse(_x2, _x3) {
1286 return _ref2.apply(this, arguments);
1287 };
1288}();
1289
1290var _child_process = __webpack_require__(8);
1291
1292var _isomorphicFetch = __webpack_require__(26);
1293
1294var _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch);
1295
1296function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1297
1298var CHECK_EVERY = 1000;
1299var TIMEOUT = 5 * 60 * 1000;
1300
1301exports.default = function () {
1302 var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(_ref4) {
1303 var _ref4$scriptName = _ref4.scriptName,
1304 scriptName = _ref4$scriptName === undefined ? 'start' : _ref4$scriptName,
1305 url = _ref4.url;
1306 var child;
1307 return _regenerator2.default.wrap(function _callee4$(_context4) {
1308 while (1) {
1309 switch (_context4.prev = _context4.next) {
1310 case 0:
1311 child = void 0;
1312
1313 if (!(scriptName !== 'none')) {
1314 _context4.next = 7;
1315 break;
1316 }
1317
1318 _context4.next = 4;
1319 return checkResponse(url);
1320
1321 case 4:
1322 if (!_context4.sent) {
1323 _context4.next = 6;
1324 break;
1325 }
1326
1327 throw new Error('Detected process already running at ' + url + '\nIf you are sure this is your server, pass `--do-not-start` to skip this step.');
1328
1329 case 6:
1330
1331 child = (0, _child_process.spawn)('npm', ['run', scriptName], {
1332 env: (0, _extends3.default)({}, process.env, {
1333 NODE_ENV: 'development',
1334 BROWSER: 'none'
1335 })
1336 });
1337
1338 case 7:
1339 _context4.next = 9;
1340 return waitForResponse(child, url);
1341
1342 case 9:
1343 return _context4.abrupt('return', child);
1344
1345 case 10:
1346 case 'end':
1347 return _context4.stop();
1348 }
1349 }
1350 }, _callee4, this);
1351 }));
1352
1353 function startApp(_x4) {
1354 return _ref5.apply(this, arguments);
1355 }
1356
1357 return startApp;
1358}();
1359
1360/***/ }),
1361/* 16 */
1362/***/ (function(module, exports) {
1363
1364module.exports = {"name":"react-chromatic","version":"0.7.11","description":"Visual Testing for React Components","browser":"./dist/client.js","main":"./dist/assets/null-server.js","scripts":{"prebuild":"rm -rf ./dist","build:bin":"../../node_modules/.bin/babel -s -d ./dist ./src -D --only 'assets,bin'","build:webpack":"../../node_modules/.bin/webpack","build":"../../node_modules/.bin/npm-run-all --serial -l build:**","prepare":"npm run build","dev":"../../node_modules/.bin/npm-run-all --parallel -l 'build:** -- --watch'"},"bin":{"chromatic":"./dist/bin/chromatic.js"},"dependencies":{"apollo-fetch":"^0.6.0","babel-runtime":"^6.26.0","commander":"^2.9.0","debug":"^3.0.1","denodeify":"^1.2.1","ejson":"^2.1.2","es6-error":"^4.0.2","isomorphic-fetch":"^2.2.1","jsdom":"^11.5.1","jsonfile":"^4.0.0","localtunnel":"^1.8.3","node-ask":"^1.0.1","tree-kill":"^1.1.0"},"peerDependencies":{"react":"15.x || 16.x","react-dom":"15.x || 16.x"},"devDependencies":{"babel-cli":"^6.26.0","npm-run-all":"^4.0.2","prettier-eslint":"^7.1.0","webpack":"^3.10.0","webpack-node-externals":"^1.6.0"}}
1365
1366/***/ }),
1367/* 17 */
1368/***/ (function(module, exports) {
1369
1370module.exports = require("babel-runtime/core-js/json/stringify");
1371
1372/***/ }),
1373/* 18 */
1374/***/ (function(module, exports) {
1375
1376module.exports = require("node-ask");
1377
1378/***/ }),
1379/* 19 */
1380/***/ (function(module, exports) {
1381
1382module.exports = require("tree-kill");
1383
1384/***/ }),
1385/* 20 */
1386/***/ (function(module, exports, __webpack_require__) {
1387
1388"use strict";
1389
1390
1391Object.defineProperty(exports, "__esModule", {
1392 value: true
1393});
1394
1395var _regenerator = __webpack_require__(1);
1396
1397var _regenerator2 = _interopRequireDefault(_regenerator);
1398
1399var _promise = __webpack_require__(2);
1400
1401var _promise2 = _interopRequireDefault(_promise);
1402
1403var _stringify = __webpack_require__(17);
1404
1405var _stringify2 = _interopRequireDefault(_stringify);
1406
1407var _asyncToGenerator2 = __webpack_require__(0);
1408
1409var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
1410
1411var waitForBuild = function () {
1412 var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(client, variables) {
1413 var _ref2, build, status, inProgressCount, specCount, changeCount, errorCount;
1414
1415 return _regenerator2.default.wrap(function _callee$(_context) {
1416 while (1) {
1417 switch (_context.prev = _context.next) {
1418 case 0:
1419 _context.next = 2;
1420 return client.runQuery(TesterBuildQuery, variables);
1421
1422 case 2:
1423 _ref2 = _context.sent;
1424 build = _ref2.app.build;
1425
1426 debug('build:' + (0, _stringify2.default)(build));
1427 status = build.status, inProgressCount = build.inProgressCount, specCount = build.specCount, changeCount = build.changeCount, errorCount = build.errorCount;
1428
1429 if (!(status === 'BUILD_IN_PROGRESS')) {
1430 _context.next = 11;
1431 break;
1432 }
1433
1434 if (inProgressCount !== lastInProgressCount) {
1435 lastInProgressCount = inProgressCount;
1436 log(inProgressCount + '/' + pluralize(specCount, 'spec') + ' remain to test. ' + ('(' + pluralize(changeCount, 'change') + ', ' + pluralize(errorCount, 'error') + ')'));
1437 }
1438
1439 _context.next = 10;
1440 return new _promise2.default(function (resolve) {
1441 return setTimeout(resolve, BUILD_POLL_INTERVAL);
1442 });
1443
1444 case 10:
1445 return _context.abrupt('return', waitForBuild(client, variables));
1446
1447 case 11:
1448 return _context.abrupt('return', build);
1449
1450 case 12:
1451 case 'end':
1452 return _context.stop();
1453 }
1454 }
1455 }, _callee, this);
1456 }));
1457
1458 return function waitForBuild(_x, _x2) {
1459 return _ref.apply(this, arguments);
1460 };
1461}();
1462
1463var _denodeify = __webpack_require__(3);
1464
1465var _denodeify2 = _interopRequireDefault(_denodeify);
1466
1467var _nodeAsk = __webpack_require__(18);
1468
1469var _debug = __webpack_require__(4);
1470
1471var _debug2 = _interopRequireDefault(_debug);
1472
1473var _treeKill = __webpack_require__(19);
1474
1475var _treeKill2 = _interopRequireDefault(_treeKill);
1476
1477var _runtimes = __webpack_require__(14);
1478
1479var _runtimes2 = _interopRequireDefault(_runtimes);
1480
1481var _startApp = __webpack_require__(15);
1482
1483var _startApp2 = _interopRequireDefault(_startApp);
1484
1485var _tunnel = __webpack_require__(11);
1486
1487var _tunnel2 = _interopRequireDefault(_tunnel);
1488
1489var _packageJson = __webpack_require__(13);
1490
1491var _GraphQLClient = __webpack_require__(9);
1492
1493var _GraphQLClient2 = _interopRequireDefault(_GraphQLClient);
1494
1495var _git = __webpack_require__(12);
1496
1497var _package = __webpack_require__(16);
1498
1499var _environment = __webpack_require__(10);
1500
1501function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1502
1503var BUILD_POLL_INTERVAL = 1000;
1504
1505var TesterCreateAppTokenMutation = '\n mutation TesterCreateAppTokenMutation($appCode: String!) {\n createAppToken(code: $appCode)\n }\n';
1506
1507var TesterCreateBuildMutation = '\n mutation TesterCreateBuildMutation($input: CreateBuildInput!, $isolatorUrl: String!) {\n createBuild(input: $input, isolatorUrl: $isolatorUrl) {\n id\n number\n specCount\n componentCount\n webUrl\n }\n }\n';
1508
1509var TesterBuildQuery = '\n query TesterBuildQuery($buildNumber: Int!) {\n app {\n build(number: $buildNumber) {\n id\n status\n inProgressCount: snapshotCount(statuses: [SNAPSHOT_IN_PROGRESS])\n specCount\n changeCount: snapshotCount(statuses: [SNAPSHOT_PENDING, SNAPSHOT_ACCEPTED, SNAPSHOT_DENIED])\n errorCount: snapshotCount(statuses: [SNAPSHOT_CAPTURE_ERROR])\n }\n }\n }\n';
1510
1511var debug = (0, _debug2.default)('react-chromatic:tester');
1512
1513function log(msg) {
1514 // eslint-disable-next-line no-console
1515 console.log('Chromatic Tester: ' + msg);
1516}
1517
1518function pluralize(n, noun, noNumber) {
1519 var pluralizedNoun = n === 1 ? noun : noun + 's';
1520
1521 return noNumber ? pluralizedNoun : n + ' ' + pluralizedNoun;
1522}
1523
1524var lastInProgressCount = void 0;
1525
1526exports.default = function () {
1527 var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(_ref3) {
1528 var appCode = _ref3.appCode,
1529 scriptName = _ref3.scriptName,
1530 _ref3$noStart = _ref3.noStart,
1531 noStart = _ref3$noStart === undefined ? false : _ref3$noStart,
1532 port = _ref3.port,
1533 _ref3$appPath = _ref3.appPath,
1534 appPath = _ref3$appPath === undefined ? '/' : _ref3$appPath,
1535 url = _ref3.url,
1536 _ref3$exitZeroOnChang = _ref3.exitZeroOnChanges,
1537 exitZeroOnChanges = _ref3$exitZeroOnChang === undefined ? false : _ref3$exitZeroOnChang,
1538 _ref3$verbose = _ref3.verbose,
1539 verbose = _ref3$verbose === undefined ? false : _ref3$verbose,
1540 _ref3$indexUrl = _ref3.indexUrl,
1541 indexUrl = _ref3$indexUrl === undefined ? _environment.CHROMATIC_INDEX_URL : _ref3$indexUrl,
1542 _ref3$tunnelUrl = _ref3.tunnelUrl,
1543 tunnelUrl = _ref3$tunnelUrl === undefined ? _environment.CHROMATIC_TUNNEL_URL : _ref3$tunnelUrl,
1544 _ref3$createTunnel = _ref3.createTunnel,
1545 createTunnel = _ref3$createTunnel === undefined ? true : _ref3$createTunnel,
1546 _ref3$originalArgv = _ref3.originalArgv,
1547 originalArgv = _ref3$originalArgv === undefined ? false : _ref3$originalArgv;
1548
1549 var uri, client, _ref5, jwtToken, _ref6, commit, committedAt, branch, baselineCommits, appPathWithSlash, appUrl, child, isolatorUrl, tunnel, runtimeSpecs, fromCI, exitCode, _ref7, _ref7$createBuild, number, specCount, componentCount, webUrl, onlineHint, _ref8, status, changeCount, errorCount, scriptCommand, confirmed;
1550
1551 return _regenerator2.default.wrap(function _callee2$(_context2) {
1552 while (1) {
1553 switch (_context2.prev = _context2.next) {
1554 case 0:
1555 uri = indexUrl + '/graphql';
1556 client = new _GraphQLClient2.default({ uri: uri });
1557
1558 if (appCode) {
1559 _context2.next = 4;
1560 break;
1561 }
1562
1563 throw new Error('You must provide an app code -- visit https://www.chromaticqa.com to get your code.' + '\nPass your app code with the `CHROMATIC_APP_CODE` environment variable or the `--app-code` flag.');
1564
1565 case 4:
1566 if (!(!scriptName && !noStart || !port)) {
1567 _context2.next = 6;
1568 break;
1569 }
1570
1571 throw new Error('You must provide a npm script name (`--script-name`) and port (`--port`) so we can start your app');
1572
1573 case 6:
1574 _context2.prev = 6;
1575 _context2.next = 9;
1576 return client.runQuery(TesterCreateAppTokenMutation, {
1577 appCode: appCode
1578 });
1579
1580 case 9:
1581 _ref5 = _context2.sent;
1582 jwtToken = _ref5.createAppToken;
1583
1584 client.setJwtToken(jwtToken);
1585 _context2.next = 19;
1586 break;
1587
1588 case 14:
1589 _context2.prev = 14;
1590 _context2.t0 = _context2['catch'](6);
1591
1592 if (!(_context2.t0[0] && _context2.t0[0].message && _context2.t0[0].message.match('No app with code'))) {
1593 _context2.next = 18;
1594 break;
1595 }
1596
1597 throw new Error('Incorrect app code \'' + appCode + '\' -- visit https://www.chromaticqa.com to get your code');
1598
1599 case 18:
1600 throw _context2.t0;
1601
1602 case 19:
1603 _context2.next = 21;
1604 return (0, _git.getCommit)();
1605
1606 case 21:
1607 _ref6 = _context2.sent;
1608 commit = _ref6.commit;
1609 committedAt = _ref6.committedAt;
1610 _context2.next = 26;
1611 return (0, _git.getBranch)();
1612
1613 case 26:
1614 branch = _context2.sent;
1615
1616 debug('git info: ' + (0, _stringify2.default)({ commit: commit, committedAt: committedAt, branch: branch }));
1617
1618 _context2.next = 30;
1619 return (0, _git.getBaselineCommits)(client);
1620
1621 case 30:
1622 baselineCommits = _context2.sent;
1623
1624 debug('Found baselineCommits: ' + baselineCommits);
1625
1626 appPathWithSlash = appPath[0] === '/' ? appPath : '/' + appPath;
1627 appUrl = url || 'http://localhost:' + port + appPathWithSlash;
1628 child = void 0;
1629
1630 if (!(!noStart && !url)) {
1631 _context2.next = 43;
1632 break;
1633 }
1634
1635 log('Starting app with `npm run ' + scriptName + '`');
1636 _context2.next = 39;
1637 return (0, _startApp2.default)({ scriptName: scriptName, url: appUrl });
1638
1639 case 39:
1640 child = _context2.sent;
1641
1642 log('Started app on port ' + port);
1643 _context2.next = 48;
1644 break;
1645
1646 case 43:
1647 _context2.next = 45;
1648 return (0, _startApp.checkResponse)(appUrl);
1649
1650 case 45:
1651 if (_context2.sent) {
1652 _context2.next = 47;
1653 break;
1654 }
1655
1656 throw new Error('No server responding at ' + appUrl + ' -- make sure you\'ve started it.');
1657
1658 case 47:
1659 log('Detected app on port ' + port);
1660
1661 case 48:
1662 isolatorUrl = appUrl;
1663 tunnel = void 0;
1664
1665 if (!(createTunnel && !url)) {
1666 _context2.next = 57;
1667 break;
1668 }
1669
1670 log('Opening tunnel to Chromatic capture servers');
1671 _context2.next = 54;
1672 return (0, _tunnel2.default)({ tunnelUrl: tunnelUrl, port: port });
1673
1674 case 54:
1675 tunnel = _context2.sent;
1676
1677 debug('Opened tunnel to ' + tunnel.url);
1678 isolatorUrl = '' + tunnel.url + appPathWithSlash;
1679
1680 case 57:
1681
1682 debug('Connecting to ' + isolatorUrl);
1683 log('Uploading and verifying build (this may take a few minutes depending on your connection)');
1684 _context2.next = 61;
1685 return (0, _runtimes2.default)(isolatorUrl, { verbose: verbose });
1686
1687 case 61:
1688 runtimeSpecs = _context2.sent;
1689
1690 log('Found ' + runtimeSpecs.length + ' specs');
1691
1692 fromCI = !!process.env.CI;
1693
1694 debug('Detected build fromCI:' + fromCI);
1695 debug('Detected package version:' + _package.version);
1696
1697 exitCode = 5;
1698 _context2.prev = 67;
1699 _context2.next = 70;
1700 return client.runQuery(TesterCreateBuildMutation, {
1701 input: {
1702 branch: branch,
1703 commit: commit,
1704 committedAt: committedAt,
1705 baselineCommits: baselineCommits,
1706 runtimeSpecs: runtimeSpecs,
1707 fromCI: fromCI,
1708 packageVersion: _package.version
1709 },
1710 isolatorUrl: isolatorUrl
1711 });
1712
1713 case 70:
1714 _ref7 = _context2.sent;
1715 _ref7$createBuild = _ref7.createBuild;
1716 number = _ref7$createBuild.number;
1717 specCount = _ref7$createBuild.specCount;
1718 componentCount = _ref7$createBuild.componentCount;
1719 webUrl = _ref7$createBuild.webUrl;
1720 onlineHint = 'View it online at ' + webUrl;
1721
1722 log('Started Build ' + number + ' ' + ('(' + pluralize(componentCount, 'component') + ', ' + pluralize(specCount, 'spec') + ').\n\n' + onlineHint + '.'));
1723
1724 _context2.next = 80;
1725 return waitForBuild(client, {
1726 buildNumber: number
1727 });
1728
1729 case 80:
1730 _ref8 = _context2.sent;
1731 status = _ref8.status;
1732 changeCount = _ref8.changeCount;
1733 errorCount = _ref8.errorCount;
1734 _context2.t1 = status;
1735 _context2.next = _context2.t1 === 'BUILD_PASSED' ? 87 : _context2.t1 === 'BUILD_PENDING' ? 90 : _context2.t1 === 'BUILD_ACCEPTED' ? 90 : _context2.t1 === 'BUILD_DENIED' ? 90 : _context2.t1 === 'BUILD_FAILED' ? 94 : _context2.t1 === 'BUILD_TIMED_OUT' ? 97 : _context2.t1 === 'BUILD_ERROR' ? 100 : 103;
1736 break;
1737
1738 case 87:
1739 log('Build ' + number + ' passed! ' + onlineHint + '.');
1740 exitCode = 0;
1741 return _context2.abrupt('break', 104);
1742
1743 case 90:
1744 log('Build ' + number + ' has ' + pluralize(changeCount, 'change') + '. ' + onlineHint + '.');
1745 if (!exitZeroOnChanges) {
1746 log('Pass --exit-zero-on-changes if you want this command to exit successfully in this case. Read more: http://docs.chromaticqa.com/test');
1747 }
1748 exitCode = exitZeroOnChanges ? 0 : 1;
1749 return _context2.abrupt('break', 104);
1750
1751 case 94:
1752 log('Build ' + number + ' has ' + pluralize(errorCount, 'error') + '. ' + onlineHint + '.');
1753 exitCode = 2;
1754 return _context2.abrupt('break', 104);
1755
1756 case 97:
1757 log('Build ' + number + ' has timed out. Ensure your machine is connected to the internet and please try again.');
1758 exitCode = 3;
1759 return _context2.abrupt('break', 104);
1760
1761 case 100:
1762 log('Build ' + number + ' has failed to run. Our apologies. Please try again.');
1763 exitCode = 4;
1764 return _context2.abrupt('break', 104);
1765
1766 case 103:
1767 throw new Error('Unexpected build status: ' + status);
1768
1769 case 104:
1770 _context2.next = 114;
1771 break;
1772
1773 case 106:
1774 _context2.prev = 106;
1775 _context2.t2 = _context2['catch'](67);
1776
1777 if (!(_context2.t2.length && _context2.t2[0] && _context2.t2[0].message.match(/Cannot run a build with no specs./))) {
1778 _context2.next = 113;
1779 break;
1780 }
1781
1782 log(_context2.t2[0].message);
1783 exitCode = 255;
1784 _context2.next = 114;
1785 break;
1786
1787 case 113:
1788 throw _context2.t2;
1789
1790 case 114:
1791 _context2.prev = 114;
1792
1793 if (tunnel) {
1794 tunnel.close();
1795 }
1796
1797 if (!child) {
1798 _context2.next = 119;
1799 break;
1800 }
1801
1802 _context2.next = 119;
1803 return (0, _denodeify2.default)(_treeKill2.default)(child.pid, 'SIGHUP');
1804
1805 case 119:
1806 return _context2.finish(114);
1807
1808 case 120:
1809 if (!(!(0, _packageJson.checkPackageJson)() && originalArgv)) {
1810 _context2.next = 127;
1811 break;
1812 }
1813
1814 scriptCommand = ('chromatic test ' + originalArgv.slice(2).join(' ')).replace(/--app-code[= ]\S+/, '');
1815 _context2.next = 124;
1816 return (0, _nodeAsk.confirm)("\nYou have not added Chromatic's test script to your `package.json`. Would you like me to do it for you?");
1817
1818 case 124:
1819 confirmed = _context2.sent;
1820
1821 if (confirmed) {
1822 (0, _packageJson.addScriptToPackageJson)('chromatic', scriptCommand);
1823 // eslint-disable-next-line no-console
1824 console.log('\nAdded script `chromatic`. You can now run it here or in CI with `npm run chromatic` (or `yarn chromatic`)');
1825 } else {
1826 // eslint-disable-next-line no-console
1827 console.log('\nNo problem. You can add it later with:\n{\n "scripts": {\n "chromatic": "' + scriptCommand + '"\n }\n}');
1828 }
1829
1830 // eslint-disable-next-line no-console
1831 console.log('\nMake sure you set the `CHROMATIC_APP_CODE` environment variable when running builds (in particular on your CI server).');
1832
1833 case 127:
1834 return _context2.abrupt('return', exitCode);
1835
1836 case 128:
1837 case 'end':
1838 return _context2.stop();
1839 }
1840 }
1841 }, _callee2, this, [[6, 14], [67, 106, 114, 120]]);
1842 }));
1843
1844 function runTest(_x3) {
1845 return _ref4.apply(this, arguments);
1846 }
1847
1848 return runTest;
1849}();
1850
1851/***/ }),
1852/* 21 */
1853/***/ (function(module, exports) {
1854
1855module.exports = require("apollo-fetch");
1856
1857/***/ }),
1858/* 22 */
1859/***/ (function(module, exports) {
1860
1861module.exports = require("babel-runtime/core-js/object/keys");
1862
1863/***/ }),
1864/* 23 */
1865/***/ (function(module, exports) {
1866
1867module.exports = require("babel-runtime/core-js/object/values");
1868
1869/***/ }),
1870/* 24 */
1871/***/ (function(module, exports) {
1872
1873module.exports = require("babel-runtime/helpers/slicedToArray");
1874
1875/***/ }),
1876/* 25 */
1877/***/ (function(module, exports) {
1878
1879module.exports = require("babel-runtime/helpers/toConsumableArray");
1880
1881/***/ }),
1882/* 26 */
1883/***/ (function(module, exports) {
1884
1885module.exports = require("isomorphic-fetch");
1886
1887/***/ }),
1888/* 27 */
1889/***/ (function(module, exports) {
1890
1891module.exports = require("jsdom");
1892
1893/***/ }),
1894/* 28 */
1895/***/ (function(module, exports) {
1896
1897module.exports = require("jsonfile");
1898
1899/***/ }),
1900/* 29 */
1901/***/ (function(module, exports) {
1902
1903module.exports = require("localtunnel");
1904
1905/***/ }),
1906/* 30 */
1907/***/ (function(module, exports) {
1908
1909module.exports = require("path");
1910
1911/***/ })
1912/******/ ]);
1913//# sourceMappingURL=tester.js.map
\No newline at end of file