diff --git a/core/src/main/kotlin/com/malinskiy/marathon/report/html/HtmlSummaryReporter.kt b/core/src/main/kotlin/com/malinskiy/marathon/report/html/HtmlSummaryReporter.kt index 3459e087f..8c6f50fb0 100644 --- a/core/src/main/kotlin/com/malinskiy/marathon/report/html/HtmlSummaryReporter.kt +++ b/core/src/main/kotlin/com/malinskiy/marathon/report/html/HtmlSummaryReporter.kt @@ -8,6 +8,7 @@ import com.malinskiy.marathon.config.Configuration import com.malinskiy.marathon.device.DeviceFeature import com.malinskiy.marathon.device.DeviceInfo import com.malinskiy.marathon.device.DevicePoolId +import com.malinskiy.marathon.execution.AttachmentType import com.malinskiy.marathon.execution.TestResult import com.malinskiy.marathon.execution.TestStatus import com.malinskiy.marathon.extension.escape @@ -175,14 +176,10 @@ class HtmlSummaryReporter( } } - private fun TestResult.receiveVideoPath(poolId: String, batchId: String): String { - val videoRelativePath = - fileManager.createFile(FileType.VIDEO, DevicePoolId(poolId), device, test, batchId).relativePathTo(rootOutput) - val videoFullPath = File(rootOutput, videoRelativePath) - return when (device.deviceFeatures.contains(DeviceFeature.VIDEO) && videoFullPath.exists()) { - true -> "../../../../${videoRelativePath.replace("#", "%23")}" - false -> "" - } + private fun TestResult.receiveVideoPaths(poolId: String, batchId: String): List { + if (!device.deviceFeatures.contains(DeviceFeature.VIDEO)) return emptyList() + return attachments.filter { it.type == AttachmentType.VIDEO && it.file.exists() }.map { it.file.relativePathTo(rootOutput) } + .map { "../../../../${it.replace("#","%23")}" } } private fun TestResult.receiveLogPath(poolId: String, batchId: String): String { @@ -209,7 +206,7 @@ class HtmlSummaryReporter( diagnosticScreenshots = device.deviceFeatures.contains(DeviceFeature.SCREENSHOT), stacktrace = stacktrace, screenshot = receiveScreenshotPath(poolId, batchId), - video = receiveVideoPath(poolId, batchId), + videos = receiveVideoPaths(poolId, batchId), logFile = receiveLogPath(poolId, batchId) ) diff --git a/html-report/src/components/TestItem.js b/html-report/src/components/TestItem.js index 99d53971b..aa5d14f5b 100644 --- a/html-report/src/components/TestItem.js +++ b/html-report/src/components/TestItem.js @@ -38,9 +38,12 @@ export default class TestItem extends Component { - {!!data.video &&
- -
} +
+ {data.videos.map((video, i) => { + return (
) + }) + } +
{!!data.screenshot &&
diff --git a/report/html-report/src/main/kotlin/com/malinskiy/marathon/report/HtmlFullTest.kt b/report/html-report/src/main/kotlin/com/malinskiy/marathon/report/HtmlFullTest.kt index b5b813d25..0aa78eb43 100644 --- a/report/html-report/src/main/kotlin/com/malinskiy/marathon/report/HtmlFullTest.kt +++ b/report/html-report/src/main/kotlin/com/malinskiy/marathon/report/HtmlFullTest.kt @@ -16,6 +16,6 @@ data class HtmlFullTest( @SerializedName("diagnostic_video") val diagnosticVideo: Boolean, @SerializedName("diagnostic_screenshots") val diagnosticScreenshots: Boolean, @SerializedName("screenshot") val screenshot: String, - @SerializedName("video") val video: String, + @SerializedName("videos") val videos: List, @SerializedName("log_file") val logFile: String, ) diff --git a/report/html-report/src/main/resources/html-report/app.min.js b/report/html-report/src/main/resources/html-report/app.min.js index edec10ec4..3ff47b968 100644 --- a/report/html-report/src/main/resources/html-report/app.min.js +++ b/report/html-report/src/main/resources/html-report/app.min.js @@ -1,2 +1,2 @@ /*! For license information please see app.min.js.LICENSE.txt */ -(()=>{var e={986:e=>{e.exports=function(e){var t=e%1e3,n=(e=(e-t)/1e3)%60,r=(e=(e-n)/60)%60,o=e=(e-r)/60,i=t.toString().length;return 2===i&&(t="0"+t),1===i&&(t="00"+t),o>0?o+":"+r+":"+n+"."+t:r+":"+n+"."+t}},505:e=>{e.exports={fromIndexToPool:function(e){return"./pools/".concat(e,".html")},fromPoolToIndex:"../index.html",fromTestToPool:function(e){return"../../".concat(e,".html")},fromTestToIndex:"../../../index.html",fromLogsToIndex:"../../../../index.html",fromTestToLogs:function(e){return"./logs/".concat(e)},fromLogsToTest:function(e){return"../".concat(e,".html")},fromLogsToPool:function(e){return"../../../".concat(e,".html")}}},184:(e,t)=>{var n;!function(){"use strict";var r={}.hasOwnProperty;function o(){for(var e=[],t=0;t{"use strict";var t=function(e){return function(e){return!!e&&"object"==typeof e}(e)&&!function(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||function(e){return e.$$typeof===n}(e)}(e)},n="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function r(e,t){return!1!==t.clone&&t.isMergeableObject(e)?l((n=e,Array.isArray(n)?[]:{}),e,t):e;var n}function o(e,t,n){return e.concat(t).map((function(e){return r(e,n)}))}function i(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter((function(t){return e.propertyIsEnumerable(t)})):[]}(e))}function a(e,t){try{return t in e}catch(e){return!1}}function l(e,n,u){(u=u||{}).arrayMerge=u.arrayMerge||o,u.isMergeableObject=u.isMergeableObject||t,u.cloneUnlessOtherwiseSpecified=r;var c=Array.isArray(n);return c===Array.isArray(e)?c?u.arrayMerge(e,n,u):function(e,t,n){var o={};return n.isMergeableObject(e)&&i(e).forEach((function(t){o[t]=r(e[t],n)})),i(t).forEach((function(i){(function(e,t){return a(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))})(e,i)||(a(e,i)&&n.isMergeableObject(t[i])?o[i]=function(e,t){if(!t.customMerge)return l;var n=t.customMerge(e);return"function"==typeof n?n:l}(i,n)(e[i],t[i],n):o[i]=r(t[i],n))})),o}(e,n,u):r(n,u)}l.all=function(e,t){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce((function(e,n){return l(e,n,t)}),{})};var u=l;e.exports=u},453:(e,t,n)=>{var r,o;!function(){var i,a,l,u,c,s,f,p,d,y,h,m,v,b,g,w,P,k,O,E,S,x,T,_,j,C=function(e){var t=new C.Index;return t.pipeline.add(C.trimmer,C.stopWordFilter,C.stemmer),e&&e.call(t,t),t};C.version="0.9.5",lunr=C,C.utils={},C.utils.warn=(i=this,function(e){i.console&&console.warn&&console.warn(e)}),C.utils.toString=function(e){return null==e?"":e.toString()},C.EventEmitter=function(){this.events={}},C.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach((function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)}),this)},C.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},C.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach((function(e){e.apply(void 0,t)}),this)}},C.EventEmitter.prototype.hasHandler=function(e){return e in this.events},C.tokenizer=function(e){if(!arguments.length||null==e)return[];if(Array.isArray(e)){var t=e.filter((function(e){return null!=e}));t=t.map((function(e){return C.utils.toString(e).toLowerCase()}));var n=[];return t.forEach((function(e){var t=e.split(C.tokenizer.seperator);n=n.concat(t)}),this),n}return e.toString().trim().toLowerCase().split(C.tokenizer.seperator)},C.tokenizer.defaultSeperator=/[\s\-]+/,C.tokenizer.seperator=C.tokenizer.defaultSeperator,C.tokenizer.setSeperator=function(e){null!=e&&"object"==typeof e&&(C.tokenizer.seperator=e)},C.tokenizer.resetSeperator=function(){C.tokenizer.seperator=C.tokenizer.defaultSeperator},C.tokenizer.getSeperator=function(){return C.tokenizer.seperator},C.Pipeline=function(){this._queue=[]},C.Pipeline.registeredFunctions={},C.Pipeline.registerFunction=function(e,t){t in C.Pipeline.registeredFunctions&&C.utils.warn("Overwriting existing registered function: "+t),e.label=t,C.Pipeline.registeredFunctions[t]=e},C.Pipeline.getRegisteredFunction=function(e){return e in C.Pipeline.registeredFunctions!=1?null:C.Pipeline.registeredFunctions[e]},C.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||C.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},C.Pipeline.load=function(e){var t=new C.Pipeline;return e.forEach((function(e){var n=C.Pipeline.getRegisteredFunction(e);if(!n)throw new Error("Cannot load un-registered function: "+e);t.add(n)})),t},C.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){C.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)}),this)},C.Pipeline.prototype.after=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var n=this._queue.indexOf(e);if(-1===n)throw new Error("Cannot find existingFn");this._queue.splice(n+1,0,t)},C.Pipeline.prototype.before=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var n=this._queue.indexOf(e);if(-1===n)throw new Error("Cannot find existingFn");this._queue.splice(n,0,t)},C.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},C.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,r=this._queue.length,o=0;o0&&t.push(e),n)"docs"!==r&&"df"!==r&&this.expandToken(e+r,t,n[r]);return t},C.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},C.Configuration=function(e,t){var n;if(e=e||"",null==t||null==t)throw new Error("fields should not be null");this.config={};try{n=JSON.parse(e),this.buildUserConfig(n,t)}catch(e){C.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(t)}},C.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach((function(e){this.config[e]={boost:1,bool:"OR",expand:!1}}),this)},C.Configuration.prototype.buildUserConfig=function(e,t){var n="OR",r=!1;if(this.reset(),"bool"in e&&(n=e.bool||n),"expand"in e&&(r=e.expand||r),"fields"in e)for(var o in e.fields)if(t.indexOf(o)>-1){var i=e.fields[o],a=r;null!=i.expand&&(a=i.expand),this.config[o]={boost:i.boost||0===i.boost?i.boost:1,bool:i.bool||n,expand:a}}else C.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(n,r,t)},C.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach((function(n){this.config[n]={boost:1,bool:e,expand:t}}),this)},C.Configuration.prototype.get=function(){return this.config},C.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(i===e)return o;ie&&(n=o),r=n-t,o=t+Math.floor(r/2),i=this.elements[o]}return i===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,r=n-t,o=t+Math.floor(r/2),i=this.elements[o];r>1;)ie&&(n=o),r=n-t,o=t+Math.floor(r/2),i=this.elements[o];return i>e?o:io-1||r>i-1);)a[n]!==l[r]?a[n]l[r]&&r++:(t.add(a[n]),n++,r++);return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,r;this.length>=e.length?(t=this,n=e):(t=e,n=this),r=t.clone();for(var o=0,i=n.toArray();o{function t(e,t){e.onload=function(){this.onerror=this.onload=null,t(null,e)},e.onerror=function(){this.onerror=this.onload=null,t(new Error("Failed to load "+this.src),e)}}function n(e,t){e.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||(this.onreadystatechange=null,t(null,e))}}e.exports=function(e,r,o){var i=document.head||document.getElementsByTagName("head")[0],a=document.createElement("script");"function"==typeof r&&(o=r,r={}),r=r||{},o=o||function(){},a.type=r.type||"text/javascript",a.charset=r.charset||"utf8",a.async=!("async"in r)||!!r.async,a.src=e,r.attrs&&function(e,t){for(var n in t)e.setAttribute(n,t[n])}(a,r.attrs),r.text&&(a.text=""+r.text),("onload"in a?t:n)(a,o),a.onload||t(a,o),i.appendChild(a)}},845:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=Number.isNaN||function(e){return"number"==typeof e&&e!=e};function o(e,t){if(e.length!==t.length)return!1;for(var n=0;n{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,i){for(var a,l,u=o(e),c=1;c{"use strict";var r=n(414);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:o};return n.PropTypes=n,n}},697:(e,t,n)=>{e.exports=n(703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},23:function(e,t,n){var r;e=n.nmd(e),r=function(){var e=null,t={};c("monochrome",null,[[0,0],[100,0]]),c("red",[-26,18],[[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]]),c("orange",[18,46],[[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]]),c("yellow",[46,62],[[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]]),c("green",[62,178],[[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]]),c("blue",[178,257],[[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]]),c("purple",[257,282],[[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]]),c("pink",[282,334],[[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]]);var n=[],r=function(t){if(void 0!==(t=t||{}).seed&&null!==t.seed&&t.seed===parseInt(t.seed,10))e=t.seed;else if("string"==typeof t.seed)e=function(e){for(var t=0,n=0;n!==e.length&&!(t>=Number.MAX_SAFE_INTEGER);n++)t+=e.charCodeAt(n);return t}(t.seed);else{if(void 0!==t.seed&&null!==t.seed)throw new TypeError("The seed value must be an integer or string");e=null}var l,u;if(null!==t.count&&void 0!==t.count){for(var c=t.count,f=[],d=0;df.length;){var y=r(t);null!==e&&(t.seed=e),f.push(y)}return t.count=c,f}return function(e,t){switch(t.format){case"hsvArray":return e;case"hslArray":return p(e);case"hsl":var n=p(e);return"hsl("+n[0]+", "+n[1]+"%, "+n[2]+"%)";case"hsla":var r=p(e),o=t.alpha||Math.random();return"hsla("+r[0]+", "+r[1]+"%, "+r[2]+"%, "+o+")";case"rgbArray":return s(e);case"rgb":return"rgb("+s(e).join(", ")+")";case"rgba":var i=s(e);return o=t.alpha||Math.random(),"rgba("+i.join(", ")+", "+o+")";default:return function(e){var t=s(e);function n(e){var t=e.toString(16);return 1==t.length?"0"+t:t}return"#"+n(t[0])+n(t[1])+n(t[2])}(e)}}([l=o(t),u=i(l,t),a(l,u,t)],t)};function o(e){if(n.length>0){var r=u(a=function(e){if(isNaN(e)){if("string"==typeof e)if(t[e]){var n=t[e];if(n.hueRange)return n.hueRange}else if(e.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i))return l(f(e)[0]).hueRange}else{var r=parseInt(e);if(r<360&&r>0)return l(e).hueRange}return[0,360]}(e.hue)),o=(a[1]-a[0])/n.length,i=parseInt((r-a[0])/o);return!0===n[i]?i=(i+2)%n.length:n[i]=!0,(r=u(a=[(a[0]+i*o)%359,(a[0]+(i+1)*o)%359]))<0&&(r=360+r),r}var a;return(r=u(a=function(e){if("number"==typeof parseInt(e)){var n=parseInt(e);if(n<360&&n>0)return[n,n]}if("string"==typeof e)if(t[e]){var r=t[e];if(r.hueRange)return r.hueRange}else if(e.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)){var o=f(e)[0];return[o,o]}return[0,360]}(e.hue)))<0&&(r=360+r),r}function i(e,t){if("monochrome"===t.hue)return 0;if("random"===t.luminosity)return u([0,100]);var n=function(e){return l(e).saturationRange}(e),r=n[0],o=n[1];switch(t.luminosity){case"bright":r=55;break;case"dark":r=o-10;break;case"light":o=55}return u([r,o])}function a(e,t,n){var r=function(e,t){for(var n=l(e).lowerBounds,r=0;r=o&&t<=a){var c=(u-i)/(a-o);return c*t+(i-c*o)}}return 0}(e,t),o=100;switch(n.luminosity){case"dark":o=r+20;break;case"light":r=(o+r)/2;break;case"random":r=0,o=100}return u([r,o])}function l(e){for(var n in e>=334&&e<=360&&(e-=360),t){var r=t[n];if(r.hueRange&&e>=r.hueRange[0]&&e<=r.hueRange[1])return t[n]}return"Color not found"}function u(t){if(null===e){var n=Math.random();return n+=.618033988749895,n%=1,Math.floor(t[0]+n*(t[1]+1-t[0]))}var r=t[1]||1,o=t[0]||0,i=(e=(9301*e+49297)%233280)/233280;return Math.floor(o+i*(r-o))}function c(e,n,r){var o=r[0][0],i=r[r.length-1][0],a=r[r.length-1][1],l=r[0][1];t[e]={hueRange:n,lowerBounds:r,saturationRange:[o,i],brightnessRange:[a,l]}}function s(e){var t=e[0];0===t&&(t=1),360===t&&(t=359),t/=360;var n=e[1]/100,r=e[2]/100,o=Math.floor(6*t),i=6*t-o,a=r*(1-n),l=r*(1-i*n),u=r*(1-(1-i)*n),c=256,s=256,f=256;switch(o){case 0:c=r,s=u,f=a;break;case 1:c=l,s=r,f=a;break;case 2:c=a,s=r,f=u;break;case 3:c=a,s=l,f=r;break;case 4:c=u,s=a,f=r;break;case 5:c=r,s=a,f=l}return[Math.floor(255*c),Math.floor(255*s),Math.floor(255*f)]}function f(e){e=3===(e=e.replace(/^#/,"")).length?e.replace(/(.)/g,"$1$1"):e;var t=parseInt(e.substr(0,2),16)/255,n=parseInt(e.substr(2,2),16)/255,r=parseInt(e.substr(4,2),16)/255,o=Math.max(t,n,r),i=o-Math.min(t,n,r),a=o?i/o:0;switch(o){case t:return[(n-r)/i%6*60||0,a,o];case n:return[60*((r-t)/i+2)||0,a,o];case r:return[60*((t-n)/i+4)||0,a,o]}}function p(e){var t=e[0],n=e[1]/100,r=e[2]/100,o=(2-n)*r;return[t,Math.round(n*r/(o<1?o:2-o)*1e4)/100,o/2*100]}return r}(),e&&e.exports&&(t=e.exports=r),t.randomColor=r},448:(e,t,n)=>{"use strict";var r=n(294),o=n(418),i=n(840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n