index.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. (function () {
  2. var settings = allure.getPluginSettings('screen-diff', { diffType: 'diff' });
  3. function renderImage(src) {
  4. return (
  5. '<div class="screen-diff__container">' +
  6. '<img class="screen-diff__image" src="' +
  7. src +
  8. '">' +
  9. '</div>'
  10. );
  11. }
  12. function findImage(data, name) {
  13. if (data.testStage && data.testStage.attachments) {
  14. var matchedImage = data.testStage.attachments.filter(function (attachment) {
  15. return attachment.name === name;
  16. })[0];
  17. if (matchedImage) {
  18. return 'data/attachments/' + matchedImage.source;
  19. }
  20. }
  21. return null;
  22. }
  23. function renderDiffContent(type, diffImage, actualImage, expectedImage) {
  24. if (type === 'diff') {
  25. if (diffImage) {
  26. return renderImage(diffImage);
  27. }
  28. }
  29. if (type === 'overlay' && expectedImage) {
  30. return (
  31. '<div class="screen-diff__overlay screen-diff__container">' +
  32. '<img class="screen-diff__image" src="' +
  33. expectedImage +
  34. '">' +
  35. '<div class="screen-diff__image-over">' +
  36. '<img class="screen-diff__image" src="' +
  37. actualImage +
  38. '">' +
  39. '</div>' +
  40. '</div>'
  41. );
  42. }
  43. if (actualImage) {
  44. return renderImage(actualImage);
  45. }
  46. return 'No diff data provided';
  47. }
  48. var TestResultView = Backbone.Marionette.View.extend({
  49. regions: {
  50. subView: '.screen-diff-view',
  51. },
  52. template: function () {
  53. return '<div class="screen-diff-view"></div>';
  54. },
  55. onRender: function () {
  56. var data = this.model.toJSON();
  57. var testType = data.labels.filter(function (label) {
  58. return label.name === 'testType';
  59. })[0];
  60. var diffImage = findImage(data, 'diff');
  61. var actualImage = findImage(data, 'actual');
  62. var expectedImage = findImage(data, 'expected');
  63. if (!testType || testType.value !== 'screenshotDiff') {
  64. return;
  65. }
  66. this.showChildView(
  67. 'subView',
  68. new ScreenDiffView({
  69. diffImage: diffImage,
  70. actualImage: actualImage,
  71. expectedImage: expectedImage,
  72. }),
  73. );
  74. },
  75. });
  76. var ErrorView = Backbone.Marionette.View.extend({
  77. templateContext: function () {
  78. return this.options;
  79. },
  80. template: function (data) {
  81. return '<pre class="screen-diff-error">' + data.error + '</pre>';
  82. },
  83. });
  84. var AttachmentView = Backbone.Marionette.View.extend({
  85. regions: {
  86. subView: '.screen-diff-view',
  87. },
  88. template: function () {
  89. return '<div class="screen-diff-view"></div>';
  90. },
  91. onRender: function () {
  92. jQuery
  93. .getJSON(this.options.sourceUrl)
  94. .then(this.renderScreenDiffView.bind(this), this.renderErrorView.bind(this));
  95. },
  96. renderErrorView: function (error) {
  97. console.log(error);
  98. this.showChildView(
  99. 'subView',
  100. new ErrorView({
  101. error: error.statusText,
  102. }),
  103. );
  104. },
  105. renderScreenDiffView: function (data) {
  106. this.showChildView(
  107. 'subView',
  108. new ScreenDiffView({
  109. diffImage: data.diff,
  110. actualImage: data.actual,
  111. expectedImage: data.expected,
  112. }),
  113. );
  114. },
  115. });
  116. var ScreenDiffView = Backbone.Marionette.View.extend({
  117. className: 'pane__section',
  118. events: function () {
  119. return {
  120. ['click [name="screen-diff-type-' + this.cid + '"]']: 'onDiffTypeChange',
  121. 'mousemove .screen-diff__overlay': 'onOverlayMove',
  122. };
  123. },
  124. initialize: function (options) {
  125. this.diffImage = options.diffImage;
  126. this.actualImage = options.actualImage;
  127. this.expectedImage = options.expectedImage;
  128. this.radioName = 'screen-diff-type-' + this.cid;
  129. },
  130. templateContext: function () {
  131. return {
  132. diffType: settings.get('diffType'),
  133. diffImage: this.diffImage,
  134. actualImage: this.actualImage,
  135. expectedImage: this.expectedImage,
  136. radioName: this.radioName,
  137. };
  138. },
  139. template: function (data) {
  140. if (!data.diffImage && !data.actualImage && !data.expectedImage) {
  141. return '';
  142. }
  143. return (
  144. '<h3 class="pane__section-title">Screen Diff</h3>' +
  145. '<div class="screen-diff__content">' +
  146. '<div class="screen-diff__switchers">' +
  147. '<label><input type="radio" name="' +
  148. data.radioName +
  149. '" value="diff"> Show diff</label>' +
  150. '<label><input type="radio" name="' +
  151. data.radioName +
  152. '" value="overlay"> Show overlay</label>' +
  153. '</div>' +
  154. renderDiffContent(
  155. data.diffType,
  156. data.diffImage,
  157. data.actualImage,
  158. data.expectedImage,
  159. ) +
  160. '</div>'
  161. );
  162. },
  163. adjustImageSize: function (event) {
  164. var overImage = this.$(event.target);
  165. overImage.width(overImage.width());
  166. },
  167. onRender: function () {
  168. const diffType = settings.get('diffType');
  169. this.$('[name="' + this.radioName + '"][value="' + diffType + '"]').prop(
  170. 'checked',
  171. true,
  172. );
  173. if (diffType === 'overlay') {
  174. this.$('.screen-diff__image-over img').on('load', this.adjustImageSize.bind(this));
  175. }
  176. },
  177. onOverlayMove: function (event) {
  178. var pageX = event.pageX;
  179. var containerScroll = this.$('.screen-diff__container').scrollLeft();
  180. var elementX = event.currentTarget.getBoundingClientRect().left;
  181. var delta = pageX - elementX + containerScroll;
  182. this.$('.screen-diff__image-over').width(delta);
  183. },
  184. onDiffTypeChange: function (event) {
  185. settings.save('diffType', event.target.value);
  186. this.render();
  187. },
  188. });
  189. allure.api.addTestResultBlock(TestResultView, { position: 'before' });
  190. allure.api.addAttachmentViewer('application/vnd.allure.image.diff', {
  191. View: AttachmentView,
  192. icon: 'fa fa-exchange',
  193. });
  194. })();