tractive-device-farm 2.1.2 → 2.1.4
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/lib/auth/middleware.js +14 -4
- package/lib/helpers.js +2 -2
- package/lib/plugin.js +20 -5
- package/lib/public/dashboard/asset-manifest.json +3 -3
- package/lib/public/dashboard/index.html +1 -1
- package/lib/public/dashboard/static/js/main.9652282b.chunk.js +2 -0
- package/lib/public/dashboard/static/js/main.9652282b.chunk.js.map +1 -0
- package/lib/public/version.txt +1 -1
- package/package.json +1 -1
- package/lib/commands/handle.js +0 -19
- package/lib/commands/index.js +0 -10
- package/lib/public/dashboard/static/js/main.f68d4156.chunk.js +0 -2
- package/lib/public/dashboard/static/js/main.f68d4156.chunk.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["reportWebVitals.ts","store/redux-action-types.ts","store/sagas/application-saga.ts","utils/logger.ts","store/sagas/polling-saga.ts","api/index.ts","api/sessions.ts","store/actions/session-actions.ts","store/sagas/session-saga.ts","api/builds.ts","store/actions/build-actions.ts","store/sagas/build-saga.ts","api/metrics.ts","store/actions/metrics-actions.ts","store/sagas/metrics-saga.ts","store/sagas/index.ts","utils/createReducer.ts","store/reducers/entities/sessions-reducer.ts","store/reducers/entities/logs-reducer.ts","store/reducers/entities/builds-reducer.ts","store/reducers/entities/metrics-reducer.ts","store/reducers/entities/index.ts","store/reducers/ui/app-initialised.tsx","store/reducers/ui/selected-reducer.ts","constants/themes.ts","store/reducers/ui/theme-reducer.ts","store/reducers/ui/filter-reducer.ts","store/reducers/ui/loaders.ts","store/reducers/ui/index.ts","store/reducers/root-reducer.ts","store/index.tsx","constants/routes.ts","constants/ui.ts","store/selectors/entities/sessions-selector.ts","components/UI/layouts/parallel-layout.tsx","components/UI/layouts/serial-layout.tsx","utils/ui.ts","components/UI/molecules/centered.tsx","components/UI/molecules/empty-message.tsx","components/UI/layouts/tab-layout.tsx","components/UI/organisms/session/session-capability-details.tsx","store/actions/polling-actions.ts","store/selectors/entities/logs-selector.ts","components/UI/atoms/checkbox.tsx","components/UI/atoms/input.tsx","components/UI/atoms/animation.tsx","components/UI/atoms/spinner.tsx","components/UI/atoms/icon.tsx","components/UI/atoms/code-viewer.tsx","components/UI/organisms/session/session-debug-log-entry.tsx","components/UI/organisms/session/session-debug-logs.tsx","components/UI/organisms/session/session-device-logs.tsx","utils/common-utils.ts","components/UI/organisms/session/session-text-logs-entry.tsx","components/UI/organisms/session/session-text-logs.tsx","store/selectors/ui/theme-selector.ts","components/UI/organisms/session/session-app-profiling.tsx","components/UI/organisms/http-log-details.tsx","components/UI/organisms/http-logs-table.tsx","components/UI/organisms/session/session-http-logs.tsx","components/UI/organisms/session/session-logs.tsx","components/UI/organisms/session/session-summary.tsx","components/UI/atoms/video-player.tsx","components/UI/organisms/session/session-video.tsx","components/UI/organisms/session/session-details-menu-items.tsx","components/UI/organisms/session/session-script-executor.tsx","components/UI/organisms/session/session-details.tsx","components/UI/organisms/session/session-card.tsx","constants/session.ts","store/selectors/ui/filter-selector.ts","components/UI/atoms/button.tsx","components/UI/atoms/select.tsx","components/UI/organisms/session/session-list-filter.tsx","components/UI/atoms/dropdown.tsx","utils/utility.ts","components/UI/organisms/session/session-list.tsx","store/selectors/entities/builds-selector.ts","components/UI/organisms/build/build-card.tsx","constants/build-filter-options.ts","components/UI/organisms/build/build-list-filter.tsx","components/UI/organisms/build/build-list.tsx","components/UI/organisms/header/header.tsx","assets/logo-tractive-white.png","components/templates/dashboard-template.tsx","components/pages/dashboard.tsx","components/UI/organisms/metrics/metrics-filters.tsx","components/UI/organisms/metrics/metrics-kpis.tsx","components/UI/organisms/metrics/metrics-trend-chart.tsx","components/UI/organisms/metrics/metrics-platform-split.tsx","components/UI/organisms/metrics/metrics-tables.tsx","store/selectors/entities/metrics-selector.ts","components/templates/metrics-template.tsx","components/pages/metrics.tsx","components/pages/page-not-found.tsx","components/UI/molecules/app-loader.tsx","App-router.tsx","index.tsx"],"names":["reportWebVitals","onPerfEntry","Function","then","_ref","getCLS","getFID","getFCP","getLCP","getTTFB","ReduxActionTypes","INIT_APP","INIT_SESSION_SAGA","INIT_BUILD_SAGA","FETCH_SESSIONS_INIT","FETCH_SESSIONS_SUCCESS","FETCH_SESSION","FETCH_SESSION_SUCCESS","SELECT_SESSION","DESELECT_SESSION","SET_SESSION_FILTER","DELETE_SESSION","DELETE_ALL_SESSION","PAUSE_SESSION","RUN_SCRIPT_FOR_SESSION","RUN_SCRIPT_FOR_SESSION_FINISH","RESET_SCRIPT_RESPONSE_FOR_SESSION","RESUME_SESSION","SESSION_STATE_CHANGE_FINISH","FETCH_SESSION_TEXT_LOG","FETCH_SESSION_TEXT_LOG_SUCCESS","FETCH_SESSION_DEVICE_LOG","FETCH_SESSION_DEVICE_LOG_SUCCESS","FETCH_SESSION_DEBUG_LOG","FETCH_SESSION_DEBUG_LOG_SUCCESS","FETCH_SESSION_HTTP_LOG","FETCH_SESSION_HTTP_LOG_SUCCESS","FETCH_SESSION_PROFILING_DATA","FETCH_SESSION_PROFILING_DATA_SUCCESS","FETCH_SESSIONS_BY_BUILD_ID","POLLING_INIT","POLLING_STOP","ADD_POLLING_TASK","REMOVE_POLLING_TASK","SESSION_DELETE_INIT","SESSION_DELETE_FINISH","FETCH_BUILD_INIT","FETCH_BUILD","FETCH_BUILD_SUCCESS","SET_BUILD_FILTER","SELECT_BUILD","DESELECT_BUILD","INIT_METRICS_SAGA","FETCH_METRICS_INIT","FETCH_METRICS_SUCCESS","FETCH_METRICS_FAILURE","SET_METRICS_FILTER","_callee","_regeneratorRuntime","wrap","_context","prev","next","put","type","stop","_marked","debug","payload","console","log","TaskScheduler","_marked2","mark","TaskExecutor","_marked3","TaskAggregator","_marked4","PollingSaga","getPollingChannel","secs","eventChannel","emit","interval","setInterval","clearInterval","pollingChannel","executionChannel","tasks","_iterator","_step","task","take","_createForOfIteratorHelper","s","n","done","value","t0","e","f","finish","action","_context2","sent","_loop","_context4","_yield$take","filteredTasks","_context3","find","push","abrupt","filter","length","Array","prototype","apply","delegateYield","taskAggregatorSaga","taskSchedulerSaga","taskExecutorSaga","_context5","channel","fork","call","close","cancel","defaultConfig","baseURL","paramsSerializer","params","qs","stringify","arrayFormat","TOKEN_KEY","axios","interceptors","request","use","config","_config$headers","token","window","localStorage","getItem","headers","Authorization","concat","response","error","_error$response","status","removeItem","_unused","here","location","pathname","search","assign","encodeURIComponent","Promise","reject","Api","_classCallCheck","_createClass","key","url","arguments","undefined","get","_objectSpread","data","catch","err","post","delete","base_url","process","SessionApi","filterParams","buildId","sessionId","script","timeoutMs","timeout","fetchSessionByBuildId","fetchSessionSuccess","setSelectedSession","fetchSessionTextLogs","fetchSessionDeviceLogs","fetchSessionDebugLogs","setSessionFilter","deleteSessionFinish","sessionStateChangeFinish","fetchSessions","fetchAllSessionsByBuild","fetchSession","fetchSessionTextLog","_marked5","fetchSessionDeviceLog","_marked6","fetchSessionDebugLog","_marked7","fetchSessionHttpLog","_marked8","deleteSession","_marked9","deleteAllSession","_marked0","pauseSession","_marked1","resumeSession","_marked10","fetchSessionProfileData","_marked11","runDriverScript","_marked12","sessions","omitBy","d","getAllSessions","success","count","result","rows","filters","build_id","providedBuildId","rest","warn","_objectWithoutProperties","_excluded","getSessionsByBuild","getSessionById","logs","getTextLogsForSession","getDeviceLogsForSession","_context6","getDebugLogsForSession","_context7","getHttpLogsForSession","_context8","deleteSessionById","_context9","deleteAllSessions","_context0","_context1","_context10","getAppProfilingForSession","_context11","_context12","all","takeEvery","takeLatest","BuildApi","fetchBuildInit","fetchBuildSuccess","setSelectedBuild","fetchBuilds","fetchBuild","builds","getAllBuilds","build","getBuildById","MetricsApi","fetchMetricsSuccess","fetchMetricsFailure","fetchMetrics","v","getMetrics","initSaga","ApplicationSaga","BuildSaga","SessionSaga","MetricsSaga","createReducer","initialState","matchers","state","items","isLoading","_createReducer","_defineProperty","_action$payload","_action$payload2","text","device","profiling","http","days","combineReducers","SessionsReducer","BuildsReducer","LogsReducer","metrics","MetricsReducer","session","DEFAULT_THEME","name","light","colors","primary","secondary","tertiary","border","font","warning","tab_active_header","greyscale","controls","background","components","session_card_running_status","session_card_active_bg","session_card_default_bg","log_entry_hover","profiling_chart_system_cpu_border","profiling_chart_system_cpu_background","profiling_chart_app_cpu_border","profiling_chart_app_cpu_background","profiling_chart_system_memory_border","profiling_chart_system_memory_background","profiling_chart_app_memory_border","profiling_chart_app_memory_background","http_logs_table_bg","http_logs_table_border","http_logs_table_color","http_logs_table_header_bg","http_logs_table_header_color","http_logs_table_row_hover","http_logs_table_row_active","http_logs_table_even_row_bg","http_logs_table_icon_api","http_logs_table_icon_document","http_logs_table_icon_script","http_logs_details_header_active","fonts","size","M","L","XL","XXL","weight","borderRadius","device_udid","deviceName","user","project","platform_name","isPending","theme","ThemeReducer","selected","SelectedReducer","appInitialised","AppInitialised","sessionFilter","FilterReducer","buildFilter","loaders","LoaderReducer","entities","EntitiesReducer","ui","UiReducer","sagaMiddleware","createSagaMiddleware","createStore","rootReducer","composeWithDevTools","applyMiddleware","run","str","BASE_URL","RegExp","test","URL","getBuildDetailsUrl","id","METRICS_URL","APP_HEADER_HEIGHT","SUB_APP_HEADER_HEIGHT","getSessions","getIsSessionsLoading","getSelectedSession","isSessionDeleting","getSessionDeleteResponse","isStateChangePending","getSessionStateChangeResponse","isDriverScriptExecutionPending","getDriverScriptResult","GIRD_SIZE","ColumnContainer","styled","div","_templateObject","_taggedTemplateLiteral","props","grid","scrollable","padding","Column","children","className","_jsx","Container","_templateObject2","responsive","responsiveWidth","ParallelLayout","RowContainer","height","align","Row","heightOnResize","SerialLayout","_props$responsive","getHeaderStyle","Centered","EmptyMessageSize","Message","p","EmptyMessage","Banner","TabsContainer","Tab","TAB_HEADER_HEIGHT","TabsLayoutContainer","Header","_templateObject3","TabName","_templateObject4","active","Body","_templateObject5","TabsLayout","tabs","React","Children","forEach","useTabs","defaultTab","tab","_useState","useState","_useState2","_slicedToArray","selectedTabName","setSelectedTabName","selectedTab","_jsxs","map","onClick","TabChildContainer","Entry","Label","Value","getCapabilityEntries","capabilityObject","capabilities","desired","Object","keys","k","JSON","SessionCapabilityDetails","childHeight","addPollingTask","removePollingTask","getTextLogs","getisTextLogsLoading","getDeviceLogs","getisDeviceLogsLoading","getDebugLogs","getisDebugLogsLoading","getHttpLogs","getisHttpLogsLoading","getProfilingdata","getisProfilingLoading","Classes","CONTROL_INDICATOR","CheckboxComponent","checked","label","onChange","Checkbox","event","target","ICON_WIDTH","width","INPUT_GROUP","hasIcon","Input","_props$type","leftIcon","placeholder","rightElement","InputGroup","Animation","animationData","spinner","Lottie","Sizes","Spinner","span","color","Icon","icon","FaHome","FcAndroidOs","FaApple","SiSafari","FaChrome","FaAngleUp","FaAngleDown","FaCheckCircle","AiFillCloseCircle","BsClockFill","FaFilter","FaTrash","IoPhonePortraitOutline","BsFillExclamationTriangleFill","GiPauseButton","FaPlay","BiArrowFromRight","IoClose","AiFillCaretRight","AiFillCaretDown","TiDocumentText","AiOutlineApi","BsSquare","TiImage","SiCsswizardry","BsFileCode","GoTerminal","VscDebugAlt","FaRegStopCircle","SiPrettier","IoMdExpand","FiMinimize","FaChevronUp","FaChevronDown","tooltip","tooltipPosition","Tooltip","title","placement","arrow","classes","wrapIconWithTooltip","themes","github","githubTheme","nightOwl","nightOwlTheme","LineNo","Pre","pre","Highlight","CodeViewer","code","language","_props$theme","_props$lineNumber","lineNumber","defaultProps","style","tokens","getLineProps","getTokenProps","line","i","expandable","Content","Time","Expand","_templateObject6","CodeViewerWrapper","_templateObject7","SessionDebugLogEntry","entry","isExpanded","setIsExpanded","args","Moment","format","timestamp","message","StyledInput","SessionDebugLogs","parentHeight","filterText","setFilterText","useSelector","indexOf","useLogs","dispatch","useDispatch","_useState3","is_completed","_useState4","enablePolling","setEnablePolling","useEffect","session_id","togglePolling","useCallback","on","HEADER_HEIGHT","LogsEntry","SessionDeviceLogs","index","API_BASE","appendAuthToken","separator","includes","CommonUtils","startDate","endDate","Math","ceil","getTime","getReadableDuration","trim","seconds","round","levels","floor","returntext","max","_session$name","toLowerCase","os","session_status","_session$udid","udid","reduce","acc","urlParams","fromEntries","schema","obj","parsedObject","valid","isArray","_","isString","parse","logId","object","ParamsContainer","ParamsTitle","ErrorContainer","WarningContainer","StringValue","JsonValue","JsonEntryKey","ErrorNameLabel","_templateObject8","getLogBody","logTitle","logBody","getDuration","start_time","end_time","convertTimeToReadableFormat","Date","replace","_templateObject9","Title","_templateObject0","isError","chroma","brighten","hex","TitleInfo","_templateObject1","_templateObject10","TimeText","_templateObject11","_templateObject12","ScreenshotLink","a","_templateObject13","Screenshot","LazyLoadImage","_templateObject14","LogEntry","expanded","setExpanded","showScreenShots","is_error","title_info","screen_shot","href","getScreenshotForLog","log_id","src","effect","SessionTextLogs","setShowScreenShots","showExceptions","setShowExceptions","_useState5","_useState6","CheckBox","getSelectedTheme","ChartJS","register","CategoryScale","LinearScale","PointElement","LineElement","Legend","Filler","ChartRow","toMegaByte","Number","getCpuChartOptions","aspectRatio","plugins","legend","position","labels","usePointStyle","display","device_info","total_cpu","callbacks","context","dataset","parsed","y","parsing","xAxisKey","yAxisKey","scales","min","getCpuChartData","profilingData","datasets","cpu","total_cpu_used","fill","borderColor","backgroundColor","appPackage","getMemoryUsageChartOptions","totalMemoryInMB","total_memory","ticks","stepSize","getMemoryChartData","memory","total_memory_used","AppProfiling","processedData","getTimeDiffInSecs","created_at","uniqBy","useProfiling","Line","options","LogTabs","HeaderTab","LogBody","HttpHeaderTabAccordionContainer","HttpHeaderTabAccordionTitleContainer","HttpHeaderTabAccordionTitle","HttpHeaderTabAccordionBody","JsonRow","JsonKey","StyledEmptyMessage","HttpHeadersTab","header","expand","details","_props$showCount","showCount","toggleAccordion","useMemo","FORM_URL_ENCODED_CONTENT_TYPE","getPayloadElement","parseJson","HttpLogDetails","onClose","HEADERS","activeTab","setActiveTab","PAYLOAD","RESPONSE","onTabChange","tabHeader","bodyContent","Method","method","response_status","response_status_text","request_headers","response_headers","response_body","response_content_type","request_post_data","request_content_type","getBody","Table","table","TableHead","thead","TableBody","tbody","TH","th","TR","tr","failed","TD","td","LogDetailsContainer","UrlIconContainer","UrlName","columns","getComponent","row","path","split","pop","searchParams","getIcon","request_type","logType","iconSize","S","themeComponent","getColumns","isLogsSelected","getHeader","isLogSelected","c","getRows","selectedLog","onLogSelected","l","cells","isFunction","getCellValue","isFailure","HttpLogsTable","setSelectedLog","HeaderContainer","LogTypeFilterContainer","LogTypeFilterItem","isSelected","requestTypeFilters","filterRegex","SessionHttpLogs","selectedRequestTypeFilter","setSelectedRequestTypeFilter","textFilter","setTextFilter","opts","_opts$requestTypeFilt","requestTypeFilterId","typeFilter","filterFn","_toConsumableArray","onRequestTypeFilterChange","onTextFilterChange","TAB_HEADERS","SessionLogs","TEXTLOGS","DEVICELOGS","DEBUGLOGS","is_profiling_available","PROFILING","Profiling","is_http_logs_available","NETWORK","SUMMARY_CONFIG","android","ios","formatValue","or","app","safari","chrome","browser_name","getEntry","template","SessionSummary","VideoContainer","StyledVideo","video","DownloadButton","VideoPlayer","downloadUrl","controlsList","download","EmptyVideoContainer","LiveVideoContainer","VideoImg","img","hide","LoadingContainer","LiveBadge","VideoResizeIcon","getVideoNotFoundMessage","SessionVideo","onVideoSizeChanged","isFullScreen","liveStreamLoading","setLiveStreamLoading","liveStreamError","setLiveStreamError","imageLoaded","errored","live_stream_port","getLiveVideoForSession","onLoad","onError","_Fragment","video_path","getDownloadVideoForSession","getVideoForSession","IconGroup","IconContainer","sessionMenuItems","paused","debugging","onStateChanged","onDebuggingToggled","deletePending","stateChangePending","deleteResponse","stateChangeResponse","debugToggleChange","onPause","onResume","onDelete","toast","autoClose","hideProgressBar","closeOnClick","pauseOnHover","draggable","progress","ToastContainer","SpinnerSize","FlexContainer","EditorContainer","EditorHeader","EditorControls","TextWithIcon","RunButton","ConsoleContainer","ConsoleHeader","ConsoleHeaderLabel","ConsoleBody","ConsoleEntry","DEFAULT_SCRIPT","SessionScriptExecutor","isRunning","driverScriptResult","setScript","showConsole","setShowConsole","getLogs","rawLogs","level","Boolean","m","mIndex","stack","IconSize","jsBeautify","indent_size","space_in_empty_paren","XS","CodeMirror","extensions","javascript","onScriptChanged","HEADER","Name","ProgressIndicator","RunningProgressIndicator","PausedProgressIndicator","SummaryContainer","SummaryCollapseIcon","RESPONSIVE_WIDTH","hasSessionFailureMessage","session_status_message","getLoadingIndicator","isPaused","SessionDetails","is_paused","setPaused","isDebugging","setIsDebugging","isVideoFullscreen","setIsVideFullScreen","_useState7","_useState8","hideSummary","setHideSummary","onToggleSummary","MAIN_CONTENT_CONTAINER_HEIGHT","getSessiobDetailsMainContainerHeight","videoHeight","SessionMenuItems","onDebuggerToggle","onSessionStateChange","getStatusIcon","getTilte","platform_version","ExecutionTime","StausColor","StatusIcon","StatusLabel","DeviceName","SessionCard","device_name","formattedStartTime","history","useHistory","STATUS","DEVICE_FILTERS","getSessionFilterCount","values","getSessionFilters","getBuildFilterCount","getBuildFilters","StyledButtonComponent","ButtonComponent","variant","Button","_props$variant","StyledSelect","SelectComponent","getOption","option","Select","isMultiple","_props$multiple","multiple","massagedOption","hash","onSelectChange","MenuItem","Control","Actions","StyledButton","SessionListFilter","onApply","platform","filterState","setStatus","setUuid","showClearButton","setShowClearButton","setDeviceName","deviceNames","reset","some","val","selectedDeviceUDID","Trigger","Dropdown","_props$id","_props$vertical","vertical","_props$horizontal","horizontal","controlled","open","onOpen","anchorEl","useRef","_React$useState","_React$useState2","isOpen","setIsOpen","ref","Popover","current","anchorOrigin","extractBuildIdFromUrl","matches","match","List","FilterTrigger","FilterTriggerLabel","FilterDropdown","StyledBadge","Badge","getFiltersFromQueryParams","searchQuery","URLSearchParams","allowedFilters","dateString","isNaN","getDate","Utils","parseJsonSchema","urlParamsToObject","SessionList","_filteredSessions$","_filteredSessions$$pl","selectedSession","isFilterOpen","setIsFilterOpen","filterCount","effectiveBuildId","setEffectiveBuildId","rawBuildId","stableUrlFilters","setFilter","finalPayload","filteredSessions","badgeContent","getBuilds","getSelectedBuild","getBuildStatusIcon","running","BuildCard","build_name","paddingRight","total","PLATFORM","PROJECT","USER","BuildListFilter","setUser","setProject","platformName","setPlatformName","BuildList","urlFilters","selectedBuild","setBuildFilter","alt","NavLink","exact","to","activeClassName","isActive","startsWith","DashboardTemplate","useLocation","extractSessionidFromUrl","buildIdFromUrl","matchedSession","matchingBuild","b","sessionsUrl","Router","Switch","Route","Dashboard","Bar","Group","Chip","button","input","RANGES","PLATFORMS","MetricsFiltersBar","platformSet","Set","r","has","add","from","join","togglePlatform","app_version","Grid","Card","accent","Sub","fmtDuration","toFixed","MetricsKpiRow","kpis","passColor","pass_rate","toLocaleString","passed","avg_duration_sec","flaky_rate","flaky_tests","unique_builds","unique_app_versions","BarElement","Title2","ChartBox","baseOptions","maintainAspectRatio","interaction","mode","intersect","boxWidth","borderWidth","titleColor","bodyColor","x","maxRotation","autoSkip","beginAtZero","PassFailTrend","trend","day","slice","stacked","DurationTrend","_ref2","tension","pointRadius","ArcElement","Stats","Dot","COLORS","MetricsPlatformSplitView","fontSize","chartData","Doughnut","cutout","TableInner","Pill","Empty","passRateColor","rate","TopFailingTestsTable","last_failure_at","moment","fromNow","DeviceReliabilityTable","BuildHealthTable","_ref3","AppVersionTable","_ref4","getMetricsData","getMetricsFilter","getIsMetricsLoading","getMetricsError","Page","PageHeading","h1","SubHeading","TwoCol","FullRow","Center","ErrorBox","MetricsTemplate","patch","platform_split","build_health","top_failing_tests","app_versions","device_reliability","Metrics","PageNotFound","AppLoader","connect","isAppInitialised","ThemeProvider","component","ReactDOM","render","StrictMode","Provider","store","Store","AppRouter","document","getElementById"],"mappings":"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","file":"static/js/main.9652282b.chunk.js","sourcesContent":["import { ReportHandler } from \"web-vitals\";\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import(\"web-vitals\").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","const ReduxActionTypes = {\n INIT_APP: \"INIT_APP\",\n INIT_SESSION_SAGA: \"INIT_SESSION_SAGA\",\n INIT_BUILD_SAGA: \"INIT_BUILD_SAGA\",\n\n //Session\n FETCH_SESSIONS_INIT: \"FETCH_SESSION_INIT\",\n FETCH_SESSIONS_SUCCESS: \"FETCH_SESSION_SUCCESS\",\n FETCH_SESSION: \"FETCH_SESSION\",\n FETCH_SESSION_SUCCESS: \"FETCH_SESSION_SUCCESS\",\n SELECT_SESSION: \"SELECT_SESSION\",\n DESELECT_SESSION: \"DESELECT_SESSION\",\n SET_SESSION_FILTER: \"SET_SESSION_FILTER\",\n DELETE_SESSION: \"DELETE_SESSION\",\n DELETE_ALL_SESSION: \"DELETE_ALL_SESSION\",\n PAUSE_SESSION: \"PAUSE_SESSION\",\n RUN_SCRIPT_FOR_SESSION: \"RUN_SCRIPT_FOR_SESSION\",\n RUN_SCRIPT_FOR_SESSION_FINISH: \"RUN_SCRIPT_FOR_SESSION_FINISH\",\n RESET_SCRIPT_RESPONSE_FOR_SESSION: \"RESET_SCRIPT_RESPONSE_FOR_SESSION\",\n RESUME_SESSION: \"RESUME_SESSION\",\n SESSION_STATE_CHANGE_FINISH: \"SESSION_STATE_CHANGE_FINISH\",\n //Logs\n FETCH_SESSION_TEXT_LOG: \"FETCH_SESSION_TEXT_LOG\",\n FETCH_SESSION_TEXT_LOG_SUCCESS: \"FETCH_SESSION_TEXT_LOG_SUCCESS\",\n FETCH_SESSION_DEVICE_LOG: \"FETCH_SESSION_DEVICE_LOG\",\n FETCH_SESSION_DEVICE_LOG_SUCCESS: \"FETCH_SESSION_DEVICE_LOG_SUCCESS\",\n FETCH_SESSION_DEBUG_LOG: \"FETCH_SESSION_DEBUG_LOG\",\n FETCH_SESSION_DEBUG_LOG_SUCCESS: \"FETCH_SESSION_DEBUG_LOG_SUCCESS\",\n FETCH_SESSION_HTTP_LOG: \"FETCH_SESSION_HTTP_LOG\",\n FETCH_SESSION_HTTP_LOG_SUCCESS: \"FETCH_SESSION_HTTP_LOG_SUCCESS\",\n FETCH_SESSION_PROFILING_DATA: \"FETCH_SESSION_PROFILING_DATA\",\n FETCH_SESSION_PROFILING_DATA_SUCCESS: \"FETCH_SESSION_PROFILING_DATA_SUCCESS\",\n FETCH_SESSIONS_BY_BUILD_ID :\"FETCH_SESSIONS_BY_BUILD_ID\",\n\n //polling\n POLLING_INIT: \"POLLING_INIT\",\n POLLING_STOP: \"POLLING_STOP\",\n ADD_POLLING_TASK: \"ADD_POLLING_TASK\",\n REMOVE_POLLING_TASK: \"REMOVE_POLLING_TASK\",\n\n //loaders\n SESSION_DELETE_INIT: \"SESSION_DELETE_INIT\",\n SESSION_DELETE_FINISH: \"SESSION_DELETE_FINISH\",\n\n //Builds,\n FETCH_BUILD_INIT: \"FETCH_BUILD_INIT\",\n FETCH_BUILD : \"FETCH_BUILD\",\n FETCH_BUILD_SUCCESS: \"FETCH_BUILD_SUCCESS\",\n SET_BUILD_FILTER: \"SET_BUILD_FILTER\",\n SELECT_BUILD: \"SELECT_BUILD\",\n DESELECT_BUILD: \"DESELECT_BUILD\",\n\n //Metrics\n INIT_METRICS_SAGA: \"INIT_METRICS_SAGA\",\n FETCH_METRICS_INIT: \"FETCH_METRICS_INIT\",\n FETCH_METRICS_SUCCESS: \"FETCH_METRICS_SUCCESS\",\n FETCH_METRICS_FAILURE: \"FETCH_METRICS_FAILURE\",\n SET_METRICS_FILTER: \"SET_METRICS_FILTER\",\n};\n\nexport default ReduxActionTypes;\n","import { put } from \"redux-saga/effects\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nexport default function* () {\n yield put({\n type: ReduxActionTypes.INIT_SESSION_SAGA,\n });\n yield put({\n type: ReduxActionTypes.INIT_BUILD_SAGA,\n });\n yield put({\n type: ReduxActionTypes.POLLING_INIT,\n });\n yield put({\n type: ReduxActionTypes.INIT_METRICS_SAGA,\n });\n}\n","export default function debug(payload: any) {\n console.log(payload);\n}\n","import { Channel, channel, EventChannel, eventChannel, Task } from \"redux-saga\";\nimport {\n call,\n CallEffect,\n cancel,\n CancelEffect,\n ChannelPutEffect,\n ChannelTakeEffect,\n fork,\n ForkEffect,\n put,\n take,\n TakeEffect,\n} from \"redux-saga/effects\";\nimport { ReduxActionType } from \"../../interfaces/redux\";\nimport debug from \"../../utils/logger\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nfunction getPollingChannel(secs: number): EventChannel<string> {\n return eventChannel((emit) => {\n const interval = setInterval(() => {\n emit(\"\");\n }, secs);\n return () => {\n clearInterval(interval);\n };\n });\n}\n\nfunction* TaskScheduler(\n pollingChannel: EventChannel<string>,\n executionChannel: Channel<any>,\n tasks: TasksType,\n): Generator<ChannelTakeEffect<string> | ChannelPutEffect<any>> {\n debug(\"Scheduler Ready\");\n while (true) {\n yield take(pollingChannel);\n for (const task of tasks) {\n yield put(executionChannel, task);\n }\n debug(\"scheduled tasks\");\n }\n}\n\nfunction* TaskExecutor(executionChannel: Channel<any>): Generator<any> {\n debug(\"Executor Ready\");\n while (true) {\n const action = yield take(executionChannel);\n yield put(action as ReduxActionType<any>);\n debug(\"executed tasks\");\n }\n}\n\nfunction* TaskAggregator(tasks: TasksType) {\n debug(\"Aggregator Ready\");\n while (true) {\n const { type, payload } = yield take([\n ReduxActionTypes.ADD_POLLING_TASK,\n ReduxActionTypes.REMOVE_POLLING_TASK,\n ]);\n debug(tasks);\n\n switch (type) {\n case ReduxActionTypes.ADD_POLLING_TASK:\n const task = tasks.find((task) => task.type === payload.type);\n\n if (!task) {\n tasks.push(payload);\n } else {\n debug(\"Duplicate task was scheduled\");\n }\n break;\n case ReduxActionTypes.REMOVE_POLLING_TASK:\n // TODO: optimize following line\n const filteredTasks = tasks.filter(\n (task) => task.type !== payload.type,\n );\n tasks.length = 0;\n Array.prototype.push.apply(tasks, filteredTasks);\n break;\n }\n debug(tasks);\n }\n}\n\nconst INTERVAL_IN_MS = 10000;\n\ntype TasksType = Array<ReduxActionType<any>>;\n\nexport default function* PollingSaga(): Generator<\n ForkEffect | TakeEffect | CallEffect | CancelEffect\n> {\n const pollingChannel = getPollingChannel(INTERVAL_IN_MS);\n const tasks: TasksType = [];\n const executionChannel = channel();\n const taskAggregatorSaga = yield fork(TaskAggregator, tasks);\n const taskSchedulerSaga = yield fork(\n TaskScheduler,\n pollingChannel,\n executionChannel,\n tasks,\n );\n const taskExecutorSaga = yield fork(TaskExecutor, executionChannel);\n // Listen for event to stop polling\n yield take(ReduxActionTypes.POLLING_STOP);\n yield call(pollingChannel.close);\n yield cancel(taskAggregatorSaga as Task);\n yield cancel(taskSchedulerSaga as Task);\n yield cancel(taskExecutorSaga as Task);\n}\n","import axios, { AxiosRequestConfig } from \"axios\";\nimport qs from \"qs\";\n\n// API is always mounted at /device-farm/api in the merged plugin. The router\n// base in constants/routes.ts is driven by REACT_APP_API_BASE_URL separately\n// (which points at /device-farm/dashboard).\nconst defaultConfig = {\n baseURL: '/device-farm/api',\n};\n\nfunction paramsSerializer(params: any) {\n return qs.stringify(params, { arrayFormat: \"comma\" });\n}\n\n// Bearer-token plumbing. The token is set by the device-farm dashboard's\n// login page (same origin → shared localStorage), so this side just reads it\n// and attaches the header. On a 401 from any request we drop the token and\n// bounce the user to the device-farm login.\nconst TOKEN_KEY = \"df_token\";\n\naxios.interceptors.request.use((config) => {\n const token = window.localStorage.getItem(TOKEN_KEY);\n if (token) {\n config.headers = config.headers ?? {};\n (config.headers as any).Authorization = `Bearer ${token}`;\n }\n return config;\n});\n\naxios.interceptors.response.use(\n (response) => response,\n (error) => {\n if (error?.response?.status === 401) {\n try {\n window.localStorage.removeItem(TOKEN_KEY);\n } catch {\n // ignore\n }\n const here = window.location.pathname + window.location.search;\n window.location.assign(`/device-farm/login?from=${encodeURIComponent(here)}`);\n }\n return Promise.reject(error);\n },\n);\n\nexport default class Api {\n static base_url = process.env.REACT_APP_API_BASE_URL;\n\n static get(\n url: string,\n params?: any,\n config: Partial<AxiosRequestConfig> = {},\n ) {\n return axios\n .get(url, {\n ...defaultConfig,\n ...config,\n params,\n paramsSerializer,\n })\n .then((response) => response.data)\n .catch((err) => err.response.data);\n }\n\n static post(\n url: string,\n payload: any = {},\n params?: any,\n config: Partial<AxiosRequestConfig> = {},\n ) {\n return axios\n .post(url, payload, {\n ...defaultConfig,\n ...config,\n params,\n paramsSerializer,\n })\n .then((response) => response.data)\n .catch((err) => err.response.data);\n }\n\n static delete(\n url: string,\n params?: any,\n config: Partial<AxiosRequestConfig> = {},\n ) {\n return axios\n .delete(url, {\n ...defaultConfig,\n ...config,\n params,\n paramsSerializer,\n })\n .then((response) => response.data)\n .catch((err) => err.response.data);\n }\n}\n","import Api from \"./index\";\n\ntype ListResponse = {\n result: {\n count: number;\n rows: any[];\n };\n};\n\nexport default class SessionApi {\n public static getAllSessions(\n filterParams?: Record<string, string>,\n ): Promise<ListResponse> {\n return Api.get(\"/sessions\", filterParams || {});\n }\n\n public static getSessionsByBuild(buildId: string,filterParams?: Record<string, string>,){\n return Api.get(`/builds/${buildId}/sessions`,filterParams || {});\n }\n\n public static getTextLogsForSession(\n sessionId: string,\n ): Promise<ListResponse> {\n return Api.get(`/sessions/${sessionId}/logs/text`, {});\n }\n\n public static getDeviceLogsForSession(\n sessionId: string,\n ): Promise<ListResponse> {\n return Api.get(`/sessions/${sessionId}/logs/device`, {});\n }\n\n public static getDebugLogsForSession(\n sessionId: string,\n ): Promise<ListResponse> {\n return Api.get(`/sessions/${sessionId}/logs/debug`, {});\n }\n\n public static getSessionById(sessionId: string) {\n return Api.get(`/sessions/${sessionId}`, {});\n }\n\n public static deleteSessionById(sessionId: string) {\n return Api.delete(`/sessions/${sessionId}`);\n }\n\n public static deleteAllSessions() {\n return Api.delete(`/sessions`);\n }\n\n public static getSessionTextLogs(sessionId: string) {\n return Api.get(`/sessions/${sessionId}/logs/text`, {});\n }\n\n public static pauseSession(sessionId: string) {\n return Api.post(`/debug/${sessionId}/pause`, {});\n }\n\n public static resumeSession(sessionId: string) {\n return Api.post(`/debug/${sessionId}/play`, {});\n }\n\n public static getAppProfilingForSession(sessionId: string) {\n return Api.get(`/sessions/${sessionId}/profiling_data`);\n }\n\n public static getHttpLogsForSession(sessionId: string) {\n return Api.get(`/sessions/${sessionId}/http_logs`);\n }\n\n public static runDriverScript({\n sessionId,\n script,\n timeoutMs,\n }: {\n sessionId: string;\n script: string;\n timeoutMs?: number;\n }) {\n return Api.post(`/debug/${sessionId}/execute_driver_script`, {\n script,\n timeout: timeoutMs,\n });\n }\n}\n","import { PaginatedResponse } from \"../../interfaces/api\";\nimport { ReduxActionType } from \"../../interfaces/redux\";\nimport Session from \"../../interfaces/session\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nexport const fetchSessionInit = (payload?: any) => ({\n type: ReduxActionTypes.FETCH_SESSIONS_INIT,\n payload,\n});\n\nexport const fetchSessionsSuccess = (payload: PaginatedResponse<Session>) => ({\n type: ReduxActionTypes.FETCH_SESSIONS_SUCCESS,\n payload,\n});\n\nexport const fetchSessionByBuildId = (payload?: any) => ({\n type: ReduxActionTypes.FETCH_SESSIONS_BY_BUILD_ID,\n payload,\n});\n\nexport const fetchSessionSuccess = (payload: Session) => ({\n type: ReduxActionTypes.FETCH_SESSION_SUCCESS,\n payload,\n});\n\nexport const setSelectedSession = (payload: Session | null) => ({\n type: ReduxActionTypes.SELECT_SESSION,\n payload,\n});\n\nexport const fetchSessionTextLogs = (\n payload: string,\n): ReduxActionType<string> => ({\n type: ReduxActionTypes.FETCH_SESSION_TEXT_LOG,\n payload,\n});\n\nexport const fetchSessionTextLogsSuccess = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_TEXT_LOG_SUCCESS,\n payload,\n});\n\nexport const fetchSessionDeviceLogs = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_DEVICE_LOG,\n payload,\n});\n\nexport const fetchSessionDeviceLogsSuccess = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_DEVICE_LOG_SUCCESS,\n payload,\n});\n\nexport const fetchSessionDebugLogs = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_DEBUG_LOG,\n payload,\n});\n\nexport const fetchSessionDebugLogsSuccess = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_DEBUG_LOG_SUCCESS,\n payload,\n});\n\nexport const fetchSessionHttpLogs = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_HTTP_LOG,\n payload,\n});\n\nexport const fetchSessionHttpLogsSuccess = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_HTTP_LOG_SUCCESS,\n payload,\n});\n\nexport const fetchSessionProfilingData = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_PROFILING_DATA,\n payload,\n});\n\nexport const fetchSessionProfilingDataSuccess = (payload: any) => ({\n type: ReduxActionTypes.FETCH_SESSION_PROFILING_DATA_SUCCESS,\n payload,\n});\n\nexport const setSessionFilter = (payload: any) => ({\n type: ReduxActionTypes.SET_SESSION_FILTER,\n payload,\n});\n\nexport const deleteSession = (payload: string) => ({\n type: ReduxActionTypes.DELETE_SESSION,\n payload,\n});\n\nexport const deleteAllSession = () => ({\n type: ReduxActionTypes.DELETE_ALL_SESSION,\n});\n\nexport const deleteSessionFinish = (payload: any) => ({\n type: ReduxActionTypes.SESSION_DELETE_FINISH,\n payload,\n});\n\nexport const pauseSession = (payload: string) => ({\n type: ReduxActionTypes.PAUSE_SESSION,\n payload,\n});\n\nexport const resumeSession = (payload: string) => ({\n type: ReduxActionTypes.RESUME_SESSION,\n payload,\n});\n\nexport const sessionStateChangeFinish = (payload: any) => ({\n type: ReduxActionTypes.SESSION_STATE_CHANGE_FINISH,\n payload,\n});\n\nexport const runDriverScript = (payload: any) => ({\n type: ReduxActionTypes.RUN_SCRIPT_FOR_SESSION,\n payload,\n});\n\nexport const sessionScriptExecutionFinish = (payload: any) => ({\n type: ReduxActionTypes.RUN_SCRIPT_FOR_SESSION_FINISH,\n payload,\n});\n\nexport const sessionScriptExecutionReset = (payload: any) => ({\n type: ReduxActionTypes.RESET_SCRIPT_RESPONSE_FOR_SESSION,\n payload,\n});\n","import { all, put, takeEvery, takeLatest } from \"redux-saga/effects\";\nimport SessionApi from \"../../api/sessions\";\nimport { ApiResponse, PaginatedResponse } from \"../../interfaces/api\";\nimport { ReduxActionType } from \"../../interfaces/redux\";\nimport Session from \"../../interfaces/session\";\nimport {\n fetchSessionSuccess,\n fetchSessionTextLogsSuccess,\n fetchSessionDeviceLogsSuccess,\n fetchSessionDebugLogsSuccess,\n deleteSessionFinish,\n sessionStateChangeFinish,\n fetchSessionProfilingDataSuccess,\n fetchSessionHttpLogsSuccess,\n sessionScriptExecutionFinish, fetchSessionByBuildId\n} from \"../actions/session-actions\";\nimport ReduxActionTypes from \"../redux-action-types\";\nimport { omitBy } from \"lodash\";\n\nfunction* fetchSessions(action?: ReduxActionType<Record<string, string>>) {\n const payload = omitBy(action?.payload, (d) => !d);\n const sessions: ApiResponse<PaginatedResponse<Session>> =\n yield SessionApi.getAllSessions(payload);\n if (sessions.success) {\n yield put(\n fetchSessionSuccess({\n count: sessions.result.count,\n rows: sessions.result.rows,\n }),\n );\n }\n}\n\nfunction* fetchAllSessionsByBuild(action: ReduxActionType<any>) {\n if (!action || !action.payload) {\n console.warn(\"[fetchAllSessionsByBuild] Missing payload, skipping fetch\");\n return;\n }\n\n const payload = action.payload;\n\n let filters: Record<string, any> = {};\n let buildId: string | undefined;\n\n //Handle both string and object payloads\n if (typeof payload === \"string\") {\n buildId = payload; // direct buildId\n } else if (typeof payload === \"object\") {\n const { build_id, buildId: providedBuildId, ...rest } = payload;\n buildId = providedBuildId || build_id;\n filters = rest;\n }\n\n //Now check for buildId\n if (!buildId) {\n console.warn(\"[fetchAllSessionsByBuild] Missing buildId, skipping fetch\");\n console.log(\"payload:\", payload);\n return;\n }\n\n //Fetch sessions scoped to that build\n const sessions: ApiResponse<PaginatedResponse<Session>> =\n yield SessionApi.getSessionsByBuild(buildId, filters);\n\n if (sessions && sessions.success) {\n yield put(\n fetchSessionSuccess({\n count: sessions.result.count,\n rows: sessions.result.rows,\n })\n );\n }\n}\n\n\nfunction* fetchSession(action: ReduxActionType<string>) {\n if (action.payload) {\n const sessions: ApiResponse<Session> = yield SessionApi.getSessionById(\n action.payload,\n );\n if (sessions.success) {\n yield put(fetchSessionSuccess(sessions.result));\n }\n }\n}\n\nfunction* fetchSessionTextLog(action: ReduxActionType<string>) {\n if (action.payload) {\n const logs: ApiResponse<any> = yield SessionApi.getTextLogsForSession(\n action.payload,\n );\n if (logs.success) {\n yield put(fetchSessionTextLogsSuccess(logs.result));\n }\n }\n}\n\nfunction* fetchSessionDeviceLog(action: ReduxActionType<string>) {\n if (action.payload) {\n const logs: ApiResponse<any> = yield SessionApi.getDeviceLogsForSession(\n action.payload,\n );\n if (logs.success) {\n yield put(fetchSessionDeviceLogsSuccess(logs.result));\n }\n }\n}\n\nfunction* fetchSessionDebugLog(action: ReduxActionType<string>) {\n if (action.payload) {\n const logs: ApiResponse<any> = yield SessionApi.getDebugLogsForSession(\n action.payload,\n );\n if (logs.success) {\n yield put(fetchSessionDebugLogsSuccess(logs.result));\n }\n }\n}\n\nfunction* fetchSessionHttpLog(action: ReduxActionType<string>) {\n if (action.payload) {\n const logs: ApiResponse<any> = yield SessionApi.getHttpLogsForSession(\n action.payload,\n );\n if (logs.success) {\n yield put(fetchSessionHttpLogsSuccess(logs.result));\n }\n }\n}\n\nfunction* deleteSession(action: ReduxActionType<string>) {\n if (action.payload) {\n const response: ApiResponse<any> = yield SessionApi.deleteSessionById(\n action.payload,\n );\n yield put(deleteSessionFinish(response));\n }\n}\n\nfunction* deleteAllSession() {\n const response: ApiResponse<any> = yield SessionApi.deleteAllSessions();\n yield put(deleteSessionFinish(response));\n}\n\nfunction* pauseSession(action: ReduxActionType<string>) {\n if (action.payload) {\n const response: ApiResponse<any> = yield SessionApi.pauseSession(\n action.payload,\n );\n yield put(sessionStateChangeFinish(response));\n }\n}\n\nfunction* resumeSession(action: ReduxActionType<string>) {\n if (action.payload) {\n const response: ApiResponse<any> = yield SessionApi.resumeSession(\n action.payload,\n );\n yield put(sessionStateChangeFinish(response));\n }\n}\n\nfunction* fetchSessionProfileData(action: ReduxActionType<string>) {\n if (action.payload) {\n const response: ApiResponse<any> =\n yield SessionApi.getAppProfilingForSession(action.payload);\n yield put(\n fetchSessionProfilingDataSuccess({\n count: response.result.length,\n rows: response.result,\n }),\n );\n }\n}\n\nfunction* runDriverScript(\n action: ReduxActionType<{\n sessionId: string;\n script: string;\n timeoutMs?: number;\n }>,\n) {\n if (action.payload) {\n const response: ApiResponse<any> = yield SessionApi.runDriverScript(\n action.payload,\n );\n yield put(sessionScriptExecutionFinish(response.result));\n }\n}\n\nexport default function* () {\n yield all([\n takeEvery(ReduxActionTypes.FETCH_SESSIONS_INIT, fetchSessions),\n takeEvery(ReduxActionTypes.FETCH_SESSIONS_BY_BUILD_ID, fetchAllSessionsByBuild),\n takeLatest(ReduxActionTypes.FETCH_SESSION, fetchSession),\n takeLatest(ReduxActionTypes.FETCH_SESSION_TEXT_LOG, fetchSessionTextLog),\n takeLatest(\n ReduxActionTypes.FETCH_SESSION_DEVICE_LOG,\n fetchSessionDeviceLog,\n ),\n takeLatest(ReduxActionTypes.FETCH_SESSION_DEBUG_LOG, fetchSessionDebugLog),\n takeLatest(ReduxActionTypes.FETCH_SESSION_HTTP_LOG, fetchSessionHttpLog),\n takeLatest(\n ReduxActionTypes.FETCH_SESSION_PROFILING_DATA,\n fetchSessionProfileData,\n ),\n takeLatest(ReduxActionTypes.DELETE_SESSION, deleteSession),\n takeLatest(ReduxActionTypes.DELETE_ALL_SESSION, deleteAllSession),\n takeLatest(ReduxActionTypes.SET_SESSION_FILTER, fetchSessionByBuildId),\n takeLatest(ReduxActionTypes.PAUSE_SESSION, pauseSession),\n takeLatest(ReduxActionTypes.RESUME_SESSION, resumeSession),\n takeLatest(ReduxActionTypes.RUN_SCRIPT_FOR_SESSION, runDriverScript),\n ]);\n}\n","import Api from \"./index\";\n\ntype ListResponse = {\n result: {\n count: number;\n rows: any[];\n };\n};\n\nexport default class BuildApi{\n\n public static getAllBuilds(filterParams?: Record<string, string>):Promise<ListResponse>{\n return Api.get(\"/builds\",filterParams || {})\n }\n\n public static getBuildById(buildId: string) {\n return Api.get(`/builds/${buildId}`, {});\n }\n\n public static deleteAllBuilds() {\n return Api.delete(`/builds`);\n }\n\n}","import ReduxActionTypes from \"../redux-action-types\";\nimport Build from \"../../interfaces/build\";\n\nexport const fetchBuildInit = (payload?: any) => ({\n type: ReduxActionTypes.FETCH_BUILD_INIT,\n payload,\n});\n\nexport const setBuildFilter = (payload: any) => ({\n type: ReduxActionTypes.SET_BUILD_FILTER,\n payload,\n});\n\nexport const fetchBuildSuccess = (payload: Build) => ({\n type: ReduxActionTypes.FETCH_BUILD_SUCCESS,\n payload,\n});\n\nexport const setSelectedBuild = (payload: Build | null) => ({\n type: ReduxActionTypes.SELECT_BUILD,\n payload,\n});","import { ReduxActionType } from \"../../interfaces/redux\";\nimport { omitBy } from \"lodash\";\nimport { ApiResponse, PaginatedResponse } from \"../../interfaces/api\";\nimport { all, put, takeEvery, takeLatest } from \"redux-saga/effects\";\nimport BuildApi from \"../../api/builds\";\nimport ReduxActionTypes from \"../redux-action-types\";\nimport Build from \"../../interfaces/build\";\nimport { fetchBuildSuccess } from \"../actions/build-actions\";\n\nfunction* fetchBuilds(action?: ReduxActionType<Record<string, string>>) {\n const payload = omitBy(action?.payload, (d) => !d);\n const builds: ApiResponse<PaginatedResponse<Build>> =\n yield BuildApi.getAllBuilds(payload);\n if (builds.success) {\n yield put(\n fetchBuildSuccess({\n count: builds.result.count,\n rows: builds.result.rows,\n }),\n );\n }\n}\n\nfunction* fetchBuild(action: ReduxActionType<string>) {\n if (action.payload) {\n const build: ApiResponse<Build> = yield BuildApi.getBuildById(\n action.payload,\n );\n if (build.success) {\n yield put(fetchBuildSuccess(build.result));\n }\n }\n}\n\n\nexport default function* () {\n yield all([\n takeEvery(ReduxActionTypes.FETCH_BUILD_INIT, fetchBuilds),\n takeLatest(ReduxActionTypes.FETCH_BUILD, fetchBuild),\n takeLatest(ReduxActionTypes.SET_BUILD_FILTER, fetchBuilds),\n ]);\n}","import Api from \"./index\";\nimport { MetricsFilter, MetricsPayload } from \"../interfaces/metrics\";\nimport { ApiResponse } from \"../interfaces/api\";\n\nexport default class MetricsApi {\n public static getMetrics(\n filter?: MetricsFilter\n ): Promise<ApiResponse<MetricsPayload>> {\n return Api.get(\"/metrics\", filter || {});\n }\n}","import { MetricsFilter, MetricsPayload } from \"../../interfaces/metrics\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nexport const fetchMetricsInit = (payload?: MetricsFilter) => ({\n type: ReduxActionTypes.FETCH_METRICS_INIT,\n payload,\n});\n\nexport const fetchMetricsSuccess = (payload: MetricsPayload) => ({\n type: ReduxActionTypes.FETCH_METRICS_SUCCESS,\n payload,\n});\n\nexport const fetchMetricsFailure = (payload: string) => ({\n type: ReduxActionTypes.FETCH_METRICS_FAILURE,\n payload,\n});\n\nexport const setMetricsFilter = (payload: MetricsFilter) => ({\n type: ReduxActionTypes.SET_METRICS_FILTER,\n payload,\n});","import { all, put, takeLatest } from \"redux-saga/effects\";\nimport { omitBy } from \"lodash\";\nimport MetricsApi from \"../../api/metrics\";\nimport { ApiResponse } from \"../../interfaces/api\";\nimport { MetricsFilter, MetricsPayload } from \"../../interfaces/metrics\";\nimport { ReduxActionType } from \"../../interfaces/redux\";\nimport {\n fetchMetricsFailure,\n fetchMetricsSuccess,\n} from \"../actions/metrics-actions\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nfunction* fetchMetrics(action?: ReduxActionType<MetricsFilter>) {\n const payload = omitBy(\n action?.payload || {},\n (v) => v === undefined || v === null || v === \"\"\n ) as MetricsFilter;\n const response: ApiResponse<MetricsPayload> = yield MetricsApi.getMetrics(\n payload\n );\n if (response?.success) {\n yield put(fetchMetricsSuccess(response.result));\n } else {\n yield put(fetchMetricsFailure(\"Failed to load metrics\"));\n }\n}\n\nexport default function* () {\n yield all([\n takeLatest(ReduxActionTypes.FETCH_METRICS_INIT, fetchMetrics),\n takeLatest(ReduxActionTypes.SET_METRICS_FILTER, fetchMetrics),\n ]);\n}","import { all, takeLatest } from \"redux-saga/effects\";\nimport ReduxActionTypes from \"../redux-action-types\";\nimport ApplicationSaga from \"./application-saga\";\nimport PollingSaga from \"./polling-saga\";\nimport SessionSaga from \"./session-saga\";\nimport BuildSaga from \"./build-saga\";\nimport MetricsSaga from \"./metrics-saga\";\n\nexport default function* initSaga() {\n yield all([\n takeLatest(ReduxActionTypes.INIT_APP, ApplicationSaga),\n takeLatest(ReduxActionTypes.INIT_BUILD_SAGA, BuildSaga),\n takeLatest(ReduxActionTypes.INIT_SESSION_SAGA, SessionSaga),\n takeLatest(ReduxActionTypes.POLLING_INIT, PollingSaga),\n takeLatest(ReduxActionTypes.INIT_METRICS_SAGA, MetricsSaga),\n ]);\n}\n","import { ReduxActionType } from \"../interfaces/redux\";\n\ntype createReducerActions = {\n [key: string]: (state: any, action: ReduxActionType<any>) => any;\n};\n\nconst createReducer = (initialState: any, matchers: createReducerActions) => {\n return (state = initialState, action: ReduxActionType<any>) => {\n if (matchers[action.type]) {\n return matchers[action.type](state, action);\n } else {\n return state;\n }\n };\n};\n\nexport default createReducer;\n","import { ListEntityType } from \".\";\nimport { PaginatedResponse } from \"../../../interfaces/api\";\nimport { ReduxActionType } from \"../../../interfaces/redux\";\nimport Session from \"../../../interfaces/session\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type SessionEntityType = ListEntityType<Session>;\n\nconst initialState: SessionEntityType = {\n count: 0,\n items: [],\n isLoading: false,\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.FETCH_SESSIONS_INIT]: (state: SessionEntityType) => ({\n ...state,\n isLoading: true,\n }),\n [ReduxActionTypes.FETCH_SESSIONS_SUCCESS]: (\n state: SessionEntityType,\n action: ReduxActionType<PaginatedResponse<Session>>,\n ) => ({\n ...state,\n count: action.payload?.count,\n items: action.payload?.rows,\n isLoading: false,\n }),\n});\n","import { ListEntityType } from \".\";\nimport { ReduxActionType } from \"../../../interfaces/redux\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type LogsState = {\n text: ListEntityType<any>;\n device: ListEntityType<any>;\n debug: ListEntityType<any>;\n profiling: ListEntityType<any>;\n http: ListEntityType<any>;\n};\n\nconst initialState: LogsState = {\n text: {\n count: 0,\n items: [],\n isLoading: false,\n },\n device: {\n count: 0,\n items: [],\n isLoading: false,\n },\n debug: {\n count: 0,\n items: [],\n isLoading: false,\n },\n profiling: {\n count: 0,\n items: [],\n isLoading: false,\n },\n http: {\n count: 0,\n items: [],\n isLoading: false,\n },\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.FETCH_SESSION_TEXT_LOG]: (state: LogsState) => ({\n ...state,\n text: {\n ...state.text,\n isLoading: true,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_TEXT_LOG_SUCCESS]: (\n state: LogsState,\n action: ReduxActionType<any>,\n ) => ({\n ...state,\n text: {\n count: action.payload.count,\n items: action.payload.rows,\n isLoading: false,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_DEVICE_LOG]: (state: LogsState) => ({\n ...state,\n device: {\n ...state.device,\n isLoading: true,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_DEVICE_LOG_SUCCESS]: (\n state: LogsState,\n action: ReduxActionType<any>,\n ) => ({\n ...state,\n device: {\n count: action.payload.count,\n items: action.payload.rows,\n isLoading: false,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_DEBUG_LOG]: (state: LogsState) => ({\n ...state,\n debug: {\n ...state.debug,\n isLoading: true,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_DEBUG_LOG_SUCCESS]: (\n state: LogsState,\n action: ReduxActionType<any>,\n ) => ({\n ...state,\n debug: {\n count: action.payload.count,\n items: action.payload.rows,\n isLoading: false,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_HTTP_LOG]: (state: LogsState) => ({\n ...state,\n http: {\n ...state.http,\n isLoading: true,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_HTTP_LOG_SUCCESS]: (\n state: LogsState,\n action: ReduxActionType<any>,\n ) => ({\n ...state,\n http: {\n count: action.payload.count,\n items: action.payload.rows,\n isLoading: false,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_PROFILING_DATA]: (state: LogsState) => ({\n ...state,\n profiling: {\n ...state.profiling,\n isLoading: true,\n },\n }),\n [ReduxActionTypes.FETCH_SESSION_PROFILING_DATA_SUCCESS]: (\n state: LogsState,\n action: ReduxActionType<any>,\n ) => ({\n ...state,\n profiling: {\n count: action.payload.count,\n items: action.payload.rows,\n isLoading: false,\n },\n }),\n});\n","import { ListEntityType } from \".\";\nimport { PaginatedResponse } from \"../../../interfaces/api\";\nimport { ReduxActionType } from \"../../../interfaces/redux\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\nimport Build from \"../../../interfaces/build\";\n\nexport type BuildEntityType = ListEntityType<Build>;\n\nconst initialState: BuildEntityType = {\n count: 0,\n items: [],\n isLoading: false,\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.FETCH_BUILD_INIT]: (state: BuildEntityType) => ({\n ...state,\n isLoading: true,\n }),\n [ReduxActionTypes.FETCH_BUILD_SUCCESS]: (\n state: BuildEntityType,\n action: ReduxActionType<PaginatedResponse<Build>>,\n ) => ({\n ...state,\n count: action.payload?.count,\n items: action.payload?.rows,\n isLoading: false,\n }),\n});\n","import { ReduxActionType } from \"../../../interfaces/redux\";\nimport { MetricsFilter, MetricsPayload } from \"../../../interfaces/metrics\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type MetricsEntityType = {\n data: MetricsPayload | null;\n filter: MetricsFilter;\n isLoading: boolean;\n error: string | null;\n};\n\nconst initialState: MetricsEntityType = {\n data: null,\n filter: { days: 30 },\n isLoading: false,\n error: null,\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.FETCH_METRICS_INIT]: (state: MetricsEntityType) => ({\n ...state,\n isLoading: true,\n error: null,\n }),\n [ReduxActionTypes.FETCH_METRICS_SUCCESS]: (\n state: MetricsEntityType,\n action: ReduxActionType<MetricsPayload>\n ) => ({\n ...state,\n data: action.payload,\n isLoading: false,\n error: null,\n }),\n [ReduxActionTypes.FETCH_METRICS_FAILURE]: (\n state: MetricsEntityType,\n action: ReduxActionType<string>\n ) => ({\n ...state,\n isLoading: false,\n error: action.payload,\n }),\n [ReduxActionTypes.SET_METRICS_FILTER]: (\n state: MetricsEntityType,\n action: ReduxActionType<MetricsFilter>\n ) => ({\n ...state,\n filter: { ...state.filter, ...action.payload },\n }),\n});","import { combineReducers } from \"@reduxjs/toolkit\";\nimport SessionsReducer, { SessionEntityType } from \"./sessions-reducer\";\nimport LogsReducer, { LogsState } from \"./logs-reducer\";\nimport BuildsReducer, { BuildEntityType } from \"./builds-reducer\";\nimport MetricsReducer, { MetricsEntityType } from \"./metrics-reducer\";\n\nexport type ListEntityType<T> = {\n count: number;\n items: Array<T>;\n isLoading: boolean;\n};\n\nexport type EntitiesState = {\n sessions: SessionEntityType;\n builds: BuildEntityType;\n logs: LogsState;\n metrics: MetricsEntityType;\n};\n\nexport default combineReducers({\n sessions: SessionsReducer,\n builds: BuildsReducer,\n logs: LogsReducer,\n metrics: MetricsReducer,\n});\n","import createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type AppInitilisedState = boolean;\n\nconst InitialState = false;\n\nexport default createReducer(InitialState, {\n [ReduxActionTypes.INIT_APP]: () => true,\n});\n","import { AppState } from \"../..\";\nimport { ReduxActionType } from \"../../../interfaces/redux\";\nimport Session from \"../../../interfaces/session\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\nimport Build from \"../../../interfaces/build\";\n\nexport type SelectedState = {\n session: Session | null;\n build: Build | null;\n};\n\nconst initialState: SelectedState = {\n session: null,\n build : null\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.SELECT_SESSION]: (\n state: AppState,\n action: ReduxActionType<Session>,\n ) => ({\n ...state,\n session: action.payload,\n }),\n [ReduxActionTypes.DESELECT_SESSION]: (state: AppState) => ({\n ...state,\n session: null,\n }),\n\n /** Build **/\n [ReduxActionTypes.SELECT_BUILD]: (\n state: AppState,\n action: ReduxActionType<Build>,\n ) => ({\n ...state,\n build: action.payload,\n }),\n [ReduxActionTypes.DESELECT_BUILD]: (state: AppState) => ({\n ...state,\n build: null,\n }),\n});\n","type Color = string;\n\ntype ColorScale = [string, string, string, string, string, string, string];\n\nexport type ThemeConfig = {\n colors: Record<string, Record<string, Color> | Color | ColorScale>;\n fonts: Record<string, any>;\n borderRadius: Record<string, any>;\n};\n\n// Dark greyscale: [0]=primary text → [6]=main bg\nconst greyscale = [\n \"#dde1ef\", // [0] primary text (was #000000)\n \"#dde1ef\", // [1] primary text (was #333333)\n \"#8892a8\", // [2] secondary text (was #666666)\n \"#4a5068\", // [3] tertiary text / dim borders (was #999999)\n \"#1a1d28\", // [4] hover background (was #CCCCCC)\n \"#13151d\", // [5] surface / card bg (was #EEEEEE)\n \"#0c0d12\", // [6] main background (was #FFFFFF)\n] as ColorScale;\n\nconst LightTheme: ThemeConfig = {\n colors: {\n primary: \"#5b7fff\",\n secondary: \"#13151d\",\n tertiary: \"#1a1d28\",\n border: \"#1f2235\",\n font: \"#dde1ef\",\n success: \"#2dd975\",\n error: \"#f45858\",\n warning: \"#e8c14a\",\n tab_active_header: \"#5b7fff\",\n greyscale: greyscale,\n controls: {\n background: \"#1a1d28\",\n },\n components: {\n session_card_running_status: \"#5b7fff\",\n session_card_active_bg: \"#22263a\",\n session_card_default_bg: \"#13151d\",\n log_entry_hover: \"#1a1d28\",\n\n profiling_chart_system_cpu_border: \"rgb(194, 230, 153)\",\n profiling_chart_system_cpu_background: \"rgba(194, 230, 153, 0.3)\",\n profiling_chart_app_cpu_border: \"rgb(49, 163, 84)\",\n profiling_chart_app_cpu_background: \"rgba(49, 163, 84, 0.3)\",\n profiling_chart_system_memory_border: \"rgb(65, 182, 196)\",\n profiling_chart_system_memory_background: \"rgba(65, 182, 196, 0.3)\",\n profiling_chart_app_memory_border: \"rgb(34, 94, 168)\",\n profiling_chart_app_memory_background: \"rgba(34, 94, 168, 0.3)\",\n\n /* http logs component */\n http_logs_table_bg: \"#0c0d12\",\n http_logs_table_border: \"#1f2235\",\n http_logs_table_color: \"#dde1ef\",\n http_logs_table_header_bg: \"#0c0d12\",\n http_logs_table_header_color: \"#8892a8\",\n http_logs_table_row_hover: \"#1a1d28\",\n http_logs_table_row_active: \"#22263a\",\n http_logs_table_even_row_bg: \"#131620\",\n\n http_logs_table_icon_api: \"#2dd975\",\n http_logs_table_icon_document: \"#5b7fff\",\n http_logs_table_icon_script: \"#e8c14a\",\n\n http_logs_details_header_active: \"#1a1d28\",\n },\n },\n fonts: {\n size: {\n M: \"10px\",\n L: \"12px\",\n XL: \"14px\",\n XXL: \"16px\",\n },\n weight: {\n M: \"200\",\n L: \"400\",\n XL: \"500\",\n XXL: \"700\",\n },\n },\n borderRadius: {\n M: \"4px\",\n L: \"6px\",\n XL: \"12px\",\n XXL: \"24px\",\n },\n};\n\nexport default {\n light: LightTheme,\n};\n\nexport const DEFAULT_THEME = \"light\";\n","import createReducer from \"../../../utils/createReducer\";\nimport themes, { ThemeConfig, DEFAULT_THEME } from \"../../../constants/themes\";\n\nexport type ThemeState = {\n name: string;\n config: ThemeConfig;\n};\n\nconst initialState: ThemeState = {\n name: DEFAULT_THEME,\n config: themes[DEFAULT_THEME],\n};\n\nexport default createReducer(initialState, {});\n","import { ReduxActionType } from \"../../../interfaces/redux\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type SessionFilterType = {\n deviceName : string;\n status: Array<string>;\n device_udid: string;\n};\n\nexport type BuildFilterType = {\n user : string;\n project : Array<string>;\n platform_name : Array<string>;\n}\n\nexport type FilterState = {\n session: SessionFilterType;\n build: BuildFilterType;\n};\n\nconst initialState: FilterState = {\n session: {\n status: [],\n device_udid: \"\",\n deviceName: \"\",\n },\n build : {\n user : \"\",\n project : [],\n platform_name : [],\n }\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.SET_SESSION_FILTER]: (\n state: FilterState,\n action: ReduxActionType<SessionFilterType>,\n ) => ({\n ...state,\n session: action.payload,\n }),\n [ReduxActionTypes.SET_BUILD_FILTER]: (\n state: FilterState,\n action: ReduxActionType<BuildFilterType>,\n ) => ({\n ...state,\n build: action.payload,\n }),\n});\n","import { AppState } from \"../..\";\nimport { ReduxActionType } from \"../../../interfaces/redux\";\nimport createReducer from \"../../../utils/createReducer\";\nimport ReduxActionTypes from \"../../redux-action-types\";\n\nexport type LoadersState = {\n delete: {\n isPending: boolean;\n response: Record<string, string> | null;\n };\n state: {\n isPending: boolean;\n response: Record<string, string> | null;\n };\n script: {\n isPending: boolean;\n response: Record<string, any> | null;\n };\n};\n\nconst initialState: LoadersState = {\n delete: {\n isPending: false,\n response: null,\n },\n state: {\n isPending: false,\n response: null,\n },\n script: {\n isPending: false,\n response: null,\n },\n};\n\nexport default createReducer(initialState, {\n [ReduxActionTypes.DELETE_SESSION]: (state: AppState) => ({\n ...state,\n delete: {\n isPending: true,\n },\n }),\n [ReduxActionTypes.SESSION_DELETE_FINISH]: (\n state: AppState,\n action: ReduxActionType<Record<string, string>>,\n ) => ({\n ...state,\n delete: {\n isPending: false,\n response: action.payload,\n },\n }),\n [ReduxActionTypes.PAUSE_SESSION]: (state: AppState) => ({\n ...state,\n state: {\n isPending: true,\n },\n }),\n [ReduxActionTypes.RESUME_SESSION]: (state: AppState) => ({\n ...state,\n state: {\n isPending: true,\n },\n }),\n [ReduxActionTypes.RESET_SCRIPT_RESPONSE_FOR_SESSION]: (state: AppState) => ({\n ...state,\n script: {\n isPending: false,\n response: null,\n },\n }),\n [ReduxActionTypes.RUN_SCRIPT_FOR_SESSION]: (state: AppState) => ({\n ...state,\n script: {\n isPending: true,\n },\n }),\n [ReduxActionTypes.RUN_SCRIPT_FOR_SESSION_FINISH]: (\n state: AppState,\n action: ReduxActionType<Record<string, string | boolean>>,\n ) => ({\n ...state,\n script: {\n isPending: false,\n response: action.payload,\n },\n }),\n [ReduxActionTypes.SESSION_STATE_CHANGE_FINISH]: (\n state: AppState,\n action: ReduxActionType<Record<string, string | boolean>>,\n ) => ({\n ...state,\n state: {\n isPending: false,\n response: action.payload,\n },\n }),\n});\n","import { combineReducers } from \"redux\";\nimport AppInitialised, { AppInitilisedState } from \"./app-initialised\";\nimport SelectedReducer, { SelectedState } from \"./selected-reducer\";\nimport ThemeReducer, { ThemeState } from \"./theme-reducer\";\nimport FilterReducer, { FilterState } from \"./filter-reducer\";\nimport LoaderReducer, { LoadersState } from \"./loaders\";\n\nexport type UIState = {\n theme: ThemeState;\n selected: SelectedState;\n appInitialised: AppInitilisedState;\n sessionFilter: FilterState;\n buildFilter: FilterState;\n loaders: LoadersState;\n};\n\nexport default combineReducers({\n theme: ThemeReducer,\n selected: SelectedReducer,\n appInitialised: AppInitialised,\n sessionFilter: FilterReducer,\n buildFilter: FilterReducer,\n loaders: LoaderReducer,\n});\n","import { combineReducers } from \"@reduxjs/toolkit\";\nimport EntitiesReducer from \"./entities\";\nimport UiReducer from \"./ui\";\n\nexport default combineReducers({\n entities: EntitiesReducer,\n ui: UiReducer,\n});\n","import { applyMiddleware, createStore } from \"redux\";\nimport createSagaMiddleware from \"redux-saga\";\nimport { composeWithDevTools } from \"redux-devtools-extension\";\nimport initSaga from \"./sagas\";\nimport rootReducer from \"./reducers/root-reducer\";\nimport { EntitiesState } from \"./reducers/entities\";\nimport { UIState } from \"./reducers/ui\";\n\nconst sagaMiddleware = createSagaMiddleware();\nexport default createStore(\n rootReducer,\n composeWithDevTools(applyMiddleware(sagaMiddleware)),\n);\n\nsagaMiddleware.run(initSaga);\n\nexport type AppState = {\n entities: EntitiesState;\n ui: UIState;\n};\n\nexport type RootState = ReturnType<typeof rootReducer>;\n","function validURL(str: string | undefined) {\n if (!str) {\n return false;\n }\n return !!new RegExp(/^(https?):\\/\\/[^\\s$.?#].[^\\s]*$/gi).test(str);\n}\n\nexport const BASE_URL =\n process.env.REACT_APP_API_BASE_URL &&\n validURL(process.env.REACT_APP_API_BASE_URL)\n ? new URL(process.env.REACT_APP_API_BASE_URL).pathname\n : process.env.REACT_APP_API_BASE_URL || \"\";\n\nexport const SESSION_DETAILS = \"session/:id\";\n\nexport const getSessionDetailsUrl = (id: string) => {\n return `${BASE_URL}/session/${id}`;\n};\n\nexport const getBuildDetailsUrl = (id: string) => {\n return `${BASE_URL}/builds/${id}/sessions`;\n};\n\nexport const getBaseUrl = () => {\n return `${BASE_URL}`;\n};\n\nexport const METRICS_URL = `${BASE_URL}/metrics`;\n","export const APP_HEADER_HEIGHT = 60;\n\nexport const SUB_APP_HEADER_HEIGHT = 50;\n","import { AppState } from \"../..\";\n\nexport const getSessions = (state: AppState) => state.entities.sessions.items;\n\nexport const getIsSessionsLoading = (state: AppState) =>\n state.entities.sessions.isLoading;\n\nexport const getSelectedSession = (state: AppState) =>\n state.ui.selected.session;\n\nexport const isSessionDeleting = (state: AppState) =>\n state.ui.loaders.delete.isPending;\n\nexport const getSessionDeleteResponse = (state: AppState) =>\n state.ui.loaders.delete.response;\n\nexport const isStateChangePending = (state: AppState) =>\n state.ui.loaders.state.isPending;\n\nexport const getSessionStateChangeResponse = (state: AppState) =>\n state.ui.loaders.state.response;\n\nexport const isDriverScriptExecutionPending = (state: AppState) =>\n state.ui.loaders.script.isPending;\n\nexport const getDriverScriptResult = (state: AppState) =>\n state.ui.loaders.script.response;\n","import React from \"react\";\nimport styled from \"styled-components\";\n\nconst GIRD_SIZE = 100 / 12;\nconst ColumnContainer = styled.div<{\n grid: number;\n scrollable?: boolean;\n padding?: string;\n}>`\n flex-basis: ${(props) => GIRD_SIZE * props.grid}%;\n width: ${(props) => GIRD_SIZE * props.grid}%;\n display: flex;\n height: 100%;\n ${(props) => (props.scrollable ? \"overflow: auto\" : \"\")};\n padding: ${(props) => props.padding};\n\n & > * {\n height: 100%;\n width: 100%;\n }\n`;\n\ntype ColumnProps = {\n children: JSX.Element | null;\n className?: string;\n grid: number;\n scrollable?: boolean;\n padding?: string;\n};\n\nexport function Column(props: ColumnProps) {\n const { children, className, grid, scrollable, padding } = props;\n return (\n <ColumnContainer\n className={className}\n grid={grid}\n scrollable={scrollable}\n padding={padding}\n >\n {children}\n </ColumnContainer>\n );\n}\n\nconst Container = styled.div<{\n responsive?: boolean;\n responsiveWidth?: number;\n}>`\n display: flex;\n align-items: center;\n\n ${(props) =>\n props.responsive &&\n `{\n @media (max-width: ${props.responsiveWidth}px) {\n display: flex;\n flex-direction: column;\n overflow: scroll;\n & > * {\n height: auto;\n width: 100%;\n }\n }`}\n`;\n\ntype ParallelLayoutType = {\n className?: string;\n children: Array<JSX.Element | null> | JSX.Element | null;\n responsive?: boolean;\n responsiveWidth?: number;\n};\n\nexport default function ParallelLayout(props: ParallelLayoutType) {\n const { children, className, responsive, responsiveWidth } = props;\n return (\n <Container\n className={className}\n responsive={responsive}\n responsiveWidth={responsiveWidth}\n >\n {children}\n </Container>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\n\nconst RowContainer = styled.div<{\n height?: string;\n padding?: string;\n scrollable?: boolean;\n align?: string;\n}>`\n height: ${(props) => props.height};\n display: flex;\n padding: ${(props) => props.padding};\n text-align: ${(props) => props.align};\n ${(props) => (props.scrollable ? \"overflow: auto\" : \"\")};\n\n & > * {\n height: 100%;\n width: 100%;\n }\n`;\n\ntype RowPropsType = {\n className?: string;\n children: JSX.Element;\n height?: string;\n padding?: string;\n scrollable?: boolean;\n align?: \"center\" | \"left\" | \"right\";\n};\n\nexport function Row(props: RowPropsType) {\n const { children, className, height, padding, scrollable, align } = props;\n return (\n <RowContainer\n className={className}\n height={height}\n padding={padding}\n scrollable={scrollable}\n align={align}\n >\n {children}\n </RowContainer>\n );\n}\n\nconst Container = styled.div<{\n responsive?: boolean;\n responsiveWidth?: number;\n heightOnResize?: string;\n height?: string;\n}>`\n height: ${(props) => props.height};\n ${(props) =>\n props.responsive &&\n `{\n @media (max-width: ${props.responsiveWidth}px) {\n display: flex;\n flex-direction: columns;\n height: ${props.heightOnResize};\n }\n & > * {\n width: 100%;\n }\n }`};\n`;\n\ntype SerialLayouttype = {\n className?: string;\n children: Array<JSX.Element | null> | JSX.Element;\n responsive?: boolean;\n responsiveWidth?: number;\n heightOnResize?: string;\n height?: string;\n};\n\nexport default function SerialLayout(props: SerialLayouttype) {\n const {\n children,\n className,\n responsive = false,\n responsiveWidth,\n heightOnResize,\n height,\n } = props;\n return (\n <Container\n className={className}\n responsive={responsive}\n responsiveWidth={responsiveWidth}\n heightOnResize={heightOnResize}\n height={height}\n >\n {children}\n </Container>\n );\n}\n","import { ThemeConfig } from \"../constants/themes\";\n\nexport const getHeaderStyle = (theme: ThemeConfig) => `\n background: rgba(12, 13, 18, 0.85);\n backdrop-filter: blur(14px);\n -webkit-backdrop-filter: blur(14px);\n color: ${theme.colors.greyscale[0]};\n border-bottom: 1px solid ${theme.colors.border};\n`;\n","import React from \"react\";\nimport styled from \"styled-components\";\n\nconst Container = styled.div`\n display: flex;\n height: 100%;\n width: 100%;\n align-items: center;\n justify-content: center;\n`;\n\ntype PropsType = {\n children: string | JSX.Element;\n};\n\nexport default function Centered(props: PropsType) {\n const { children } = props;\n return <Container>{children}</Container>;\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Banner from \"./centered\";\n\nconst Message = styled.p<{ size?: keyof typeof EmptyMessageSize }>`\n font-size: ${(props) => props.size || EmptyMessageSize.XL};\n`;\n\nexport enum EmptyMessageSize {\n \"L\" = \"10px\",\n \"XL\" = \"15px\",\n \"XXL\" = \"20px\",\n}\n\nexport type PropsType = {\n children: string;\n size?: keyof typeof EmptyMessageSize;\n};\n\nexport default function EmptyMessage(props: PropsType) {\n const { size, children } = props;\n\n return (\n <Banner>\n <Message size={size}>{children}</Message>\n </Banner>\n );\n}\n","import React from \"react\";\nimport { useState } from \"react\";\nimport styled from \"styled-components\";\n\nconst TabsContainer = styled.div``;\n\ntype TabPropsType = {\n name: string;\n children: JSX.Element | null;\n};\n\nexport function Tab(props: TabPropsType) {\n const { children } = props;\n return <TabsContainer>{children}</TabsContainer>;\n}\n\nexport const TAB_HEADER_HEIGHT = 40;\n\nconst TabsLayoutContainer = styled.div`\n overflow: auto;\n height: 100%;\n`;\n\nconst Header = styled.div`\n height: ${TAB_HEADER_HEIGHT}px;\n border-bottom: 1px solid ${(props) => props.theme.colors.border};\n`;\n\nconst TabName = styled.div<{ active: boolean }>`\n display: inline-block;\n border-bottom: 3px solid\n ${(props) =>\n props.active ? props.theme.colors.tab_active_header : \"transparent\"};\n padding: 10px;\n cursor: ${(props) => (props.active ? \"default\" : \"pointer\")};\n color: ${(props) =>\n props.active ? props.theme.colors.tab_active_header : \"inherit\"};\n margin-right: 20px;\n font-weight: 600;\n font-size: 13px;\n`;\n\nconst Body = styled.div``;\n\ntype TabType = TabPropsType;\n\nconst useTabs = (children: JSX.Element[]) => {\n const tabs: TabType[] = [];\n React.Children.forEach(children, (children) => {\n if (children) {\n const props: TabType = children.props as TabType;\n\n tabs.push({\n name: props.name,\n children: props.children,\n });\n }\n });\n\n return tabs;\n};\n\ntype TabsLayoutPropsType = {\n selected: string;\n children: JSX.Element[];\n};\n\nexport default function TabsLayout(props: TabsLayoutPropsType) {\n const { selected } = props;\n const tabs = useTabs(props.children);\n const defaultTab = tabs.find((tab) => tab.name === selected);\n const [selectedTabName, setSelectedTabName] = useState<string | undefined>(\n defaultTab?.name,\n );\n const selectedTab =\n tabs.find((tab) => tab.name === selectedTabName) || tabs[0];\n\n return (\n <TabsLayoutContainer>\n <Header>\n {tabs.map((tab: TabType) => (\n <TabName\n active={selectedTab?.name === tab.name}\n onClick={() => setSelectedTabName(tab.name)}\n key={tab.name}\n >\n {tab.name}\n </TabName>\n ))}\n </Header>\n <Body>{selectedTab?.children}</Body>\n </TabsLayoutContainer>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport TabsLayout, { Tab, TAB_HEADER_HEIGHT } from \"../../layouts/tab-layout\";\nimport Session from \"../../../../interfaces/session\";\n\nconst Container = styled.div`\n word-break: break-word;\n padding: 10px;\n`;\n\nconst TabChildContainer = styled.div<{\n height: string;\n responsiveWidth: number;\n}>`\n height: ${(props) => props.height};\n overflow: auto;\n\n @media (max-width: ${(props) => props.responsiveWidth}px) {\n height: 100%;\n } ;\n`;\n\nconst Entry = styled.div`\n width: 100%;\n display: flex;\n padding: 5px;\n margin-top: 10px;\n &:hover {\n background: ${(props) => props.theme.colors.greyscale[5]};\n }\n`;\n\nconst Label = styled.div`\n min-width: 230px;\n font-weight: 600;\n`;\n\nconst Value = styled.div`\n flex-wrap: wrap;\n`;\n\nconst getCapabilityEntries = (tab: string, session: Session) => {\n const capabilityObject =\n tab == \"Capabilities\" ? session.capabilities : session.capabilities.desired;\n if (!capabilityObject) {\n return null;\n }\n\n return Object.keys(capabilityObject)\n .filter((k) => k != \"desired\" && capabilityObject[k] != \"\")\n .map((k) => {\n return (\n <Entry key={k}>\n <Label>{k}</Label>\n <Value>\n {typeof capabilityObject[k] == \"object\" ||\n typeof capabilityObject[k] == \"boolean\"\n ? JSON.stringify(capabilityObject[k], null, 2)\n : capabilityObject[k]}\n </Value>\n </Entry>\n );\n });\n};\n\ntype Propstype = {\n session: Session;\n height: number;\n responsiveWidth: number;\n};\n\nexport default function SessionCapabilityDetails(props: Propstype) {\n const { session, height, responsiveWidth } = props;\n const childHeight = `calc(100vh - ${height + TAB_HEADER_HEIGHT}px)`;\n return (\n <Container>\n <TabsLayout selected=\"Capabilities\">\n <Tab name=\"Capabilities\">\n <TabChildContainer\n height={childHeight}\n responsiveWidth={responsiveWidth}\n >\n {getCapabilityEntries(\"Capabilities\", session)}\n </TabChildContainer>\n </Tab>\n <Tab name=\"Desired Capabilities\">\n <TabChildContainer\n height={childHeight}\n responsiveWidth={responsiveWidth}\n >\n {getCapabilityEntries(\"Desired Capabilities\", session)}\n </TabChildContainer>\n </Tab>\n </TabsLayout>\n </Container>\n );\n}\n","import { ReduxActionType } from \"../../interfaces/redux\";\nimport ReduxActionTypes from \"../redux-action-types\";\n\nexport const addPollingTask = (payload: ReduxActionType<any>) => ({\n type: ReduxActionTypes.ADD_POLLING_TASK,\n payload,\n});\n\nexport const removePollingTask = (payload: ReduxActionType<any>) => ({\n type: ReduxActionTypes.REMOVE_POLLING_TASK,\n payload,\n});\n","import { AppState } from \"../..\";\n\nexport const getTextLogs = (state: AppState) => state.entities.logs.text.items;\n\nexport const getisTextLogsLoading = (state: AppState) =>\n state.entities.logs.text.isLoading;\n\nexport const getDeviceLogs = (state: AppState) =>\n state.entities.logs.device.items;\n\nexport const getisDeviceLogsLoading = (state: AppState) =>\n state.entities.logs.device.isLoading;\n\nexport const getDebugLogs = (state: AppState) =>\n state.entities.logs.debug.items;\n\nexport const getisDebugLogsLoading = (state: AppState) =>\n state.entities.logs.debug.isLoading;\n\nexport const getHttpLogs = (state: AppState) => state.entities.logs.http.items;\n\nexport const getisHttpLogsLoading = (state: AppState) =>\n state.entities.logs.http.isLoading;\n\nexport const getProfilingdata = (state: AppState) =>\n state.entities.logs.profiling.items;\n\nexport const getisProfilingLoading = (state: AppState) =>\n state.entities.logs.profiling.isLoading;\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { Checkbox, Classes } from \"@blueprintjs/core\";\n\nconst Container = styled.div`\n & .${Classes.CONTROL_INDICATOR} {\n width: 10px;\n display: inline-block;\n }\n\n & input {\n position: relative;\n top: 2px;\n }\n`;\n\ntype PropsType = {\n checked: boolean;\n label: string;\n onChange?: (isChecked: boolean) => void;\n};\n\nexport default function CheckboxComponent(props: PropsType) {\n const { checked, label, onChange } = props;\n\n return (\n <Container>\n <Checkbox\n checked={checked}\n label={label}\n onChange={(event: React.ChangeEvent<HTMLInputElement>) =>\n onChange && onChange(event.target.checked)\n }\n />\n </Container>\n );\n}\n","import { Classes, IconName, InputGroup } from \"@blueprintjs/core\";\nimport React from \"react\";\nimport styled from \"styled-components\";\n\nconst DEFAULT_HEIGHT = \"20px\";\nconst DEFAULT_WIDTH = \"100%\";\nconst ICON_WIDTH = \"20px\";\n\nconst Container = styled.div<{\n height: string;\n width: string;\n hasIcon: boolean;\n}>`\n background: ${(props) => props.theme.colors.controls.background};\n width: ${(props) => props.width};\n\n & .${Classes.INPUT_GROUP} {\n border: none;\n span {\n display: inline-block;\n width: ${ICON_WIDTH};\n }\n input {\n display: inline-block;\n height: ${(props) => props.height};\n width: ${(props) =>\n props.hasIcon ? `calc(100% - ${ICON_WIDTH})` : `100%`};\n vertical-align: super;\n border: 1px solid ${(props) => props.theme.colors.border};\n border-radius: ${(props) => props.theme.borderRadius.M};\n font-size: 12px;\n padding: 14px 8px;\n\n &:focus {\n outline: none;\n }\n }\n }\n`;\n\ntype PropsType = {\n name?: string;\n value?: string;\n type?: string;\n leftIcon?: IconName;\n placeholder?: string;\n rightElement?: JSX.Element;\n onChange?: (e: any) => void;\n height?: string;\n width?: string;\n className?: string;\n};\n\nexport default function Input(props: PropsType) {\n const {\n className,\n name,\n value,\n type = \"text\",\n leftIcon,\n placeholder,\n rightElement,\n onChange,\n height,\n width,\n } = props;\n\n return (\n <Container\n className={className}\n height={height || DEFAULT_HEIGHT}\n width={width || DEFAULT_WIDTH}\n hasIcon={!!leftIcon}\n >\n <InputGroup\n name={name}\n value={value}\n type={type}\n leftIcon={leftIcon}\n placeholder={placeholder}\n rightElement={rightElement}\n onChange={onChange}\n />\n </Container>\n );\n}\n","import React from \"react\";\nimport Lottie from \"lottie-react\";\nimport styled from \"styled-components\";\nimport spinner from \"../../../assets/lottie/spinner.json\";\n\nconst Container = styled.div<{ width?: string }>`\n width: ${(props) => props.width};\n`;\n\ntype PropsType = {\n name: string;\n width?: string;\n};\n\nexport default function Animation(props: PropsType) {\n const { name, width } = props;\n let animationData;\n\n switch (name) {\n case \"spinner\":\n animationData = spinner;\n break;\n default:\n animationData = {};\n break;\n }\n\n return (\n <Container width={width}>\n <Lottie animationData={animationData} />\n </Container>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Animation from \"./animation\";\n\nconst Container = styled.div<{ size?: keyof typeof Sizes }>`\n width: ${(props) => {\n switch (props.size) {\n case \"XS\":\n return \"40px\";\n case \"S\":\n return \"50px\";\n case \"M\":\n return \"70px\";\n case \"L\":\n return \"100px\";\n case \"XL\":\n return \"200px\";\n default:\n return \"100px\";\n }\n }};\n`;\n\nexport enum Sizes {\n \"XS\" = \"XS\",\n \"S\" = \"S\",\n \"M\" = \"M\",\n \"L\" = \"L\",\n \"XL\" = \"XL\",\n}\n\ntype PropsType = {\n size?: keyof typeof Sizes;\n};\n\nexport default function Spinner(props: PropsType) {\n const { size } = props;\n return (\n <Container size={size}>\n <Animation name=\"spinner\" />\n </Container>\n );\n}\n","import React from \"react\";\nimport {\n FaHome,\n FaAngleDown,\n FaAngleUp,\n FaCheckCircle,\n FaFilter,\n FaChevronDown,\n FaChevronUp, FaStop\n} from \"react-icons/fa\";\nimport { FcAndroidOs } from \"react-icons/fc\";\nimport {\n FaApple,\n FaTrash,\n FaPlay,\n FaChrome,\n FaRegStopCircle,\n} from \"react-icons/fa\";\nimport { SiSafari } from \"react-icons/si\";\nimport { IoPhonePortraitOutline } from \"react-icons/io5\";\nimport { IoClose } from \"react-icons/io5\";\nimport { AiFillCloseCircle, AiOutlineApi } from \"react-icons/ai\";\nimport { GiPauseButton } from \"react-icons/gi\";\nimport { BiArrowFromRight } from \"react-icons/bi\";\nimport { AiFillCaretRight, AiFillCaretDown } from \"react-icons/ai\";\nimport { TiImage } from \"react-icons/ti\";\nimport {\n BsClockFill,\n BsFillExclamationTriangleFill,\n BsSquare,\n BsFileCode,\n} from \"react-icons/bs\";\nimport { FiMinimize } from \"react-icons/fi\";\nimport { VscDebugAlt } from \"react-icons/vsc\";\nimport { GoTerminal } from \"react-icons/go\";\nimport { SiCsswizardry, SiPrettier } from \"react-icons/si\";\nimport { TiDocumentText } from \"react-icons/ti\";\nimport { IoMdExpand } from \"react-icons/io\";\nimport styled from \"styled-components\";\nimport Tooltip from \"@mui/material/Tooltip\";\nexport enum Sizes {\n S = \"12\",\n M = \"14\",\n L = \"16\",\n XL = \"18\",\n XXL = \"20\",\n XXXL = \"25\",\n}\n\nconst Container = styled.span<{ size?: string; color?: string }>`\n font-size: ${(props) => props.size || 14}px;\n vertical-align: middle;\n color: ${(props) => props.color};\n`;\n\ntype IconProps = {\n name: string;\n onClick?: () => void;\n size?: string;\n tooltip?: string;\n tooltipPosition?: \"top\" | \"bottom\" | \"right\" | \"left\";\n color?: string;\n};\n\nfunction wrapIconWithTooltip(icon: any, props: IconProps) {\n const { tooltip, tooltipPosition } = props;\n if (!tooltip) {\n return icon;\n } else {\n return (\n <Tooltip\n title={tooltip}\n placement={tooltipPosition}\n arrow\n classes={{\n tooltip: \"custom-tooltip-container\",\n arrow: \"custom-tooltip-arrow\",\n }}\n >\n {icon}\n </Tooltip>\n );\n }\n}\n\nexport default function Icon(props: IconProps) {\n const { name, onClick, size, color } = props;\n let icon;\n\n switch (name) {\n case \"home\":\n icon = <FaHome />;\n break;\n case \"android\":\n icon = <FcAndroidOs />;\n break;\n case \"ios\":\n icon = <FaApple />;\n break;\n case \"safari\":\n icon = <SiSafari />;\n break;\n case \"chrome\":\n icon = <FaChrome />;\n break;\n case \"arrow-up\":\n icon = <FaAngleUp />;\n break;\n case \"arrow-down\":\n icon = <FaAngleDown />;\n break;\n case \"success\":\n icon = <FaCheckCircle />;\n break;\n case \"error\":\n icon = <AiFillCloseCircle />;\n break;\n case \"time\":\n icon = <BsClockFill />;\n break;\n case \"filter\":\n icon = <FaFilter />;\n break;\n case \"delete\":\n icon = <FaTrash />;\n break;\n case \"mobile\":\n icon = <IoPhonePortraitOutline />;\n break;\n case \"exclamation\":\n icon = <BsFillExclamationTriangleFill />;\n break;\n case \"pause\":\n icon = <GiPauseButton />;\n break;\n case \"play\":\n icon = <FaPlay />;\n break;\n case \"collapse\":\n icon = <BiArrowFromRight />;\n break;\n case \"close\":\n icon = <IoClose />;\n break;\n case \"expand-arrow\":\n icon = <AiFillCaretRight />;\n break;\n case \"collapse-arrow\":\n icon = <AiFillCaretDown />;\n break;\n case \"document\":\n icon = <TiDocumentText />;\n break;\n case \"api\":\n icon = <AiOutlineApi />;\n break;\n case \"square\":\n icon = <BsSquare />;\n break;\n case \"image\":\n icon = <TiImage />;\n break;\n case \"css\":\n icon = <SiCsswizardry />;\n break;\n case \"code\":\n icon = <BsFileCode />;\n break;\n case \"terminal\":\n icon = <GoTerminal />;\n break;\n case \"debug\":\n icon = <VscDebugAlt />;\n break;\n case \"stop\":\n icon = <FaRegStopCircle />;\n break;\n case \"code-format\":\n icon = <SiPrettier />;\n break;\n case \"maximize\":\n icon = <IoMdExpand />;\n break;\n case \"minimize\":\n icon = <FiMinimize />;\n break;\n case \"chevron-up\":\n icon = <FaChevronUp />;\n break;\n case \"chevron-down\":\n icon = <FaChevronDown />;\n break;\n default:\n icon = null;\n }\n const container = (\n <Container onClick={onClick} size={size} className=\"icon\" color={color}>\n {icon}\n </Container>\n );\n return wrapIconWithTooltip(container, props);\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Highlight, { defaultProps, Language } from \"prism-react-renderer\";\nimport githubTheme from \"prism-react-renderer/themes/github\";\nimport nightOwlTheme from \"prism-react-renderer/themes/nightOwl\";\n\nconst themes = {\n github: githubTheme,\n nightOwl: nightOwlTheme,\n};\n\nexport const LineNo = styled.span`\n display: inline-block;\n width: 2em;\n user-select: none;\n opacity: 0.3;\n`;\n\nconst Pre = styled.pre`\n text-align: left;\n margin: 5px 0;\n background: transparent !important;\n\n & {\n .token-line {\n white-space: break-spaces;\n word-break: break-all;\n }\n }\n`;\n\nconst Container = styled(Highlight)``;\n\ntype PropsType = {\n code: string;\n language: Language;\n theme?: \"github\" | \"nightOwl\";\n lineNumber?: boolean;\n};\n\nexport default function CodeViewer(props: PropsType) {\n const { code, language, theme = \"github\", lineNumber = false } = props;\n\n return (\n <Container\n {...defaultProps}\n theme={themes[theme]}\n code={code}\n language={language}\n >\n {({ className, style, tokens, getLineProps, getTokenProps }) => (\n <Pre className={className} style={style}>\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line, key: i })}>\n {!!lineNumber && <LineNo>{i + 1}</LineNo>}\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token, key })} />\n ))}\n </div>\n ))}\n </Pre>\n )}\n </Container>\n );\n}\n","import React from \"react\";\nimport Moment from \"react-moment\";\nimport styled from \"styled-components\";\nimport { useState } from \"react\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Icon from \"../../atoms/icon\";\nimport CodeViewer from \"../../atoms/code-viewer\";\n\nconst Container = styled.div<{ expandable: boolean }>`\n padding: 10px;\n border-bottom: 1px solid ${(props) => props.theme.colors.border};\n ${(props) => {\n return props.expandable\n ? `\n cursor: pointer;\n &:hover {\n background: ${props.theme.colors.components.log_entry_hover};\n }\n `\n : \"\";\n }}\n`;\n\nconst Header = styled.div``;\n\nconst Content = styled.div``;\n\nconst Time = styled.div`\n color: ${(props) => props.theme.colors.greyscale[3]};\n`;\n\nconst Message = styled.div`\n font-size: 11px;\n margin-left: 15px;\n`;\n\nconst Expand = styled.div`\n text-align: right;\n`;\n\nconst CodeViewerWrapper = styled.div`\n border: 1px solid ${(props) => props.theme.colors.border};\n background: ${(props) => props.theme.colors.greyscale[5]};\n margin: 20px 10px 10px;\n padding: 10px;\n border-radius: ${(props) => props.theme.borderRadius.M};\n max-height: 200px;\n overflow: auto;\n`;\n\ntype PropsType = {\n entry: any;\n};\n\nexport default function SessionDebugLogEntry(props: PropsType) {\n const { entry } = props;\n const [isExpanded, setIsExpanded] = useState(false);\n return (\n <Container\n onClick={() => setIsExpanded(!isExpanded)}\n expandable={!!entry.args}\n >\n <Header>\n <ParallelLayout>\n <Column grid={2}>\n <Time>\n <Moment format=\"DD-MM-YYYY HH:mm:ss\">{entry.timestamp}</Moment>\n </Time>\n </Column>\n <Column grid={9}>\n <Message>{entry.message}</Message>\n </Column>\n <Column grid={1}>\n {entry.args && (\n <Expand>\n {isExpanded ? (\n <Icon name=\"arrow-up\" />\n ) : (\n <Icon name=\"arrow-down\" />\n )}\n </Expand>\n )}\n </Column>\n </ParallelLayout>\n </Header>\n <Content>\n {entry.args && isExpanded && (\n <CodeViewerWrapper>\n <CodeViewer\n code={JSON.stringify(entry.args, null, 2)}\n language={\"json\"}\n />\n </CodeViewerWrapper>\n )}\n </Content>\n </Container>\n );\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport {\n addPollingTask,\n removePollingTask,\n} from \"../../../../store/actions/polling-actions\";\nimport { fetchSessionDebugLogs } from \"../../../../store/actions/session-actions\";\nimport {\n getDebugLogs,\n getisDebugLogsLoading,\n} from \"../../../../store/selectors/entities/logs-selector\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport CheckboxComponent from \"../../atoms/checkbox\";\nimport Input from \"../../atoms/input\";\nimport Spinner from \"../../atoms/spinner\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport { TAB_HEADER_HEIGHT } from \"../../layouts/tab-layout\";\nimport Centered from \"../../molecules/centered\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport SessionDebugLogEntry from \"./session-debug-log-entry\";\n\nfunction useLogs(filterText: string) {\n const logs = useSelector(getDebugLogs);\n\n return logs\n .filter((log: any) => log.message && log.message.indexOf(filterText) >= 0)\n .map((log: any) => <SessionDebugLogEntry key={log} entry={log} />);\n}\n\nconst HEADER_HEIGHT = 50;\n\nconst Container = styled.div``;\n\nconst Header = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 10px;\n`;\n\nconst Content = styled.div``;\n\n//TODO: Refactor this. temporary changes\nconst StyledInput = styled(Input)`\n background: transparent;\n border-bottom: 1px solid #fff;\n\n &&& input {\n background: transparent;\n color: #fff;\n border: none;\n }\n\n &&& path {\n background: #fff;\n stroke: #fff;\n }\n`;\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nexport default function SessionDebugLogs(props: PropsType) {\n const { session, parentHeight } = props;\n const [filterText, setFilterText] = useState(\"\");\n const logs = useLogs(filterText);\n const isLoading = useSelector(getisDebugLogsLoading);\n const dispatch = useDispatch();\n const [enablePolling, setEnablePolling] = useState(!session.is_completed);\n\n useEffect(() => {\n dispatch(fetchSessionDebugLogs(session.session_id));\n\n if (session.is_completed) {\n togglePolling(false);\n } else if (enablePolling) {\n togglePolling(true);\n }\n\n return () => {\n togglePolling(false);\n };\n }, [session.session_id, session.is_completed]);\n\n const togglePolling = useCallback((on: boolean) => {\n if (on) {\n dispatch(addPollingTask(fetchSessionDebugLogs(session.session_id)));\n } else {\n dispatch(removePollingTask(fetchSessionDebugLogs(session.session_id)));\n }\n setEnablePolling(on);\n }, []);\n\n if (isLoading) {\n return (\n <Centered>\n <Spinner />\n </Centered>\n );\n } else {\n return (\n <Container>\n <SerialLayout>\n <Row height={`${HEADER_HEIGHT}px`}>\n <Header>\n <ParallelLayout>\n <Column grid={4}>\n <StyledInput\n name=\"search\"\n type=\"text\"\n leftIcon=\"search\"\n placeholder=\"Filter logs\"\n value={filterText}\n onChange={(e) => setFilterText(e.target.value)}\n />\n </Column>\n {!session.is_completed ? (\n <Column grid={4} padding=\"0px 10px\">\n <CheckboxComponent\n label=\"Enable Polling\"\n checked={enablePolling}\n onChange={(checked: boolean) => togglePolling(checked)}\n />\n </Column>\n ) : null}\n </ParallelLayout>\n </Header>\n </Row>\n <Row\n height={`calc(100vh - ${\n HEADER_HEIGHT + TAB_HEADER_HEIGHT + parentHeight\n }px)`}\n scrollable\n >\n <Content>\n {logs.length ? (\n logs\n ) : (\n <Centered>\n <EmptyMessage>No Logs available</EmptyMessage>\n </Centered>\n )}\n </Content>\n </Row>\n </SerialLayout>\n </Container>\n );\n }\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport {\n addPollingTask,\n removePollingTask,\n} from \"../../../../store/actions/polling-actions\";\nimport { fetchSessionDeviceLogs } from \"../../../../store/actions/session-actions\";\nimport {\n getDeviceLogs,\n getisDeviceLogsLoading,\n} from \"../../../../store/selectors/entities/logs-selector\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport CheckboxComponent from \"../../atoms/checkbox\";\nimport Input from \"../../atoms/input\";\nimport Spinner from \"../../atoms/spinner\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport { TAB_HEADER_HEIGHT } from \"../../layouts/tab-layout\";\nimport Centered from \"../../molecules/centered\";\n\nconst LogsEntry = styled.div`\n padding: 3px 3px 3px 3px;\n font-size: 13px;\n line-height: 20px;\n &:hover {\n background: #32383f;\n }\n`;\n\nfunction useLogs(filterText: string) {\n const logs = useSelector(getDeviceLogs);\n\n return logs\n .filter((log: any) => log.message && log.message.indexOf(filterText) >= 0)\n .map((log: any, index: number) => (\n <LogsEntry key={index}>\n {/* <ParallelLayout>\n <Column grid={1}>\n <LineNumber>{index + 1}</LineNumber>\n </Column>\n <Column grid={11}>{log.message}</Column>\n </ParallelLayout> */}\n {log.message}\n </LogsEntry>\n ));\n}\n\nconst HEADER_HEIGHT = 50;\n\nconst Container = styled.div``;\n\nconst Header = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 10px;\n`;\n\nconst Content = styled.div`\n background: #24292e;\n color: #cfd6dc;\n padding: 10px;\n word-break: break-word;\n overflow: scroll;\n`;\n\n//TODO: Refactor this. temporary changes\nconst StyledInput = styled(Input)`\n background: transparent;\n border-bottom: 1px solid #fff;\n\n &&& input {\n background: transparent;\n color: #fff;\n border: none;\n }\n\n &&& path {\n background: #fff;\n stroke: #fff;\n }\n`;\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nexport default function SessionDeviceLogs(props: PropsType) {\n const { session, parentHeight } = props;\n const [filterText, setFilterText] = useState(\"\");\n const logs = useLogs(filterText);\n const isLoading = useSelector(getisDeviceLogsLoading);\n const dispatch = useDispatch();\n const [enablePolling, setEnablePolling] = useState(!session.is_completed);\n\n useEffect(() => {\n dispatch(fetchSessionDeviceLogs(session.session_id));\n\n if (session.is_completed) {\n togglePolling(false);\n } else if (enablePolling) {\n togglePolling(true);\n }\n\n return () => {\n togglePolling(false);\n };\n }, [session.session_id, session.is_completed]);\n\n const togglePolling = useCallback((on: boolean) => {\n if (on) {\n dispatch(addPollingTask(fetchSessionDeviceLogs(session.session_id)));\n } else {\n dispatch(removePollingTask(fetchSessionDeviceLogs(session.session_id)));\n }\n setEnablePolling(on);\n }, []);\n\n if (isLoading) {\n return (\n <Centered>\n <Spinner />\n </Centered>\n );\n } else {\n return (\n <Container>\n <SerialLayout>\n <Row height={`${HEADER_HEIGHT}px`}>\n <Header>\n <ParallelLayout>\n <Column grid={4}>\n <StyledInput\n name=\"search\"\n type=\"text\"\n leftIcon=\"search\"\n placeholder=\"Filter logs\"\n value={filterText}\n onChange={(e) => setFilterText(e.target.value)}\n />\n </Column>\n {!session.is_completed ? (\n <Column grid={4} padding=\"0px 10px\">\n <CheckboxComponent\n label=\"Enable Polling\"\n checked={enablePolling}\n onChange={(checked: boolean) => togglePolling(checked)}\n />\n </Column>\n ) : null}\n </ParallelLayout>\n </Header>\n </Row>\n <Row\n height={`calc(100vh - ${\n HEADER_HEIGHT + TAB_HEADER_HEIGHT + parentHeight\n }px)`}\n scrollable\n >\n <Content>{logs}</Content>\n </Row>\n </SerialLayout>\n </Container>\n );\n }\n}\n","import _ from \"lodash\";\n\n// Match the axios baseURL in ../api/index.ts. `api.base_url` is the SPA's\n// React Router base (/device-farm/dashboard), not the API mount — using it\n// here would route asset requests into the SPA fallback in src/app.ts and\n// return index.html instead of the video/screenshot.\nconst API_BASE = \"/device-farm/api\";\n\n// Browser-issued media requests (<video src>, <img src>) can't attach an\n// Authorization header, so the bearer token rides in ?token=. The backend\n// extractBearer() accepts either form. Same TOKEN_KEY as ../api/index.ts.\nfunction appendAuthToken(url: string): string {\n const token = window.localStorage.getItem(\"df_token\");\n if (!token) return url;\n const separator = url.includes(\"?\") ? \"&\" : \"?\";\n return `${url}${separator}token=${encodeURIComponent(token)}`;\n}\n\nexport default class CommonUtils {\n public static getTimeDiffInSecs(startDate: Date, endDate: Date) {\n return Math.ceil((endDate.getTime() - startDate.getTime()) / 1000);\n }\n\n public static convertTimeToReadableFormat(startDate: Date, endDate: Date) {\n const readableDuration = CommonUtils.getReadableDuration(\n startDate,\n endDate,\n );\n\n return readableDuration.trim();\n }\n\n public static getReadableDuration(startDate: Date, endDate: Date) {\n const seconds = Math.round(\n (endDate.getTime() - startDate.getTime()) / 1000,\n );\n if (seconds <= 0) {\n return `${Math.round(endDate.getTime() - startDate.getTime())} ms`;\n }\n const levels: any = [\n [Math.floor(seconds / 31536000), \"y\"],\n [Math.floor((seconds % 31536000) / 86400), \"d\"],\n [Math.floor(((seconds % 31536000) % 86400) / 3600), \"h\"],\n [Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), \"m\"],\n [(((seconds % 31536000) % 86400) % 3600) % 60, \"s\"],\n ];\n let returntext = \"\";\n\n for (let i = 0, max = levels.length; i < max; i++) {\n if (levels[i][0] === 0) continue;\n returntext += \" \" + levels[i][0] + levels[i][1];\n }\n\n return `${returntext}`;\n }\n\n public static filterSessionList(sessions: any[], filter: any) {\n const filters: any = [];\n if (filter.name) {\n filters.push(\n (session: any) =>\n session.session_id.indexOf(filter.name) >= 0 ||\n session.name?.toLowerCase().indexOf(filter.name.toLowerCase()) >= 0,\n );\n }\n if (filter.os) {\n filters.push(\n (session: any) =>\n session.platform_name.toLowerCase() == filter.os.toLowerCase(),\n );\n }\n\n if (filter.status) {\n filters.push(\n (session: any) =>\n session.session_status.toLowerCase() == filter.status.toLowerCase(),\n );\n }\n\n if (filter.device_udid) {\n filters.push(\n (session: any) =>\n session.udid\n ?.toLowerCase()\n .indexOf(filter.device_udid.toLowerCase()) >= 0,\n );\n }\n\n return filters.reduce((acc: any, filter: any) => {\n return acc.filter(filter);\n }, sessions);\n }\n\n static urlParamsToObject(urlParams: URLSearchParams) {\n return Object.fromEntries(urlParams);\n }\n\n static parseJsonSchema(schema: any, obj: any) {\n const parsedObject: any = {};\n\n Object.keys(schema).forEach((key) => {\n if (obj[key]) {\n if (!schema[key].valid) {\n parsedObject[key] = obj[key];\n } else if (schema[key].valid) {\n if (\n typeof schema[key].valid === \"function\" &&\n schema[key].valid(obj[key])\n ) {\n parsedObject[key] = obj[key];\n } else if (\n Array.isArray(schema[key].valid) &&\n schema[key].valid.indexOf(obj[key]) >= 0\n ) {\n parsedObject[key] = obj[key];\n }\n }\n }\n });\n return parsedObject;\n }\n\n public static parseJson(str: any) {\n if (_.isString(str)) {\n try {\n return JSON.stringify(JSON.parse(str), null, 2);\n } catch (err) {}\n }\n return str;\n }\n\n static getVideoForSession(sessionId: string) {\n return appendAuthToken(`${API_BASE}/sessions/${sessionId}/video`);\n }\n\n static getDownloadVideoForSession(sessionId: string) {\n return appendAuthToken(`${API_BASE}/sessions/${sessionId}/video/download`);\n }\n\n static getLiveVideoForSession(sessionId: string) {\n return appendAuthToken(`${API_BASE}/sessions/${sessionId}/live_video`);\n }\n\n static getScreenshotForLog(sessionId: string, logId: string) {\n return appendAuthToken(\n `${API_BASE}/sessions/${sessionId}/log/${logId}/screen-shot`,\n );\n }\n\n static hash(object: any) {\n return JSON.stringify(object);\n }\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { useState } from \"react\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Icon from \"../../atoms/icon\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport CodeViewer from \"../../atoms/code-viewer\";\nimport chroma from \"chroma-js\";\nimport { LazyLoadImage } from \"react-lazy-load-image-component\";\n\nconst ParamsContainer = styled.div`\n border: 1px solid ${(props) => props.theme.colors.border};\n background: ${(props) => props.theme.colors.greyscale[5]};\n padding: 15px 15px 5px;\n margin: 20px 0 5px 0px;\n max-height: 200px;\n overflow: auto;\n border-radius: ${(props) => props.theme.borderRadius.M};\n`;\n\nconst ParamsTitle = styled.div`\n padding-bottom: 10px;\n font-size: 11px;\n color: ${(props) => props.theme.colors.greyscale[2]};\n font-weight: 900;\n text-transform: uppercase;\n`;\n\nconst ErrorContainer = styled(ParamsContainer)`\n border: 1px solid rgba(244, 88, 88, 0.3);\n border-left: 5px solid ${(props) => props.theme.colors.error};\n background: rgba(244, 88, 88, 0.08);\n color: ${(props) => props.theme.colors.error};\n\n & .text-log-params-json-entry-key {\n text-transform: capitalize;\n }\n`;\n\nconst WarningContainer = styled(ErrorContainer)`\n border: 1px solid rgba(232, 193, 74, 0.3);\n border-left: 5px solid ${(props) => props.theme.colors.warning};\n background: rgba(232, 193, 74, 0.08);\n color: ${(props) => props.theme.colors.warning};\n`;\n\nconst StringValue = styled.div`\n font-size: 12px;\n padding-bottom: 10px;\n`;\n\nconst JsonValue = styled(StringValue)``;\n\nconst JsonEntryKey = styled(StringValue)`\n font-weight: 500;\n`;\n\nconst ErrorNameLabel = styled(JsonEntryKey)`\n text-transform: capitalize;\n`;\n\nfunction getLogBody(logTitle: string, logBody: any) {\n const code =\n typeof logBody.value !== \"string\"\n ? JSON.stringify(logBody.value, null, 2)\n : logBody.value;\n if (logBody.type == \"error\") {\n return (\n <WarningContainer>\n <ErrorNameLabel>{logBody.value.error}:</ErrorNameLabel>\n <JsonValue>{logBody.value.message}</JsonValue>\n </WarningContainer>\n );\n } else {\n return (\n <ParamsContainer>\n <ParamsTitle>{logTitle}</ParamsTitle>\n <JsonValue>\n <CodeViewer code={code} language=\"json\" />\n </JsonValue>\n </ParamsContainer>\n );\n }\n}\n\nfunction getDuration(entry: any) {\n if (!entry.start_time || !entry.end_time) {\n return \"\";\n } else {\n const time = CommonUtils.convertTimeToReadableFormat(\n new Date(entry.start_time),\n new Date(entry.end_time),\n )\n .replace(/hrs|hr/g, \"h\")\n .replace(/mins|min/g, \"m\")\n .replace(/secs|sec/g, \"s\");\n return time;\n }\n}\n\nconst Container = styled.div<{ expandable: boolean }>`\n padding: 10px;\n border-bottom: 1px solid ${(props) => props.theme.colors.border};\n ${(props) => {\n if (props.expandable) {\n return `\n cursor: pointer;\n `;\n }\n }}\n &:hover {\n background: ${(props) => props.theme.colors.components.log_entry_hover};\n }\n`;\n\nconst Title = styled.div<{ isError: boolean }>`\n color: ${(props) =>\n props.isError\n ? chroma(props.theme.colors.warning).brighten(-1).hex()\n : \"inherit\"};\n }\n`;\n\nconst TitleInfo = styled.div`\n color: ${(props) => props.theme.colors.greyscale[3]};\n font-weight: ${(props) => props.theme.fonts.weight.L};\n letter-spacing: -0.2px;\n`;\n\nconst Time = styled.div`\n color: ${(props) => props.theme.colors.greyscale[3]};\n`;\n\nconst TimeText = styled.span`\n margin-left: 10px;\n`;\n\nconst Expand = styled.div`\n text-align: right;\n cursor: pointer;\n`;\n\nconst ScreenshotLink = styled.a`\n padding: 15px;\n display: flex;\n margin-right: auto;\n cursor: pointer;\n`;\n\nconst Screenshot = styled(LazyLoadImage)`\n max-width: 300px;\n max-height: 600px;\n height: auto;\n`;\n\ntype PropsType = {\n entry: any;\n showScreenShots: boolean;\n};\n\nexport default function LogEntry(props: PropsType) {\n const [expanded, setExpanded] = useState(false);\n const { entry, showScreenShots } = props;\n return (\n <Container\n onClick={() => setExpanded(!expanded)}\n expandable={!!entry.params}\n >\n <SerialLayout>\n <Row>\n <ParallelLayout>\n <Column grid={4}>\n <Title isError={entry.is_error}>{entry.title}</Title>\n </Column>\n <Column grid={6}>\n <TitleInfo>{entry.title_info}</TitleInfo>\n </Column>\n <Column grid={1}>\n {getDuration(entry) != \"\" ? (\n <Time>\n <Icon name=\"time\" />\n <TimeText>{getDuration(entry)}</TimeText>\n </Time>\n ) : null}\n </Column>\n <Column grid={1}>\n {!!entry.params ? (\n <Expand>\n {expanded ? (\n <Icon name=\"arrow-up\" onClick={() => setExpanded(false)} />\n ) : (\n <Icon name=\"arrow-down\" onClick={() => setExpanded(true)} />\n )}\n </Expand>\n ) : null}\n </Column>\n </ParallelLayout>\n </Row>\n {entry.response != null ? (\n <Row>{getLogBody(\"Response\", entry.response)}</Row>\n ) : null}\n {entry.params != null && expanded ? (\n <Row>{getLogBody(\"Params\", entry.params)}</Row>\n ) : null}\n\n {showScreenShots && entry.screen_shot != null ? (\n <Row>\n <ScreenshotLink\n target=\"blank\"\n href={CommonUtils.getScreenshotForLog(\n entry.session_id,\n entry.log_id,\n )}\n >\n <Screenshot\n src={CommonUtils.getScreenshotForLog(\n entry.session_id,\n entry.log_id,\n )}\n effect=\"opacity\"\n />\n </ScreenshotLink>\n </Row>\n ) : null}\n </SerialLayout>\n </Container>\n );\n}\n","import React from \"react\";\nimport { useCallback } from \"react\";\nimport { useEffect } from \"react\";\nimport { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport {\n addPollingTask,\n removePollingTask,\n} from \"../../../../store/actions/polling-actions\";\nimport { fetchSessionTextLogs } from \"../../../../store/actions/session-actions\";\nimport {\n getisTextLogsLoading,\n getTextLogs,\n} from \"../../../../store/selectors/entities/logs-selector\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport CheckboxComponent from \"../../atoms/checkbox\";\nimport CheckBox from \"../../atoms/checkbox\";\nimport Spinner from \"../../atoms/spinner\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport { TAB_HEADER_HEIGHT } from \"../../layouts/tab-layout\";\nimport Centered from \"../../molecules/centered\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport LogEntry from \"./session-text-logs-entry\";\n\nfunction useLogs(showScreenShots: boolean, showExceptions: boolean) {\n const logs = useSelector(getTextLogs);\n\n return logs\n .filter((log: any) => !showExceptions || log.is_error)\n .map((log: any, index: number) => (\n <LogEntry key={index} entry={log} showScreenShots={showScreenShots} />\n ));\n}\n\nconst Container = styled.div``;\n\nconst Header = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 16px 10px;\n`;\n\nconst Content = styled.div``;\n\nconst HEADER_HEIGHT = 50;\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nexport default function SessionTextLogs(props: PropsType) {\n const { session, parentHeight } = props;\n const [showScreenShots, setShowScreenShots] = useState(true);\n const [showExceptions, setShowExceptions] = useState(false);\n const [enablePolling, setEnablePolling] = useState(!session.is_completed);\n const logs = useLogs(showScreenShots, showExceptions);\n const isLoading = useSelector(getisTextLogsLoading);\n const dispatch = useDispatch();\n\n useEffect(() => {\n dispatch(fetchSessionTextLogs(session.session_id));\n\n if (session.is_completed) {\n togglePolling(false);\n } else if (enablePolling) {\n togglePolling(true);\n }\n\n return () => {\n togglePolling(false);\n };\n }, [session.session_id, session.is_completed]);\n\n const togglePolling = useCallback(\n (on: boolean) => {\n if (on) {\n dispatch(addPollingTask(fetchSessionTextLogs(session.session_id)));\n } else {\n dispatch(removePollingTask(fetchSessionTextLogs(session.session_id)));\n }\n setEnablePolling(on);\n },\n [session.session_id],\n );\n\n if (isLoading) {\n return (\n <Centered>\n <Spinner />\n </Centered>\n );\n } else {\n return (\n <Container>\n <SerialLayout>\n <Row height={`${HEADER_HEIGHT}px`}>\n <Header>\n <ParallelLayout>\n <Column grid={2}>\n <CheckBox\n label=\"Show Images\"\n checked={showScreenShots}\n onChange={(checked: boolean) => setShowScreenShots(checked)}\n />\n </Column>\n <Column grid={2.5}>\n <CheckBox\n label=\"Show Errors Only\"\n checked={showExceptions}\n onChange={(checked: boolean) => setShowExceptions(checked)}\n />\n </Column>\n {!session.is_completed ? (\n <Column grid={3} padding=\"0px 10px\">\n <CheckboxComponent\n label=\"Enable Polling\"\n checked={enablePolling}\n onChange={(checked: boolean) => togglePolling(checked)}\n />\n </Column>\n ) : null}\n </ParallelLayout>\n </Header>\n </Row>\n <Row\n height={`calc(100vh - ${\n HEADER_HEIGHT + TAB_HEADER_HEIGHT + parentHeight\n }px)`}\n scrollable\n >\n {logs.length ? (\n <Content>{logs}</Content>\n ) : (\n <EmptyMessage>No logs</EmptyMessage>\n )}\n </Row>\n </SerialLayout>\n </Container>\n );\n }\n}\n","import { AppState } from \"../..\";\n\nexport const getSelectedTheme = (state: AppState) => state.ui.theme.config;\n","import React, { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport { fetchSessionProfilingData } from \"../../../../store/actions/session-actions\";\nimport {\n getisProfilingLoading,\n getProfilingdata,\n} from \"../../../../store/selectors/entities/logs-selector\";\nimport Spinner from \"../../atoms/spinner\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport Centered from \"../../molecules/centered\";\nimport {\n Chart as ChartJS,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n Filler,\n} from \"chart.js\";\nimport { Line } from \"react-chartjs-2\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport { getSelectedTheme } from \"../../../../store/selectors/ui/theme-selector\";\nimport _ from \"lodash\";\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n Filler,\n);\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nconst Container = styled.div`\n max-width: 700px !important;\n display: flex;\n flex-direction: column;\n margin: auto;\n`;\n\nconst ChartRow = styled.div`\n margin: 25px 0 40px 0;\n`;\n\nfunction toMegaByte(value: any) {\n return Math.ceil(Number(value) / 1024);\n}\n\n/* Cpu Usage data */\nfunction getCpuChartOptions(session: Session) {\n return {\n responsive: true,\n aspectRatio: 3,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n usePointStyle: true,\n },\n },\n title: {\n display: true,\n text: `CPU [${session.device_info.total_cpu} processors = ${\n session.device_info.total_cpu * 100\n } %]`,\n },\n tooltip: {\n callbacks: {\n label: function (context: any) {\n return context.dataset.label + \" : \" + context.parsed.y;\n },\n },\n },\n },\n parsing: {\n xAxisKey: \"timestamp\",\n yAxisKey: \"cpu\",\n },\n scales: {\n y: {\n min: -1,\n max: session.device_info.total_cpu * 100,\n },\n },\n };\n}\n\nfunction getCpuChartData(\n session: Session,\n profilingData: any[],\n theme: Record<string, any>,\n) {\n return {\n datasets: [\n {\n label: \"Total CPU Usage %\",\n data: profilingData.map((v: any) => {\n return {\n timestamp: v.timestamp,\n cpu: v.total_cpu_used,\n };\n }),\n fill: true,\n borderColor: theme.colors.components.profiling_chart_system_cpu_border,\n backgroundColor:\n theme.colors.components.profiling_chart_system_cpu_background,\n },\n {\n label: `${session.capabilities.appPackage} %`,\n data: profilingData.map((v: any) => {\n return {\n timestamp: v.timestamp,\n cpu: v.cpu,\n };\n }),\n fill: true,\n borderColor: theme.colors.components.profiling_chart_app_cpu_border,\n backgroundColor:\n theme.colors.components.profiling_chart_app_cpu_background,\n },\n ],\n };\n}\n\n/* Memory usage data */\nfunction getMemoryUsageChartOptions(session: Session) {\n const totalMemoryInMB = toMegaByte(session.device_info.total_memory);\n return {\n responsive: true,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n usePointStyle: true,\n },\n },\n title: {\n display: true,\n text: `MEMORY [${totalMemoryInMB} MB]`,\n },\n tooltip: {\n callbacks: {\n label: function (context: any) {\n return context.dataset.label + \" : \" + context.parsed.y;\n },\n },\n },\n },\n parsing: {\n xAxisKey: \"timestamp\",\n yAxisKey: \"memory\",\n },\n aspectRatio: 3,\n scales: {\n y: {\n min: 0,\n max: Math.ceil(totalMemoryInMB / 500) * 500, //round to nearest five hundred\n ticks: {\n stepSize: 500,\n },\n },\n },\n };\n}\n\nfunction getMemoryChartData(\n session: Session,\n profilingData: any[],\n theme: Record<string, any>,\n) {\n return {\n datasets: [\n {\n label: \"Total Memory Usage (MB)\",\n data: profilingData.map((data) => {\n return {\n timestamp: data.timestamp,\n memory: Math.ceil(Number(data.total_memory_used) / 1024),\n };\n }),\n fill: true,\n borderColor:\n theme.colors.components.profiling_chart_system_memory_border,\n backgroundColor:\n theme.colors.components.profiling_chart_system_memory_background,\n },\n {\n label: `${session.capabilities.appPackage} (MB)`,\n data: profilingData.map((data) => {\n return {\n timestamp: data.timestamp,\n memory: toMegaByte(data.memory),\n };\n }),\n fill: true,\n borderColor: theme.colors.components.profiling_chart_app_memory_border,\n backgroundColor:\n theme.colors.components.profiling_chart_app_memory_background,\n },\n ],\n };\n}\n\nfunction useProfiling(session: Session) {\n const profilingData = useSelector(getProfilingdata);\n const processedData = profilingData.map((data: any) => {\n return {\n ...data,\n timestamp:\n CommonUtils.getTimeDiffInSecs(\n new Date(session.created_at),\n new Date(data.timestamp),\n ) + \"s\",\n };\n });\n return _.uniqBy(processedData, \"timestamp\");\n}\n\nexport default function AppProfiling(props: PropsType) {\n const { session, parentHeight } = props;\n const dispatch = useDispatch();\n const theme = useSelector(getSelectedTheme);\n const isLoading = useSelector(getisProfilingLoading);\n const profilingData = useProfiling(session);\n\n useEffect(() => {\n dispatch(fetchSessionProfilingData(session.session_id));\n }, [session.session_id]);\n\n if (isLoading) {\n return (\n <Centered>\n <Spinner />\n </Centered>\n );\n } else {\n return (\n <SerialLayout>\n <Row height={`calc(100vh - ${parentHeight}px)`} scrollable>\n <Container>\n <ChartRow>\n <Line\n options={getCpuChartOptions(session)}\n data={getCpuChartData(session, profilingData, theme)}\n ></Line>\n </ChartRow>\n <ChartRow>\n <Line\n options={getMemoryUsageChartOptions(session)}\n data={getMemoryChartData(session, profilingData, theme)}\n ></Line>\n </ChartRow>\n </Container>\n </Row>\n </SerialLayout>\n );\n }\n}\n","import chroma from \"chroma-js\";\nimport React, { useCallback, useMemo, useState } from \"react\";\nimport styled from \"styled-components\";\nimport Icon, { Sizes } from \"../atoms/icon\";\nimport CodeViewer from \"../atoms/code-viewer\";\nimport Centered from \"../molecules/centered\";\nimport EmptyMessage from \"../molecules/empty-message\";\nimport CommonUtils from \"../../../utils/common-utils\";\n\nexport type HttpLogs = {\n id: number;\n url: string;\n method: string;\n request_type: string;\n response_status: number;\n response_status_text: string;\n start_time: Date;\n request_headers: Record<string, any>;\n response_headers: Record<string, any>;\n response_body: any;\n response_content_type: string;\n request_post_data: any;\n request_content_type: string;\n};\n\nexport type propsType = {\n log: HttpLogs;\n onClose?: () => void;\n parentHeight: number;\n};\n\nconst Container = styled.div<{ height: string }>`\n height: ${(props) => props.height};\n`;\n\nconst Header = styled.div`\n display: flex;\n flex-drirection: column;\n align-items: center;\n align-content: center;\n gap: 5px;\n border: 1px solid\n ${(props) => props.theme.colors.components.http_logs_table_border};\n border-top: none;\n background: ${(props) =>\n props.theme.colors.components.http_logs_table_header_bg};\n color: ${(props) =>\n props.theme.colors.components.http_logs_table_header_color};\n padding-top: 5px;\n\n .icon {\n cursor: pointer;\n }\n`;\n\nconst HeaderTab = styled.div<{ active?: boolean }>`\n padding: 5px 5px 0 5px;\n background: ${(props) =>\n props.active ? \"rgba(91, 127, 255, 0.15)\" : \"transparent\"};\n color: ${(props) =>\n props.active\n ? props.theme.colors.tab_active_header\n : props.theme.colors.greyscale[2]};\n border-radius: 4px;\n cursor: pointer;\n font-weight: 600;\n padding-bottom: 5px;\n transition: background 0.15s, color 0.15s;\n`;\n\nconst LogBody = styled.div<{ height: string }>`\n height: ${(props) => props.height};\n overflow: auto;\n background: ${(props) => props.theme.colors.components.http_logs_table_bg};\n color: ${(props) => props.theme.colors.components.http_logs_table_color};\n`;\n\nconst HttpHeaderTabAccordionContainer = styled.div<{ expanded?: boolean }>`\n padding: 10px 5px 10px 5px;\n\n ${(props) =>\n props.expanded &&\n `border-bottom: 1px solid ${props.theme.colors.components.http_logs_table_border}`}\n`;\n\nconst HttpHeaderTabAccordionTitleContainer = styled.div<{ active: boolean }>`\n display: flex;\n padding: 5px;\n display-direction: row;\n cursor: pointer;\n\n &:hover {\n background: ${(props) =>\n props.theme.colors.components.http_logs_table_row_hover};\n }\n`;\n\nconst HttpHeaderTabAccordionTitle = styled.span`\n font-weight: 500;\n font-size: 12px;\n`;\nconst HttpHeaderTabAccordionBody = styled.div`\n padding: 10px 10px 10px 20px;\n`;\n\nconst JsonRow = styled.div`\n padding-bottom: 7px;\n`;\n\nconst JsonKey = styled.span`\n color: ${(props) =>\n chroma(props.theme.colors.components.http_logs_table_color)\n .brighten(0.9)\n .hex()};\n font-weight: 600;\n padding-right: 2px;\n`;\n\nconst JsonValue = styled.span`\n font-size: 11px;\n white-space: break-space;\n word-break: break-all;\n padding-left: 2px;\n`;\n\nconst StyledEmptyMessage = styled(EmptyMessage)`\n color: ${(props) => props.theme.colors.components.http_logs_table_color};\n font-size: 14px;\n`;\n\nfunction HttpHeadersTab(props: {\n header: string;\n expand: boolean;\n details: Record<string, any>;\n showCount?: boolean;\n}) {\n const { header, expand, details, showCount = false } = props;\n const [expanded, setExpanded] = useState(expand);\n\n const toggleAccordion = () => setExpanded(!expanded);\n\n const rows = useMemo(() => {\n const rows = Object.keys(details)\n .filter((k) => !!details[k])\n .map((k, index) => {\n return (\n <JsonRow key={index}>\n <JsonKey>{k}:</JsonKey>\n <JsonValue>{details[k]}</JsonValue>\n </JsonRow>\n );\n });\n return <HttpHeaderTabAccordionBody>{rows}</HttpHeaderTabAccordionBody>;\n }, [details]);\n\n return (\n <HttpHeaderTabAccordionContainer expanded={expanded}>\n <HttpHeaderTabAccordionTitleContainer\n active={expanded}\n onClick={toggleAccordion}\n >\n <Icon\n name={expanded ? \"collapse-arrow\" : \"expand-arrow\"}\n onClick={toggleAccordion}\n />\n <HttpHeaderTabAccordionTitle>{`${header} ${\n showCount ? `(${Object.keys(details).length})` : \"\"\n }`}</HttpHeaderTabAccordionTitle>\n </HttpHeaderTabAccordionTitleContainer>\n {!!expanded && rows}\n </HttpHeaderTabAccordionContainer>\n );\n}\n\nenum LogTabs {\n HEADERS = \"Headers\",\n RESPONSE = \"Response\",\n PAYLOAD = \"Payload\",\n}\n\nconst FORM_URL_ENCODED_CONTENT_TYPE = new RegExp(/form-urlencoded/g);\n\nfunction getPayloadElement(type: string, data: any) {\n if (!FORM_URL_ENCODED_CONTENT_TYPE.test(type)) {\n return (\n <CodeViewer\n code={CommonUtils.parseJson(data)}\n language={\"json\"}\n lineNumber\n />\n );\n } else {\n return data;\n }\n}\n\nexport default function HttpLogDetails(props: propsType) {\n {\n const { log, onClose, parentHeight } = props;\n const [activeTab, setActiveTab] = useState(LogTabs.HEADERS);\n const [headers] = useState([\n LogTabs.HEADERS,\n LogTabs.PAYLOAD,\n LogTabs.RESPONSE,\n ]);\n const onTabChange = useCallback((tabHeader: LogTabs) => {\n setActiveTab(tabHeader);\n }, []);\n\n const header = useMemo(() => {\n const tabs = headers.map((header) => (\n <HeaderTab\n key={header}\n onClick={() => onTabChange(header)}\n active={activeTab == header}\n >\n {header}\n </HeaderTab>\n ));\n return (\n <Header>\n <Icon name=\"close\" onClick={onClose} size={Sizes.L}></Icon>\n {tabs}\n </Header>\n );\n }, [headers, activeTab]);\n\n const getBody = (header: LogTabs) => {\n let bodyContent;\n switch (header) {\n case LogTabs.HEADERS:\n bodyContent = (\n <LogBody height={`calc(100vh - ${parentHeight + 20}px)`}>\n <HttpHeadersTab\n header=\"General\"\n details={{\n \"Request URL\": log.url,\n Method: log.method,\n \"Status Code\": log.response_status,\n \"Status Text\": log.response_status_text,\n }}\n expand\n />\n <HttpHeadersTab\n header=\"Request Headers\"\n details={log.request_headers}\n showCount\n expand\n />\n <HttpHeadersTab\n header=\"Response Headers\"\n details={log.response_headers}\n showCount\n expand\n />\n </LogBody>\n );\n break;\n\n case LogTabs.RESPONSE:\n if (log.response_body) {\n bodyContent = getPayloadElement(\n log.response_content_type,\n log.response_body,\n );\n } else {\n bodyContent = (\n <Centered>\n <StyledEmptyMessage>Response not available</StyledEmptyMessage>\n </Centered>\n );\n }\n break;\n case LogTabs.PAYLOAD:\n if (log.request_post_data) {\n bodyContent = getPayloadElement(\n log.request_content_type,\n log.request_post_data,\n );\n } else {\n bodyContent = (\n <Centered>\n <StyledEmptyMessage>Payload not available</StyledEmptyMessage>\n </Centered>\n );\n }\n break;\n }\n return (\n <LogBody height={`calc(100vh - ${parentHeight + 20}px)`}>\n {bodyContent}\n </LogBody>\n );\n };\n\n return (\n <Container height={`calc(100vh - ${parentHeight}px)`}>\n {header}\n {getBody(activeTab)}\n </Container>\n );\n }\n}\n","import styled from \"styled-components\";\nimport React, { useCallback, useState } from \"react\";\nimport _ from \"lodash\";\nimport Icon, { Sizes } from \"../atoms/icon\";\nimport ParallelLayout, { Column } from \"../layouts/parallel-layout\";\nimport HttpLogDetails, { HttpLogs } from \"./http-log-details\";\nimport chroma from \"chroma-js\";\nimport { ThemeConfig } from \"../../../constants/themes\";\nimport { useSelector } from \"react-redux\";\nimport { getSelectedTheme } from \"../../../store/selectors/ui/theme-selector\";\n\ntype propsType = {\n logs: Array<HttpLogs>;\n parentHeight: number;\n};\n\nconst TABLE_HEADER_HEIGHT = 20;\n\nconst Table = styled.table<{ height: string }>`\n width: 100%;\n display: flex;\n flex-direction: column;\n height: ${(props) => props.height};\n border-right: 1px solid ${(props) => props.theme.colors.greyscale[3]};\n background: ${(props) => props.theme.colors.components.http_logs_table_bg};\n color: ${(props) => props.theme.colors.components.http_logs_table_color};\n`;\n\nconst TableHead = styled.thead`\n color: ${(props) =>\n props.theme.colors.components.http_logs_table_header_color};\n background: ${(props) =>\n props.theme.colors.components.http_logs_table_header_bg};\n`;\n\nconst TableBody = styled.tbody<{ height: string }>`\n height: ${(props) => props.height};\n overflow: auto;\n\n & > {\n tr {\n border-bottom: 1px solid\n ${(props) => props.theme.colors.components.http_logs_table_border};\n }\n\n tr:hover {\n background: ${(props) =>\n props.theme.colors.components.http_logs_table_row_hover};\n }\n }\n`;\n\nconst TH = styled.th<{ width: number }>`\n width: ${(props) => props.width}%;\n height: ${TABLE_HEADER_HEIGHT}px;\n display: flex;\n align-content: center;\n justify-content: center;\n border-left: 1px solid\n ${(props) => props.theme.colors.components.http_logs_table_border};\n font-weight: 600;\n`;\n\nconst TR = styled.tr<{ failed: boolean; active?: boolean }>`\n display: flex;\n width: 100%;\n align-items: center;\n height: 25px;\n\n &:nth-child(even) {\n background : ${(props) =>\n props.theme.colors.components.http_logs_table_even_row_bg};\n }\n \n color: ${(props) =>\n props.failed\n ? chroma(props.theme.colors.error).brighten(1).hex()\n : \"inherit\"}}!important ;\n\n ${(props) =>\n !!props.active &&\n `background: ${props.theme.colors.components.http_logs_table_row_active}!important;`} \n`;\n\nconst TD = styled.td<{ width: number }>`\n width: ${(props) => props.width}%;\n display: block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding: 1px 4px;\n font-size: 11px;\n height: 21px;\n font-weight: 400;\n cursor: pointer;\n border-left: 1px solid\n ${(props) => props.theme.colors.components.http_logs_table_border};\n`;\n\nconst LogDetailsContainer = styled.div<{ height: string }>`\n height: ${(props) => props.height};\n`;\n\nconst UrlIconContainer = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n`;\n\nconst UrlName = styled.span`\n display: block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-left: 5px;\n`;\n\nconst columns: any = [\n {\n key: \"url\",\n label: \"Name\",\n width: 65,\n getComponent: (row: HttpLogs, theme: ThemeConfig) => {\n let path: string = row.url;\n try {\n const url = new URL(row.url);\n path =\n url.pathname == \"/\" ? row.url : `${url.pathname.split(\"/\").pop()}`;\n const searchParams = row.url.split(\"?\");\n path = `${path}${\n searchParams.length > 1 ? \"?\" + searchParams.pop() : \"\"\n }`;\n } catch (err) {\n //ignore\n }\n\n return (\n <UrlIconContainer>\n {getIcon(row.request_type, theme)}\n <UrlName>{path}</UrlName>\n </UrlIconContainer>\n );\n },\n },\n {\n key: \"method\",\n label: \"Method\",\n width: 10,\n },\n {\n key: \"response_status\",\n label: \"Status\",\n width: 10,\n },\n {\n key: \"request_type\",\n label: \"Type\",\n width: 15,\n },\n];\n\nfunction getIcon(logType: string, theme: ThemeConfig) {\n const iconSize = Sizes.S;\n const themeComponent: any = theme.colors.components;\n switch (logType.toLowerCase()) {\n case \"xhr\":\n case \"fetch\":\n return (\n <Icon\n name=\"api\"\n size={iconSize}\n color={themeComponent.http_logs_table_icon_api}\n ></Icon>\n );\n case \"document\":\n return (\n <Icon\n name=\"document\"\n size={iconSize}\n color={themeComponent.http_logs_table_icon_document}\n ></Icon>\n );\n case \"image\":\n return <Icon name=\"image\" size={iconSize}></Icon>;\n case \"stylesheet\":\n return <Icon name=\"css\" size={iconSize}></Icon>;\n case \"script\":\n return (\n <Icon\n name=\"code\"\n size={iconSize}\n color={themeComponent.http_logs_table_icon_script}\n ></Icon>\n );\n default:\n return <Icon name=\"square\" size={iconSize}></Icon>;\n }\n}\n\nfunction getColumns(isLogsSelected: boolean) {\n return isLogsSelected\n ? [\n {\n ...columns[0],\n width: 100,\n },\n ]\n : columns;\n}\n\nfunction getHeader(isLogSelected: boolean) {\n const headers = getColumns(isLogSelected).map((c: any) => {\n return (\n <TH key={`th-${c.key}`} width={c.width}>\n {c.label}\n </TH>\n );\n });\n return (\n <TR key={`tr-header`} failed={false}>\n {headers}\n </TR>\n );\n}\n\nfunction getRows(\n logs: Array<HttpLogs>,\n selectedLog: HttpLogs | null,\n onLogSelected: (log: HttpLogs) => any,\n theme: ThemeConfig,\n) {\n return logs.map((l: HttpLogs, index: number) => {\n const cells = getColumns(!!selectedLog).map((c: any) => {\n let value: any = l[c.key as keyof HttpLogs];\n if (_.isFunction(c.getComponent)) {\n value = c.getComponent(l, theme);\n } else if (_.isFunction(c.getCellValue)) {\n value = c.getCellValue(l);\n }\n\n return (\n <TD\n key={`td-${index}-${c.key}`}\n width={c.width}\n onClick={() => onLogSelected(l)}\n >\n {value}\n </TD>\n );\n });\n const isFailure = l.response_status >= 400 && l.response_status <= 600;\n return (\n <TR\n key={`tr-${index}`}\n failed={isFailure}\n active={selectedLog?.id == l.id}\n >\n {cells}\n </TR>\n );\n });\n}\n\nexport default function HttpLogsTable(props: propsType) {\n const { logs, parentHeight } = props;\n const theme = useSelector(getSelectedTheme);\n const [selectedLog, setSelectedLog] = useState<HttpLogs | null>(null);\n\n const onLogSelected = useCallback((log: HttpLogs | null) => {\n setSelectedLog(log);\n }, []);\n\n return (\n <ParallelLayout>\n <Column grid={!!selectedLog ? 4 : 12}>\n <Table height={`calc(100vh - ${parentHeight}px)`}>\n <TableHead>{getHeader(!!selectedLog)}</TableHead>\n <TableBody\n height={`calc(100vh - ${parentHeight + TABLE_HEADER_HEIGHT}px)`}\n >\n {getRows(logs, selectedLog, (log) => onLogSelected(log), theme)}\n </TableBody>\n </Table>\n </Column>\n {!!selectedLog ? (\n <Column grid={8}>\n <LogDetailsContainer height={`calc(100vh - ${parentHeight}px)`}>\n <HttpLogDetails\n log={selectedLog}\n onClose={() => onLogSelected(null)}\n parentHeight={parentHeight}\n ></HttpLogDetails>\n </LogDetailsContainer>\n </Column>\n ) : null}\n </ParallelLayout>\n );\n}\n","import chroma from \"chroma-js\";\nimport React, { useCallback, useEffect } from \"react\";\nimport { useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport { fetchSessionHttpLogs } from \"../../../../store/actions/session-actions\";\nimport {\n getHttpLogs,\n getisHttpLogsLoading,\n} from \"../../../../store/selectors/entities/logs-selector\";\nimport Input from \"../../atoms/input\";\nimport Spinner from \"../../atoms/spinner\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport Centered from \"../../molecules/centered\";\nimport HttpLogsTable from \"../http-logs-table\";\nimport { TAB_HEADER_HEIGHT } from \"../../layouts/tab-layout\";\n\nconst HEADER_HEIGHT = 40;\n\nconst Container = styled.div``;\n\nconst HeaderContainer = styled.div`\n background: ${(props) => props.theme.colors.primary};\n border: 1px solid ${(props) => props.theme.colors.border};\n padding-left: 20px;\n display: flex;\n flex-direction: column;\n justify-content: center;\n`;\n\nconst LogTypeFilterContainer = styled.div`\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n gap: 4px;\n margin: auto;\n`;\n\nconst LogTypeFilterItem = styled.div<{ isSelected?: boolean }>`\n background: ${(props) =>\n props.isSelected\n ? chroma(props.theme.colors.primary).brighten(2).hex()\n : \"transparent\"};\n color: ${(props) => props.theme.colors.greyscale[6]};\n padding: 3px 7px 3px 7px;\n border-radius: 12px;\n cursor: pointer;\n\n ${(props) =>\n !props.isSelected &&\n `&:hover {\n background: ${chroma(props.theme.colors.primary).brighten(1.5).hex()}\n }`};\n`;\n\n/*Document, Stylesheet, Image, Media, Font, Script, TextTrack, XHR, Fetch, EventSource, WebSocket, Manifest, SignedExchange, Ping, CSPViolationReport, Preflight, Other */\n\n//TODO: Refactor this. temporary changes\nconst StyledInput = styled(Input)`\n background: transparent;\n\n &&& input {\n background: transparent;\n color: #fff;\n background: ${(props) =>\n chroma(props.theme.colors.primary).brighten(0.6).hex()};\n border: 1px solid\n ${(props) => chroma(props.theme.colors.primary).brighten(1).hex()};\n height: 25px;\n padding: 0 0 0 5px;\n ::placeholder {\n color: ${(props) => chroma(props.theme.colors.primary).brighten(4).hex()};\n opacity: 1;\n line-height: 90px;\n }\n }\n\n &&& path {\n background: #fff;\n stroke: #fff;\n }\n`;\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nconst requestTypeFilters = [\n {\n label: \"All\",\n id: 0,\n filterRegex: /xhr|fetch/i,\n },\n {\n label: \"XHR/Fetch\",\n id: 1,\n filterRegex: /xhr|fetch/i,\n },\n {\n label: \"JS\",\n id: 2,\n filterRegex: /script/i,\n },\n {\n label: \"CSS\",\n id: 3,\n filterRegex: /stylesheet/i,\n },\n {\n label: \"Img\",\n id: 4,\n filterRegex: /image/i,\n },\n {\n label: \"Media\",\n id: 5,\n filterRegex: /media/i,\n },\n {\n label: \"Font\",\n id: 6,\n filterRegex: /font/i,\n },\n {\n label: \"Doc\",\n id: 7,\n filterRegex: /document/i,\n },\n {\n label: \"Other\",\n id: 8,\n filterRegex: /other/i,\n },\n];\n\nfunction useLogs(opts: { textFilter?: string; requestTypeFilterId?: number }) {\n const { textFilter, requestTypeFilterId = 0 } = opts;\n const logs = useSelector(getHttpLogs);\n const filters = [];\n if (textFilter) {\n filters.push((log: any) => log.url && log.url.indexOf(textFilter) >= 0);\n }\n if (requestTypeFilterId > 0) {\n const typeFilter = requestTypeFilters.filter(\n (f) => f.id == requestTypeFilterId,\n )[0];\n filters.push((log: any) =>\n new RegExp(typeFilter.filterRegex).test(log.request_type),\n );\n }\n return filters.reduce(\n (acc, filterFn) => {\n return acc.filter(filterFn);\n },\n [...logs],\n );\n}\n\nexport default function SessionHttpLogs(props: PropsType) {\n const { session, parentHeight } = props;\n const isLoading = useSelector(getisHttpLogsLoading);\n const dispatch = useDispatch();\n\n const [selectedRequestTypeFilter, setSelectedRequestTypeFilter] = useState(0);\n const [textFilter, setTextFilter] = useState(\"\");\n\n const logs = useLogs({\n requestTypeFilterId: selectedRequestTypeFilter,\n textFilter: textFilter,\n });\n\n /* Event callbacks */\n const onRequestTypeFilterChange = useCallback((index: number) => {\n setSelectedRequestTypeFilter(index);\n }, []);\n\n const onTextFilterChange = useCallback((text: string) => {\n setTextFilter(text);\n }, []);\n\n function getRequestTypeFilters() {\n return requestTypeFilters.map((filter) => (\n <LogTypeFilterItem\n key={filter.label}\n isSelected={filter.id == selectedRequestTypeFilter ? true : false}\n onClick={() => onRequestTypeFilterChange(filter.id)}\n >\n {filter.label}\n </LogTypeFilterItem>\n ));\n }\n\n useEffect(() => {\n dispatch(fetchSessionHttpLogs(session.session_id));\n }, [session.session_id]);\n\n if (isLoading) {\n return (\n <Centered>\n <Spinner />\n </Centered>\n );\n } else {\n return (\n <Container>\n <SerialLayout>\n <Row height={`${HEADER_HEIGHT}px`}>\n <HeaderContainer>\n <ParallelLayout>\n <Column grid={3}>\n <StyledInput\n name=\"search\"\n type=\"text\"\n placeholder=\"Filter logs\"\n leftIcon=\"filter\"\n width=\"200px\"\n value={textFilter}\n onChange={(e) => onTextFilterChange(e.target.value)}\n />\n </Column>\n <Column grid={9}>\n <LogTypeFilterContainer>\n {getRequestTypeFilters()}\n </LogTypeFilterContainer>\n </Column>\n </ParallelLayout>\n </HeaderContainer>\n </Row>\n {/* Table entry */}\n <Row\n height={`calc(100vh - ${\n HEADER_HEIGHT + TAB_HEADER_HEIGHT + parentHeight\n }px)`}\n >\n <HttpLogsTable\n logs={logs}\n parentHeight={HEADER_HEIGHT + TAB_HEADER_HEIGHT + parentHeight}\n />\n </Row>\n </SerialLayout>\n </Container>\n );\n }\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport TabsLayout, { Tab } from \"../../layouts/tab-layout\";\nimport SessionDebugLogs from \"./session-debug-logs\";\nimport SessionDeviceLogs from \"./session-device-logs\";\nimport SessionTextLogs from \"./session-text-logs\";\nimport Profiling from \"./session-app-profiling\";\nimport SessionHttpLogs from \"./session-http-logs\";\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nconst Container = styled.div`\n border: 1px solid ${(props) => props.theme.colors.border};\n border-bottom: none;\n margin: 20px;\n overflow: hidden;\n`;\n\nenum TAB_HEADERS {\n TEXTLOGS = \"Text Logs\",\n DEVICELOGS = \"Device Logs\",\n DEBUGLOGS = \"Debug Logs\",\n PROFILING = \"App profiling\",\n NETWORK = \"Network Logs\",\n}\n\nexport default function SessionLogs(props: PropsType) {\n const { session, parentHeight } = props;\n\n return (\n <Container>\n <TabsLayout selected={TAB_HEADERS.TEXTLOGS}>\n <Tab name={TAB_HEADERS.TEXTLOGS}>\n <SessionTextLogs session={session} parentHeight={parentHeight} />\n </Tab>\n <Tab name={TAB_HEADERS.DEVICELOGS}>\n <SessionDeviceLogs session={session} parentHeight={parentHeight} />\n </Tab>\n <Tab name={TAB_HEADERS.DEBUGLOGS}>\n <SessionDebugLogs session={session} parentHeight={parentHeight} />\n </Tab>\n {session.is_completed && session.is_profiling_available && (\n <Tab name={TAB_HEADERS.PROFILING}>\n <Profiling session={session} parentHeight={parentHeight} />\n </Tab>\n )}\n {session.is_completed && session.is_http_logs_available && (\n <Tab name={TAB_HEADERS.NETWORK}>\n <SessionHttpLogs session={session} parentHeight={parentHeight} />\n </Tab>\n )}\n </TabsLayout>\n </Container>\n );\n}\n","import React from \"react\";\nimport Moment from \"react-moment\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport Session from \"../../../../interfaces/session\";\nimport styled from \"styled-components\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\n\nconst SUMMARY_CONFIG: any[] = [\n {\n label: \"Session ID\",\n key: \"session_id\",\n },\n {\n label: \"OS\",\n key: \"platform_name\",\n icon: (session: any) => {\n const icons: any = {\n android: <Icon name=\"android\" size={Sizes.XL} />,\n ios: <Icon name=\"ios\" size={Sizes.XL} />,\n };\n return icons[session.platform_name.toLowerCase()];\n },\n },\n {\n label: \"Os Version\",\n key: \"platform_version\",\n },\n {\n label: \"Start Time\",\n formatValue: (session: any) => {\n return (\n <Moment format=\"DD-MMM-YYYY HH:mm:ss\">{session.start_time}</Moment>\n );\n },\n },\n {\n label: \"End Time\",\n formatValue: (session: any) => {\n return session.end_time ? (\n <Moment format=\"DD-MMM-YYYY HH:mm:ss\">{session.end_time}</Moment>\n ) : (\n \"-\"\n );\n },\n },\n {\n label: \"Duration\",\n formatValue: (session: any) => {\n return CommonUtils.getReadableDuration(\n new Date(session.start_time),\n session.end_time ? new Date(session.end_time) : new Date(),\n );\n },\n },\n {\n label: \"Device Name\",\n key: \"device_name\",\n },\n {\n label: \"UDID\",\n key: \"udid\",\n },\n {\n label: \"App Version\",\n key : \"app_version\"\n },\n {\n or: [\n {\n label: \"App\",\n key: \"app\",\n formatValue: (session: any) => {\n return session.app.split(\"/\").pop();\n },\n },\n {\n label: \"Browser\",\n key: \"browser_name\",\n icon: (session: any) => {\n const icons: any = {\n safari: <Icon name=\"safari\" size={Sizes.M} />,\n chrome: <Icon name=\"chrome\" size={Sizes.M} />,\n };\n return icons[session.browser_name];\n },\n },\n ],\n },\n];\n\nconst Container = styled.div`\n background: ${(props) => props.theme.colors.greyscale[5]};\n padding: 10px;\n border-bottom: 1px solid ${(props) => props.theme.colors.border};\n`;\n\nconst Entry = styled.div`\n display: inline-block;\n width: 33%;\n padding: 5px 0px;\n`;\n\nconst Label = styled.div`\n margin-right: 20px;\n font-size: 13px;\n font-weight: 600;\n color: ${(props) => props.theme.colors.greyscale[2]};\n min-width: 95px;\n text-overflow: ellipsis;\n`;\n\nconst Value = styled.div`\n font-size: 12px;\n display: flex;\n flex-direction: row;\n align-items: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis !important;\n\n & > span {\n margin-right: 5px;\n }\n`;\n\nconst getEntry = (session: Session, entry: any) => {\n if (entry.or) {\n entry = entry.or.filter((e: any) => !!session[e.key])[0];\n }\n if (!entry) {\n return;\n }\n if (entry.formatValue && typeof entry.template == \"function\") {\n return entry.formatValue(session);\n }\n return (\n <ParallelLayout>\n <Column grid={3}>\n <Label>{entry.label}:</Label>\n </Column>\n <Column grid={9}>\n <Value>\n {entry.icon && entry.icon(session)}\n {entry.formatValue ? entry.formatValue(session) : session[entry.key]}\n </Value>\n </Column>\n </ParallelLayout>\n );\n};\n\ntype PropsType = {\n session: Session;\n};\n\nexport default function SessionSummary(props: PropsType) {\n const { session } = props;\n return (\n <Container>\n {SUMMARY_CONFIG.map((entry, index) => (\n <Entry key={index}>{getEntry(session, entry)}</Entry>\n ))}\n </Container>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Button from \"./button\";\n\nconst Container = styled.div`\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n height: 100%;\n gap: 10px;\n`;\n\nconst VideoContainer = styled.div`\n height: 90%;\n width: 100%;\n`;\n\nconst StyledVideo = styled.video`\n width: 100%;\n height: auto;\n max-height: 100%;\n`;\n\nconst DownloadButton = styled.a`\n width: 50%;\n color: #fff;\n background: #6fc76b;\n padding: 5px;\n margin-right: 10px;\n margin-left: 10px;\n border-radius: 10px;\n text-align: center;\n font-size: 14px;\n`;\n\ntype PropsType = {\n session_id: string;\n url: string;\n downloadUrl: string;\n height?: number;\n width?: number;\n};\n\nexport default function VideoPlayer(props: PropsType) {\n const { url, width, downloadUrl, session_id } = props;\n return (\n <Container>\n <VideoContainer>\n <StyledVideo\n className=\"react-player\"\n src={url}\n width={width || \"100%\"}\n controls={true}\n controlsList=\"nodownload\"\n />\n </VideoContainer>\n <DownloadButton href={downloadUrl} download={session_id}>\n Download Video\n </DownloadButton>\n </Container>\n );\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport Session from \"../../../../interfaces/session\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport VideoPlayer from \"../../atoms/video-player\";\nimport styled from \"styled-components\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport Spinner from \"../../atoms/spinner\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\n\nconst Container = styled.div<{ height: string }>`\n height: ${(props) => props.height};\n transition: height 1s 0.1s ease-in-out, opacity 2s ease-in-out;\n overflow: hidden;\n position: relative;\n padding: 10px 0 10px 0;\n`;\n\nconst EmptyVideoContainer = styled.div`\n height: 100%;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n\n /* box shadow*/\n -webkit-box-shadow: 0px 10px 10px -10px #000000;\n -moz-box-shadow: 0px 10px 10px -10px #000000;\n box-shadow: 0px 10px 10px -10px #000000;\n\n & p {\n text-align: center;\n }\n`;\n\ntype PropsType = {\n session: Session;\n height: string;\n onVideoSizeChanged: (state: boolean) => any;\n isFullScreen: boolean;\n};\n\nconst LiveVideoContainer = styled.div`\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n`;\n\nconst VideoImg = styled.img<{ hide: boolean }>`\n height: 100%;\n widht: 100%;\n object-fit: scale-down;\n top: 10px;\n left: 10px;\n border: 1px solid ${(props) => props.theme.colors.border};\n display: ${(props) => (!!props.hide ? \"none\" : \"block\")};\n`;\n\nconst LoadingContainer = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-tems: center;\n`;\n\nconst LiveBadge = styled.span`\n color: red;\n position: absolute;\n top: 10px;\n right: 10px;\n font-weight: 500;\n\n @keyframes blink {\n 20% {\n opacity: 0.8;\n }\n 40% {\n opacity: 0.4;\n }\n 60% {\n opacity: 0;\n }\n 80% {\n opacity: 0.4;\n }\n 100% {\n opacity: 0.8;\n }\n }\n\n &::before {\n content: \"\";\n display: inline-block;\n background: red;\n margin-right: 5px;\n height: 8px;\n width: 8px;\n border-radius: 50%;\n animation: blink 1s step-start 0s infinite;\n }\n`;\n\nconst VideoResizeIcon = styled.div`\n position: absolute;\n bottom: 10px;\n right: 5px;\n cursor: pointer;\n`;\n\nconst getVideoNotFoundMessage = (session: Session) => {\n if (session.is_completed) {\n return \"Error occured while saving the video\";\n } else {\n return \"Video will be available once the execution is completed\";\n }\n};\n\nexport default function SessionVideo(props: PropsType) {\n const { session, height, onVideoSizeChanged, isFullScreen } = props;\n const [liveStreamLoading, setLiveStreamLoading] = useState(true);\n const [liveStreamError, setLiveStreamError] = useState(false);\n\n const imageLoaded = useCallback((errored: boolean) => {\n setLiveStreamLoading(false);\n setLiveStreamError(errored);\n }, []);\n\n useEffect(() => {\n if (!session.is_completed) {\n setLiveStreamLoading(true);\n setLiveStreamError(false);\n }\n }, [session.session_id, session.session_status]);\n\n const getVideoPlayer = () => {\n if (!session.is_completed && !!session.live_stream_port) {\n return (\n <LiveVideoContainer>\n {liveStreamLoading && (\n <LoadingContainer>\n <Spinner />\n <EmptyMessage>Loading live video..</EmptyMessage>\n </LoadingContainer>\n )}\n {liveStreamError && (\n <EmptyVideoContainer>\n <EmptyMessage>Unable to render live video</EmptyMessage>\n </EmptyVideoContainer>\n )}\n <VideoImg\n src={CommonUtils.getLiveVideoForSession(session.session_id)}\n onLoad={() => imageLoaded(false)}\n onError={() => imageLoaded(true)}\n hide={liveStreamLoading || liveStreamError}\n />\n {!liveStreamLoading && !liveStreamError && (\n <>\n <LiveBadge>LIVE</LiveBadge>\n <VideoResizeIcon>\n {isFullScreen ? (\n <Icon\n name=\"minimize\"\n size={Sizes.M}\n tooltip=\"Minimize\"\n onClick={() => onVideoSizeChanged(false)}\n />\n ) : (\n <Icon\n name=\"maximize\"\n tooltip=\"Expand\"\n size={Sizes.M}\n onClick={() => onVideoSizeChanged(true)}\n />\n )}\n </VideoResizeIcon>\n </>\n )}\n </LiveVideoContainer>\n );\n } else if (session.is_completed && session.video_path) {\n return (\n <VideoPlayer\n session_id={session.session_id}\n downloadUrl={CommonUtils.getDownloadVideoForSession(\n session.session_id,\n )}\n url={CommonUtils.getVideoForSession(session.session_id)}\n />\n );\n } else {\n return (\n <EmptyVideoContainer>\n <EmptyMessage>{getVideoNotFoundMessage(session)}</EmptyMessage>\n </EmptyVideoContainer>\n );\n }\n };\n\n return <Container height={height}>{getVideoPlayer()}</Container>;\n}\n","import React, { useCallback, useEffect } from \"react\";\nimport styled from \"styled-components\";\nimport Session from \"../../../../interfaces/session\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\nimport Spinner, { Sizes as SpinnerSize } from \"../../atoms/spinner\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n deleteSession,\n setSelectedSession,\n pauseSession,\n resumeSession,\n} from \"../../../../store/actions/session-actions\";\nimport {\n isSessionDeleting,\n getSessionDeleteResponse,\n getSessionStateChangeResponse,\n isStateChangePending,\n} from \"../../../../store/selectors/entities/sessions-selector\";\nimport { ToastContainer, toast } from \"react-toastify\";\nimport \"react-toastify/dist/ReactToastify.css\";\n\nconst Container = styled.div`\n padding: 0 30px 0px 0;\n display: flex;\n justify-content: end;\n align-items: center;\n color: #fff;\n & .icon {\n cursor: pointer;\n }\n`;\n\nconst IconGroup = styled.div`\n display: flex;\n align-items: center;\n height: 25px !important;\n gap: 12px;\n`;\n\nconst IconContainer = styled.div`\n margin-left: 20px;\n`;\n\ntype PropsType = {\n session: Session;\n paused: boolean;\n debugging: boolean;\n onStateChanged: (state: boolean) => any;\n onDebuggingToggled: (state: boolean) => any;\n};\n\nexport default function sessionMenuItems(props: PropsType) {\n const { session, paused, debugging, onStateChanged, onDebuggingToggled } =\n props;\n const dispatch = useDispatch();\n const deletePending = useSelector(isSessionDeleting);\n const stateChangePending = useSelector(isStateChangePending);\n const deleteResponse = useSelector(getSessionDeleteResponse);\n const stateChangeResponse = useSelector(getSessionStateChangeResponse);\n\n const debugToggleChange = (state: boolean) => {\n if (!!state) {\n !paused && onPause(session.session_id);\n } else {\n onResume(session.session_id);\n }\n onDebuggingToggled(state);\n };\n\n const onDelete = useCallback((id: string) => {\n dispatch(deleteSession(id));\n }, []);\n\n const onPause = useCallback((id: string) => {\n dispatch(pauseSession(id));\n }, []);\n\n const onResume = useCallback((id: string) => {\n dispatch(resumeSession(id));\n }, []);\n\n useEffect(() => {\n if (deleteResponse && deleteResponse.success) {\n dispatch(setSelectedSession(null));\n }\n }, [deleteResponse]);\n\n useEffect(() => {\n if (!stateChangeResponse) {\n return;\n }\n\n if (stateChangeResponse.success) {\n onStateChanged(!paused);\n } else {\n toast.error(stateChangeResponse.message, {\n position: \"top-right\",\n autoClose: 2000,\n hideProgressBar: false,\n closeOnClick: true,\n pauseOnHover: false,\n draggable: true,\n progress: undefined,\n });\n if (debugging) {\n onDebuggingToggled(!debugging);\n }\n }\n }, [stateChangeResponse]);\n\n function getPlayPauseIcon() {\n if (debugging) {\n return <></>;\n }\n if (paused) {\n return (\n <Icon\n name=\"play\"\n tooltip=\"Resume\"\n size={Sizes.XL}\n onClick={() => onResume(session.session_id)}\n ></Icon>\n );\n } else {\n return (\n <Icon\n name=\"pause\"\n tooltip=\"Pause\"\n size={Sizes.XL}\n onClick={() => onPause(session.session_id)}\n ></Icon>\n );\n }\n }\n\n function getDebuggerIcon() {\n if (!debugging) {\n return (\n <Icon\n name=\"debug\"\n tooltip=\"Pause & Debug\"\n size={Sizes.XL}\n onClick={() => debugToggleChange(true)}\n ></Icon>\n );\n } else {\n return (\n <Icon\n name=\"stop\"\n tooltip=\"Stop debugging\"\n size={Sizes.XL}\n onClick={() => debugToggleChange(false)}\n ></Icon>\n );\n }\n }\n\n function showStopIcon(){\n return <\n IconContainer>\n <Icon\n name=\"stop\"\n tooltip = \"terminate session\"\n size={Sizes.L}\n onClick={() => alert(\"I was asked to terminate session\")}\n ></Icon>\n </IconContainer>\n }\n\n return (\n <Container>\n <ToastContainer />\n <IconGroup>\n {/* Show pause/play icon only if the session is still running */}\n {!session.is_completed &&\n (stateChangePending ? (\n <Spinner size={SpinnerSize.S} />\n ) : (\n showStopIcon(), getPlayPauseIcon()\n ))}\n\n {!session.is_completed && getDebuggerIcon()}\n {/* Show delete icon only if the session execution is completed */}\n {session.is_completed &&\n (deletePending ? (\n <Spinner size={SpinnerSize.S} />\n ) : (\n <div>\n <IconContainer>\n <Icon\n name=\"delete\"\n tooltip=\"Delete\"\n size={Sizes.L}\n onClick={() => onDelete(session.session_id)}\n ></Icon>\n </IconContainer>\n </div>\n\n ))}\n </IconGroup>\n </Container>\n );\n}\n","import React, { useCallback, useEffect, useState } from \"react\";\nimport CodeMirror from \"@uiw/react-codemirror\";\nimport { js as jsBeautify } from \"js-beautify\";\nimport { javascript } from \"@codemirror/lang-javascript\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport Session from \"../../../../interfaces/session\";\nimport styled from \"styled-components\";\nimport Icon, { Sizes as IconSize } from \"../../atoms/icon\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n getDriverScriptResult,\n isDriverScriptExecutionPending,\n} from \"../../../../store/selectors/entities/sessions-selector\";\nimport {\n runDriverScript,\n sessionScriptExecutionReset,\n} from \"../../../../store/actions/session-actions\";\nimport Spinner, { Sizes } from \"../../atoms/spinner\";\nimport _ from \"lodash\";\n\nconst EDITOR_HEADER_HEIGHT_PX = 30;\n\nconst Container = styled.div<{ height: string }>`\n height: ${(props) => props.height};\n padding: 5px 10px 0px 10px;\n`;\n\nconst FlexContainer = styled.div`\n height: 100%;\n display: flex;\n flex-direction: column;\n`;\n\nconst EditorContainer = styled.div<{ height?: string }>`\n height: ${(props) => props.height};\n\n & .cm-theme-dark,\n .cm-editor {\n height: 100%;\n font-size: 13px;\n }\n`;\n\nconst EditorHeader = styled.div`\n display: flex;\n align-items: flex-end;\n justify-items: center;\n flex-direction: column;\n background: #4f535a;\n border: 1px solid #6f747c;\n`;\n\nconst EditorControls = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n flex-direction: row;\n gap: 15px;\n height: 100%;\n margin-right: 10px;\n\n & > .icon {\n cursor: pointer;\n }\n`;\n\nconst TextWithIcon = styled.div`\n font-size: 11px;\n display: flex;\n flex-direction: row;\n align-items: center;\n white-space: nowrap;\n overflow: hidden;\n cursor: pointer;\n\n & > span {\n padding-right: 5px;\n padding-top: 1px;\n }\n`;\n\nconst RunButton = styled(TextWithIcon)`\n color: ${(props) => props.theme.colors.greyscale[6]};\n font-weight: 400;\n max-width: 120px;\n`;\n\nconst ConsoleContainer = styled(Container)`\n padding: 0;\n display: flex:\n flex-direction: column;\n`;\n\nconst ConsoleHeader = styled.div`\n height: 20px;\n background: #2a2121;\n border: 1px solid #666666;\n display: flex;\n flex-direction: column;\n padding-left: 10px;\n align-items: flex-start;\n justify-content: center;\n`;\n\nconst ConsoleHeaderLabel = styled(TextWithIcon)`\n color: ${(props) => props.theme.colors.greyscale[6]};\n font-weight: 400;\n font-size: 11px;\n`;\n\nconst ConsoleBody = styled.div`\n height: 100%;\n background: #282c34;\n overflow: auto;\n padding: 10px 0 10px 5px;\n`;\n\nconst ConsoleEntry = styled.div<{ error: boolean }>`\n padding: 3px 3px 3px 3px;\n font-size: 11px;\n line-height: 20px;\n white-space: pre-wrap;\n\n color: ${(props) => (props.error ? \"#e77a7a\" : \"#cfd6dc\")};\n\n &:hover {\n background: #32383f;\n }\n`;\n\ntype PropsType = {\n session: Session;\n parentHeight: number;\n};\n\nconst DEFAULT_SCRIPT =\n \"/* Run webdriver.io script using driver object \" +\n \"\\n* Avaliable objects are driver, console and Promise \" +\n '\\n* Example: \\n* await driver.$(\"~Login\").click();' +\n '\\n* console.log(await driver.$(\"~Title\").getText());' +\n \"\\n*/\\n\";\n\nexport default function SessionScriptExecutor(props: PropsType) {\n const { session, parentHeight } = props;\n const dispatch = useDispatch();\n const isRunning = useSelector(isDriverScriptExecutionPending);\n const driverScriptResult = useSelector(getDriverScriptResult);\n const [script, setScript] = useState(\"\");\n const [showConsole, setShowConsole] = useState(true);\n\n const onScriptChanged = (script: string) => {\n setScript(script);\n };\n\n const formatCode = () => {\n setScript(\n jsBeautify(script, { indent_size: 2, space_in_empty_paren: true }),\n );\n };\n\n const getLogs = useCallback(() => {\n if (!driverScriptResult) {\n return [];\n }\n const logs: any = [];\n const rawLogs = [\n ...(driverScriptResult?.logs || []),\n { level: \"result\", message: [driverScriptResult?.result] },\n ];\n\n console.log(rawLogs);\n rawLogs.filter(Boolean).forEach((l: any, index: number) => {\n l.message.forEach((m: any, mIndex: number) => {\n if (m && typeof m == \"object\") {\n if (m.stack) {\n logs.push(\n <ConsoleEntry error key={`log-line-${index}-m-${mIndex}-stack`}>\n {m.stack}\n </ConsoleEntry>,\n );\n } else {\n logs.push(\n <ConsoleEntry\n error={false}\n key={`log-line-${index}-m-${mIndex}-message`}\n >\n {JSON.stringify(m, null, 2)}\n </ConsoleEntry>,\n );\n }\n } else {\n if (m && !_.isString(m)) {\n m = JSON.stringify(m);\n }\n logs.push(\n <ConsoleEntry\n error={false}\n key={`log-line-${index}-m-${mIndex}-message`}\n >\n {m || \"null\"}\n </ConsoleEntry>,\n );\n }\n });\n });\n return logs;\n }, [driverScriptResult]);\n\n useEffect(() => {\n dispatch(sessionScriptExecutionReset(null));\n setScript(DEFAULT_SCRIPT);\n }, [session.session_id]);\n\n const runScript = () => {\n dispatch(\n runDriverScript({\n sessionId: session.session_id,\n script: script,\n }),\n );\n };\n\n return (\n <Container height={`calc(100vh - ${parentHeight}px)`}>\n <SerialLayout height=\"100%\">\n <Row height={`${EDITOR_HEADER_HEIGHT_PX}px`}>\n <EditorHeader>\n <EditorControls>\n <Icon\n name=\"code-format\"\n size={IconSize.S}\n color=\"#ffffff\"\n tooltip={\"Format code\"}\n onClick={() => formatCode()}\n />\n <Icon\n name=\"terminal\"\n size={IconSize.L}\n color=\"#ffffff\"\n tooltip={showConsole ? \"Close console\" : \"Open console\"}\n onClick={() => setShowConsole(!showConsole)}\n />\n {isRunning ? (\n <RunButton>\n <Spinner size={Sizes.XS} />\n Running..\n </RunButton>\n ) : (\n <RunButton onClick={runScript}>\n <Icon\n name=\"play\"\n size={IconSize.S}\n color=\"#86ed86\"\n tooltip=\"Run script\"\n />\n Run\n </RunButton>\n )}\n </EditorControls>\n </EditorHeader>\n </Row>\n <Row\n height={`calc(100vh - ${parentHeight + EDITOR_HEADER_HEIGHT_PX}px)`}\n >\n <FlexContainer>\n <EditorContainer height={!!showConsole ? \"60%\" : \"100%\"}>\n <CodeMirror\n placeholder={jsBeautify(DEFAULT_SCRIPT, {\n indent_size: 2,\n space_in_empty_paren: true,\n })}\n value={script}\n height=\"100\"\n extensions={[javascript()]}\n onChange={(value) => {\n onScriptChanged(value);\n }}\n theme=\"dark\"\n />\n </EditorContainer>\n\n {!!showConsole && (\n <ConsoleContainer height=\"40%\">\n <ConsoleHeader>\n <ConsoleHeaderLabel>\n <Icon name=\"terminal\" size={IconSize.L} color=\"#ffffff\" />\n Console\n </ConsoleHeaderLabel>\n </ConsoleHeader>\n <ConsoleBody>{getLogs()}</ConsoleBody>\n </ConsoleContainer>\n )}\n </FlexContainer>\n </Row>\n </SerialLayout>\n </Container>\n );\n}\n","import React, { useCallback, useState, useMemo, useEffect } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport {\n APP_HEADER_HEIGHT,\n SUB_APP_HEADER_HEIGHT,\n} from \"../../../../constants/ui\";\nimport { getSelectedSession } from \"../../../../store/selectors/entities/sessions-selector\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport SessionCapabilityDetails from \"./session-capability-details\";\nimport SessionLogs from \"./session-logs\";\nimport SessionSummary from \"./session-summary\";\nimport SessionVideo from \"./session-video\";\nimport chroma from \"chroma-js\";\nimport Session from \"../../../../interfaces/session\";\nimport SessionMenuItems from \"./session-details-menu-items\";\nimport { Tooltip } from \"@mui/material\";\nimport SessionScriptExecutor from \"./session-script-executor\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\n\nconst Container = styled.div`\n @-webkit-keyframes progress {\n 0% {\n background-position: 0 0;\n }\n\n to {\n background-position: 200px 0;\n }\n }\n\n @keyframes progress {\n 0% {\n background-position: 0 0;\n }\n\n to {\n background-position: 200px 0;\n }\n }\n\n @keyframes session-summary-expand {\n 0% {\n bottom: -5px;\n }\n 50% {\n bottom: 0px;\n }\n 100% {\n bottom: -5px;\n }\n }\n\n & > * {\n .collapsible-row {\n transition: height 0.75s ease-out;\n }\n }\n`;\n\nconst HEADER = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 14px 10px;\n`;\n\nconst Name = styled.div`\n font-size: ${(props) => props.theme.fonts.size.XXL};\n`;\n\nconst ErrorContainer = styled.div`\n border: 1px solid rgba(244, 88, 88, 0.3);\n border-left: 5px solid ${(props) => props.theme.colors.error};\n background: rgba(244, 88, 88, 0.08);\n color: ${(props) => props.theme.colors.error};\n border-radius: ${(props) => props.theme.borderRadius.M};\n overflow: scroll;\n padding: 10px;\n margin: 0 15px 0 15px;\n z-index: 1;\n font-size: 13px;\n`;\n\nconst ProgressIndicator = styled.div`\n animation: progress 2s linear infinite;\n`;\n\nconst RunningProgressIndicator = styled(ProgressIndicator)`\n background: repeating-linear-gradient(\n -45deg,\n #3d85c6,\n #3d85c6 10px,\n #9fc5e8 0,\n #9fc5e8 20px\n );\n`;\n\nconst PausedProgressIndicator = styled(ProgressIndicator)`\n background: repeating-linear-gradient(\n -45deg,\n #f1c232,\n #f1c232 10px,\n #fff2cc 0,\n #fff2cc 20px\n );\n`;\nconst SummaryContainer = styled.div`\n position: relative;\n display: flex;\n justify-contents: center;\n align-items: center;\n flex-direction: column;\n transition: all 1s;\n height: auto;\n`;\n\nconst SummaryCollapseIcon = styled.div`\n position: absolute;\n animation: session-summary-expand 1s linear infinite;\n cursor: pointer;\n\n & > {\n .icon {\n color: #12bbef;\n }\n }\n`;\n\nexport const SUMMARY_HEIGHT = 110;\nexport const FAIL_MESSAGE_CONTAINER_HEIGHT = 80;\nexport const PADDING = 10;\nexport const VIDEO_PLAYER_HEIGHT = 400;\n/* App will go into responsive mode below the given width */\nexport const RESPONSIVE_WIDTH = 1400;\n\nfunction hasSessionFailureMessage(session: Session | null) {\n return (\n session &&\n session.session_status === \"FAILED\" &&\n session.session_status_message\n );\n}\n\nfunction getSessiobDetailsMainContainerHeight(\n session: Session | null,\n hideSummary: boolean,\n) {\n return (\n (hideSummary ? 0 : SUMMARY_HEIGHT) +\n APP_HEADER_HEIGHT +\n SUB_APP_HEADER_HEIGHT +\n PADDING +\n (hasSessionFailureMessage(session) ? FAIL_MESSAGE_CONTAINER_HEIGHT : 0)\n );\n}\n\nfunction getLoadingIndicator(session: Session, isPaused: boolean) {\n if (isPaused) {\n return (\n <Tooltip title=\"Paused\" arrow>\n <PausedProgressIndicator />\n </Tooltip>\n );\n } else if (!session.is_completed) {\n return (\n <Tooltip title=\"Running\" arrow>\n <RunningProgressIndicator />\n </Tooltip>\n );\n } else {\n return <></>;\n }\n}\n\nexport default function SessionDetails() {\n const session = useSelector(getSelectedSession);\n const [paused, setPaused] = useState(session?.is_paused);\n const [isDebugging, setIsDebugging] = useState(false);\n const [isVideoFullscreen, setIsVideFullScreen] = useState(false);\n const [hideSummary, setHideSummary] = useState(false);\n\n const onToggleSummary = useCallback((state) => {\n setHideSummary(state);\n }, []);\n\n const MAIN_CONTENT_CONTAINER_HEIGHT = getSessiobDetailsMainContainerHeight(\n session,\n hideSummary,\n );\n\n const videoHeight = useMemo(() => {\n return isVideoFullscreen && !session?.is_completed\n ? `calc(100vh - ${MAIN_CONTENT_CONTAINER_HEIGHT}px)`\n : `${VIDEO_PLAYER_HEIGHT}px`;\n }, [isVideoFullscreen, session?.session_id]);\n\n const onVideoSizeChanged = useCallback((isFullScreen: boolean) => {\n setIsVideFullScreen(isFullScreen);\n }, []);\n\n useEffect(() => {\n setPaused(!session?.is_completed && session?.is_paused);\n setIsDebugging(false);\n setIsVideFullScreen(isVideoFullscreen && !session?.is_completed);\n }, [session?.session_id, session?.is_completed]);\n\n const onSessionStateChange = (state: boolean) => {\n setPaused(state);\n };\n\n const onDebuggerToggle = (state: boolean) => {\n setIsDebugging(state);\n };\n\n if (!session) {\n return <EmptyMessage>Select a Session</EmptyMessage>;\n }\n\n return (\n <Container>\n <SerialLayout>\n <Row height={`${SUB_APP_HEADER_HEIGHT}px`}>\n <HEADER>\n <ParallelLayout>\n <Column grid={10}>\n <Name>{session.name || session.session_id}</Name>\n </Column>\n <Column grid={2}>\n <SessionMenuItems\n session={session}\n paused={paused}\n debugging={isDebugging}\n onDebuggingToggled={(state) => onDebuggerToggle(state)}\n onStateChanged={(state) => onSessionStateChange(state)}\n />\n </Column>\n </ParallelLayout>\n </HEADER>\n </Row>\n <Row\n height={`${hideSummary ? 0 : SUMMARY_HEIGHT}px`}\n className=\"collapsible-row\"\n >\n <SummaryContainer>\n {!hideSummary && <SessionSummary session={session} />}\n <SummaryCollapseIcon className={hideSummary ? \"down\" : \"up\"}>\n <Icon\n name={hideSummary ? \"chevron-down\" : \"chevron-up\"}\n size={Sizes.XL}\n color=\"#ff4433\"\n tooltip={hideSummary ? \"View Summary\" : \"Hide Summary\"}\n onClick={() => onToggleSummary(!hideSummary)}\n />\n </SummaryCollapseIcon>\n </SummaryContainer>\n </Row>\n {/* Animated indicator of the session status */}\n {(!session.is_completed || session.is_paused) && (\n <Row height=\"4px\">{getLoadingIndicator(session, paused)}</Row>\n )}\n {hasSessionFailureMessage(session) && (\n <Row height={`${FAIL_MESSAGE_CONTAINER_HEIGHT}px`} padding={\"10px\"}>\n <ErrorContainer>{session.session_status_message}</ErrorContainer>\n </Row>\n )}\n <Row height={`calc(100vh - ${MAIN_CONTENT_CONTAINER_HEIGHT}px)`}>\n <ParallelLayout responsiveWidth={RESPONSIVE_WIDTH} responsive>\n <Column grid={4}>\n <SerialLayout\n responsive\n responsiveWidth={RESPONSIVE_WIDTH}\n heightOnResize={videoHeight}\n >\n <Row>\n <SessionVideo\n session={session}\n onVideoSizeChanged={onVideoSizeChanged}\n isFullScreen={isVideoFullscreen}\n height={videoHeight}\n />\n </Row>\n {!isVideoFullscreen ? (\n <Row>\n <SessionCapabilityDetails\n responsiveWidth={RESPONSIVE_WIDTH}\n session={session}\n height={\n MAIN_CONTENT_CONTAINER_HEIGHT + VIDEO_PLAYER_HEIGHT\n }\n />\n </Row>\n ) : null}\n </SerialLayout>\n </Column>\n <Column grid={8}>\n {!!isDebugging ? (\n <SessionScriptExecutor\n session={session}\n parentHeight={MAIN_CONTENT_CONTAINER_HEIGHT}\n />\n ) : (\n <SessionLogs\n session={session}\n parentHeight={MAIN_CONTENT_CONTAINER_HEIGHT}\n />\n )}\n </Column>\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </Container>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Session from \"../../../../interfaces/session\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\nimport Spinner from \"../../atoms/spinner\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport Centered from \"../../molecules/centered\";\nimport { useHistory } from \"react-router-dom\";\nimport { getSessionDetailsUrl } from \"../../../../constants/routes\";\nimport chroma from \"chroma-js\";\nimport { Tooltip } from \"@mui/material\";\n\nconst getStatusIcon = (is_completed: boolean, session_status: string) => {\n if (!is_completed) {\n return <Spinner size=\"M\" />;\n } else if (session_status === \"PASSED\") {\n return <Icon name=\"success\" size={Sizes.XXL} />;\n } else if (session_status === \"TIMEOUT\") {\n return <Icon name=\"exclamation\" size={Sizes.XXL} />;\n } else {\n return <Icon name=\"error\" size={Sizes.XXL} />;\n }\n};\n\nconst getTilte = (session: Session) => {\n if (session.name) {\n return session.name;\n } else {\n let title =\n `${session.platform_name} ${session.platform_version}`.toLowerCase();\n if (session.browser_name) {\n title += `, ${session.browser_name}`;\n }\n return title;\n }\n};\n\nconst Container = styled.div`\n padding: 10px 15px;\n border-bottom: 1px solid\n ${(props) => chroma(props.theme.colors.border).brighten(0.7).hex()};\n cursor: pointer;\n background-color: ${(props) =>\n props.theme.colors.components.session_card_default_bg};\n\n &:hover {\n background-color: ${(props) => props.theme.colors.greyscale[4]};\n }\n\n &.active {\n background-color: ${(props) =>\n props.theme.colors.components.session_card_active_bg};\n }\n`;\n\nconst Name = styled.div`\n font-weight: 400;\n font-size: 13px;\n text-transform: capitalize;\n`;\n\nconst ExecutionTime = styled.div`\n color: ${(props) => props.theme.colors.greyscale[2]};\n`;\n\nconst StausColor = styled.div<{ status: string }>`\n color: ${(props) => {\n switch (props.status) {\n case \"PASSED\":\n return props.theme.colors.success;\n case \"RUNNING\":\n return props.theme.colors.components.session_card_running_status;\n case \"FAILED\":\n case \"TIMEOUT\":\n return props.theme.colors.error;\n }\n }};\n`;\n\nconst StatusIcon = styled(StausColor)``;\n\nconst StatusLabel = styled(StausColor)`\n font-weight: 600;\n font-size: 11px;\n`;\n\nconst TextWithIcon = styled.div`\n font-size: 12px;\n display: flex;\n flex-direction: row;\n align-items: center;\n white-space: nowrap;\n overflow: hidden;\n\n & > span {\n padding-right: 5px;\n }\n`;\n\nconst DeviceName = styled(TextWithIcon)`\n color: ${(props) => props.theme.colors.greyscale[2]};\n font-weight: 500;\n max-width: 120px;\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\ntype PropsType = {\n session: Session;\n selected: boolean;\n};\n\n// function getPlatformIcon(session: Session) {\n// if (session.platform_name.toLowerCase() == \"android\") {\n// return <Icon name=\"android\" size={Sizes.XL} />;\n// } else {\n// return <Icon name=\"ios\" size={Sizes.XL} />;\n// }\n// }\n\nfunction getDuration(startDate: Date) {\n return CommonUtils.convertTimeToReadableFormat(\n new Date(startDate),\n new Date(),\n ).split(\" \")[0];\n}\n\nexport default function SessionCard(props: PropsType) {\n const { session } = props;\n const { session_id, device_name, start_time, session_status, is_completed } =\n session;\n\n const formattedStartTime = getDuration(start_time);\n const history = useHistory();\n\n return (\n <Container\n className={props.selected ? \"active\" : \"\"}\n onClick={() => {\n history.push(getSessionDetailsUrl(session_id));\n }}\n >\n <ParallelLayout>\n <Column grid={11}>\n <SerialLayout>\n <Row padding=\"10px 30px 10px 0\">\n <Name>{getTilte(session)}</Name>\n </Row>\n <Row padding=\"0 0 5px 0\">\n <ParallelLayout>\n <Column grid={3}>\n <StatusLabel status={session_status}>\n {session_status}\n </StatusLabel>\n </Column>\n <Column grid={5}>\n <Tooltip title={device_name} arrow={true}>\n <DeviceName>\n <Icon name=\"mobile\" />\n {device_name}\n </DeviceName>\n </Tooltip>\n </Column>\n <Column grid={4}>\n <ExecutionTime>{formattedStartTime} ago</ExecutionTime>\n </Column>\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </Column>\n <Column grid={1}>\n <Centered>\n <StatusIcon status={session_status}>\n {getStatusIcon(is_completed, session_status)}\n </StatusIcon>\n </Centered>\n </Column>\n </ParallelLayout>\n </Container>\n );\n}\n","export const PLATFORM = [\n {\n label: \"IOS\",\n value: \"ios\",\n },\n {\n label: \"ANDROID\",\n value: \"android\",\n },\n];\n\nexport const PROJECT = [\n {\n label: \"Stage\",\n value: \"Stage\",\n },\n {\n label: \"Production\",\n value: \"Production\",\n },\n]\n\nexport const STATUS = [\n {\n label: \"RUNNING\",\n value: \"running\",\n },\n {\n label: \"PASSED\",\n value: \"passed\",\n },\n {\n label: \"FAILED\",\n value: \"failed\",\n },\n {\n label: \"TIMEOUT\",\n value: \"timeout\",\n },\n];\n\ninterface DeviceFilters {\n ios: {\n [deviceName: string]: string;\n };\n android: {\n [deviceName: string]: string;\n };\n}\n\nexport const DEVICE_FILTERS : DeviceFilters = {\n ios: {\n \"iPhone XS\": \"00008020-000930C10A38002E\",\n \"iPhone X\": \"122e949df238deb70754a5997bfed5c9136c6a47\",\n \"iPhone 12 mini\": \"00008101-00196DD026F0001E\",\n },\n android: {\n \"Samsung Galaxy S10\": \"RF8MC25GVTK\",\n \"Redmi Note 14\": \"q8oz6t7prsvs6le6\",\n },\n};","import { AppState } from \"../..\";\n\n\nexport const getSessionFilterCount = (state: AppState): number => {\n return Object.values(state.ui.sessionFilter.session).filter((d) => !!d && d.length)\n .length;\n};\n\nexport const getSessionFilters = (state: AppState) => state.ui.sessionFilter.session;\n\n\n/**\n *\n * Build filters\n */\nexport const getBuildFilterCount = (state: AppState): number => {\n return Object.values(state.ui.buildFilter.build).filter((d) => !!d && d.length)\n .length;\n};\n\nexport const getBuildFilters = (state : AppState) => state.ui.buildFilter.build;\n\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport ButtonComponent, { ButtonTypeMap } from \"@mui/material/Button\";\nimport chroma from \"chroma-js\";\n\nconst StyledButtonComponent = styled(ButtonComponent)`\n && {\n display: inline-block;\n width: auto;\n padding: ${(props) =>\n props.variant === \"contained\" ? \"3px 15px\" : \"2px 15px\"};\n background-color: ${(props) =>\n props.variant === \"contained\" && props.theme.colors.primary};\n color: ${(props) =>\n (props.variant === \"text\" || props.variant === \"outlined\") &&\n props.theme.colors.primary};\n border-color: ${(props) =>\n props.variant === \"outlined\" && props.theme.colors.primary};\n\n &:hover {\n background-color: ${(props) =>\n props.variant === \"contained\" &&\n chroma(props.theme.colors.primary).brighten(1).hex()};\n border-color: ${(props) =>\n props.variant === \"outlined\" && props.theme.colors.primary};\n }\n }\n`;\n\ntype PropsType = {\n variant?: ButtonTypeMap[\"props\"][\"variant\"];\n onClick?: () => void;\n children: string;\n className?: string;\n};\n\nexport default function Button(props: PropsType) {\n const { variant = \"contained\", onClick, children, className } = props;\n return (\n <StyledButtonComponent\n className={className}\n variant={variant}\n onClick={onClick}\n >\n {children}\n </StyledButtonComponent>\n );\n}\n","import React, { useCallback } from \"react\";\nimport styled from \"styled-components\";\nimport SelectComponent from \"@mui/material/Select\";\nimport MenuItem from \"@mui/material/MenuItem\";\nimport { useMemo } from \"react\";\nimport CommonUtils from \"../../../utils/common-utils\";\nimport _ from \"lodash\";\n\nconst Container = styled.div``;\n\nconst StyledSelect = styled(SelectComponent)`\n width: 100%;\n font-size: 12px !important;\n\n & > .MuiSelect-select {\n padding: 7px 10px;\n }\n\n .MuiMenuItem-root {\n font-size: 12px !important;\n }\n`;\n\ntype Option = {\n label: string;\n value: string;\n};\n\ntype PropsType = {\n options: Array<Option | string>;\n selected?: Option | string | Array<string>;\n onChange?: (e: any) => void;\n multiple?: boolean;\n};\n\nconst getOption = (option: Option | string) => {\n if (typeof option === \"string\") {\n return {\n value: option,\n label: option,\n };\n } else {\n return option;\n }\n};\n\nfunction getValue(isMultiple: boolean, value: any) {\n if (!value) {\n return [];\n }\n if (isMultiple && _.isString(value)) {\n return value.split(\",\");\n } else {\n return value;\n }\n}\n\nexport default function Select(props: PropsType) {\n const { options, selected, onChange, multiple = false } = props;\n const massagedOption = useMemo(\n () => options.map(getOption),\n [CommonUtils.hash(options)],\n );\n\n const onSelectChange = useCallback((e) => {\n onChange && onChange(e.target.value);\n }, []);\n\n return (\n <Container>\n <StyledSelect\n onChange={onSelectChange}\n value={getValue(multiple, selected)}\n multiple={multiple}\n >\n {massagedOption.map((option: Option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </StyledSelect>\n </Container>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { useCallback } from \"react\";\nimport { useEffect } from \"react\";\nimport { useState } from \"react\";\nimport { useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport { DEVICE_FILTERS, PLATFORM, STATUS } from \"../../../../constants/session\";\nimport { getSessionFilters } from \"../../../../store/selectors/ui/filter-selector\";\nimport Button from \"../../atoms/button\";\nimport Input from \"../../atoms/input\";\nimport Select from \"../../atoms/select\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\n\nconst Container = styled.div`\n width: 400px;\n padding: 10px;\n`;\n\nconst Label = styled.div``;\n\nconst Control = styled.div``;\n\nconst Actions = styled.div``;\n\nconst StyledButton = styled(Button)`\n && {\n margin: 0px 10px;\n }\n`;\n\ntype Propstype = {\n platform: \"ios\" | \"android\" | undefined;\n onApply: (payload: any) => void;\n};\n\nexport default function SessionListFilter(props: Propstype) {\n const { onApply,platform } = props;\n const filterState = useSelector(getSessionFilters);\n const [status, setStatus] = useState(filterState.status);\n const [device_udid, setUuid] = useState(filterState.device_udid);\n const [showClearButton, setShowClearButton] = useState(false);\n const [deviceName, setDeviceName] = useState(filterState.deviceName)\n\n // Memoize available devices based on the platform of the selected build\n const deviceNames = useMemo(() => {\n if (platform && DEVICE_FILTERS[platform]) {\n return Object.keys(DEVICE_FILTERS[platform]);\n }\n return [];\n }, [platform]);\n\n const apply = useCallback(() => {\n onApply({\n status: status,\n device_udid,\n deviceName,\n });\n }, [status, device_udid,deviceName]);\n\n const reset = useCallback(() => {\n onApply({\n status: [],\n device_udid: \"\",\n deviceName : \"\"\n });\n }, [ status, device_udid,deviceName]);\n\n useEffect(() => {\n setShowClearButton(\n [ status, device_udid, deviceName].some((val) => !!val));\n }, [status, device_udid, deviceName]);\n\n return (\n <Container>\n <SerialLayout>\n\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>Status:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Select\n multiple={true}\n options={STATUS}\n onChange={(value) => setStatus(value)}\n selected={status}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n\n {/* Device Filter */}\n {platform && deviceNames.length > 0 ? (\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>Device:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Select\n options={deviceNames}\n onChange={(value) => {\n const selectedDeviceUDID =\n DEVICE_FILTERS[platform][value];\n setDeviceName(value);\n setUuid(selectedDeviceUDID); // Update device UDID when a device is selected\n }}\n selected={deviceName}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n ) : platform === undefined ? (\n <Row padding=\"10px 0px\">\n <Label>Select a build first</Label>\n </Row>\n ) : (\n <Row padding=\"10px 0px\">\n <Label>No devices available for this platform</Label>\n </Row>\n )}\n\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>UDID:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Input\n onChange={(e) => setUuid(e.target.value)}\n value={device_udid}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n\n\n <Row align=\"center\" padding=\"20px 0px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Actions>\n <StyledButton onClick={apply}>Apply</StyledButton>\n </Actions>\n </Column>\n {showClearButton ? (\n <Column grid={6}>\n <Actions>\n <StyledButton onClick={reset}>Clear</StyledButton>\n </Actions>\n </Column>\n ) : (\n <></>\n )}\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </Container>\n );\n}\n","import Popover, { PopoverOrigin } from \"@mui/material/Popover\";\nimport React from \"react\";\nimport styled from \"styled-components\";\n\nconst Container = styled.div``;\n\nconst Trigger = styled.div`\n cursor: pointer;\n`;\n\nconst Content = styled.div`\n padding: 10px;\n`;\n\ntype PropsType = {\n children: [JSX.Element, JSX.Element];\n vertical?: PopoverOrigin[\"vertical\"];\n horizontal?: PopoverOrigin[\"horizontal\"];\n id?: string;\n open?: boolean;\n controlled?: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n};\n\nexport default function Dropdown(props: PropsType) {\n const {\n children,\n id = \"simple-popover\",\n vertical = \"bottom\",\n horizontal = \"left\",\n controlled,\n open,\n onOpen,\n onClose,\n } = props;\n const anchorEl = React.useRef(null);\n const [isOpen, setIsOpen] = React.useState(false);\n\n const handleClick = () => {\n setIsOpen(true);\n onOpen && onOpen();\n };\n\n const handleClose = () => {\n setIsOpen(false);\n onClose && onClose();\n };\n\n return (\n <Container>\n <Trigger onClick={handleClick} ref={anchorEl}>\n {children[0]}\n </Trigger>\n <Popover\n id={id}\n open={controlled ? !!open : isOpen}\n anchorEl={anchorEl.current}\n onClose={handleClose}\n anchorOrigin={{\n vertical: vertical,\n horizontal: horizontal,\n }}\n >\n <Content>{children[1]}</Content>\n </Popover>\n </Container>\n );\n}\n","export function extractBuildIdFromUrl(url: string): string | null {\n const matches = url.match(/dashboard\\/builds\\/([a-f0-9\\-]{36})(?:\\/sessions)?/);\n return matches?.[1] || null;\n}\n","import React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport styled from \"styled-components\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n getIsSessionsLoading,\n getSelectedSession,\n getSessions,\n} from \"../../../../store/selectors/entities/sessions-selector\";\nimport {\n fetchSessionByBuildId,\n setSessionFilter,\n} from \"../../../../store/actions/session-actions\";\nimport SessionCard from \"./session-card\";\nimport SessionListFilter from \"./session-list-filter\";\nimport Spinner from \"../../atoms/spinner\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport Dropdown from \"../../atoms/dropdown\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport { extractBuildIdFromUrl } from \"../../../../utils/utility\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport { Badge } from \"@material-ui/core\";\nimport { getSessionFilterCount } from \"../../../../store/selectors/ui/filter-selector\";\nimport {\n APP_HEADER_HEIGHT,\n SUB_APP_HEADER_HEIGHT,\n} from \"../../../../constants/ui\";\nimport Utils from \"../../../../utils/common-utils\";\nimport Session from \"../../../../interfaces/session\";\n\nconst Container = styled.div`\n border-right: 1px solid ${(props) => props.theme.colors.border};\n width: 100%;\n`;\n\nconst List = styled.div``;\n\nconst Header = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 7px 5px;\n`;\n\nconst FilterTrigger = styled.div`\n padding: 10px;\n`;\n\nconst FilterTriggerLabel = styled.div`\n display: inline-block;\n font-size: 13px;\n padding-left: 4px;\n`;\n\nconst FilterDropdown = styled.div``;\n\nconst StyledBadge = styled(Badge)`\n position: relative;\n left: 17px;\n top: -2px;\n`;\n\nfunction getFiltersFromQueryParams(searchQuery: string) {\n const urlParams = new URLSearchParams(searchQuery);\n\n const allowedFilters: any = {\n name: \"\",\n os: {\n valid: [\"ios\", \"android\"],\n },\n status: {\n valid: [\"running\", \"failed\", \"passed\", \"timeout\"],\n },\n device_udid: \"\",\n start_time: {\n valid: (dateString: string) => {\n return !isNaN(new Date(dateString).getDate());\n },\n },\n };\n\n return Utils.parseJsonSchema(\n allowedFilters,\n Utils.urlParamsToObject(urlParams),\n );\n}\n\nexport default function SessionList() {\n const dispatch = useDispatch();\n const sessions = useSelector(getSessions);\n const isLoading = useSelector(getIsSessionsLoading);\n const selectedSession = useSelector(getSelectedSession);\n const urlFilters = getFiltersFromQueryParams(window.location.search);\n\n const [isFilterOpen, setIsFilterOpen] = useState(false);\n const filterCount = useSelector(getSessionFilterCount);\n const [effectiveBuildId, setEffectiveBuildId] = useState<string | undefined>();\n\n const rawBuildId = extractBuildIdFromUrl(location.pathname);\n\n const stableUrlFilters = useMemo(() => {\n return getFiltersFromQueryParams(window.location.search);\n }, [window.location.search]);\n\n // 1. Set buildId from URL if available\n useEffect(() => {\n if (rawBuildId) {\n setEffectiveBuildId(rawBuildId);\n }\n }, [rawBuildId]);\n\n // 2. Fallback to the selected session's buildId if on a session URL\n useEffect(() => {\n if (!rawBuildId && selectedSession?.build_id) {\n setEffectiveBuildId(selectedSession.build_id);\n }\n }, [rawBuildId, selectedSession]);\n\n\n // 3. Fetch sessions once effectiveBuildId is known\n useEffect(() => {\n if (!effectiveBuildId) return;\n\n if (Object.keys(stableUrlFilters).length > 0) {\n dispatch(fetchSessionByBuildId({ buildId: effectiveBuildId, ...stableUrlFilters }));\n dispatch(setSessionFilter({ buildId: effectiveBuildId, ...stableUrlFilters }));\n } else {\n dispatch(fetchSessionByBuildId(effectiveBuildId));\n }\n }, [effectiveBuildId, stableUrlFilters, dispatch]);\n\n // 4. When filters are applied from UI\n const setFilter = useCallback((payload) => {\n if (!effectiveBuildId) return;\n\n const finalPayload = {\n ...payload,\n buildId: effectiveBuildId,\n };\n\n console.log(\"fetching sessions from 4\", effectiveBuildId);\n dispatch(setSessionFilter(finalPayload));\n dispatch(fetchSessionByBuildId(finalPayload));\n }, [effectiveBuildId, dispatch]);\n\n // 5. Manually filter only sessions for the current build\n const filteredSessions = sessions.filter(\n (session: Session) => session.build_id === effectiveBuildId,\n );\n\n return (\n <Container>\n <SerialLayout>\n <Row height={`${SUB_APP_HEADER_HEIGHT}px`}>\n <Header>\n <ParallelLayout>\n <Column grid={10}>\n <Dropdown\n controlled\n onOpen={() => setIsFilterOpen(true)}\n onClose={() => setIsFilterOpen(false)}\n open={isFilterOpen}\n >\n <FilterTrigger>\n <Icon name=\"filter\" size={Sizes.S} />\n <FilterTriggerLabel>FILTERS</FilterTriggerLabel>\n <StyledBadge badgeContent={filterCount} color=\"secondary\" />\n </FilterTrigger>\n <FilterDropdown>\n <SessionListFilter\n platform={filteredSessions[0]?.platform_name?.toLowerCase()}\n onApply={(payload) => {\n setFilter(payload);\n setIsFilterOpen(false);\n }}\n />\n </FilterDropdown>\n </Dropdown>\n </Column>\n {isLoading ? (\n <Column grid={2}>\n <Spinner />\n </Column>\n ) : null}\n </ParallelLayout>\n </Header>\n </Row>\n <Row\n height={`calc(100vh - ${SUB_APP_HEADER_HEIGHT + APP_HEADER_HEIGHT}px)`}\n scrollable\n >\n <List>\n {filteredSessions.length > 0 ? (\n filteredSessions.map((session: Session) => (\n <SessionCard\n key={session.session_id}\n selected={selectedSession?.session_id === session.session_id}\n session={session}\n />\n ))\n ) : (\n <EmptyMessage>No sessions found for given filter.</EmptyMessage>\n )}\n </List>\n </Row>\n </SerialLayout>\n </Container>\n );\n}","import { AppState } from \"../..\";\n\nexport const getBuilds = (state: AppState) => state.entities.builds.items;\n\nexport const getIsBuildsLoading = (state: AppState) =>\n state.entities.builds.isLoading;\n\nexport const getSelectedBuild = (state: AppState) =>\n state.ui.selected.build;","import React from \"react\";\nimport styled from \"styled-components\";\nimport chroma from \"chroma-js\";\nimport { Tooltip } from \"@mui/material\";\nimport Spinner from \"../../atoms/spinner\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\nimport Build from \"../../../../interfaces/build\";\nimport CommonUtils from \"../../../../utils/common-utils\";\nimport { useHistory } from \"react-router-dom\";\nimport {\n getBuildDetailsUrl,\n} from \"../../../../constants/routes\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport Centered from \"../../molecules/centered\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n fetchSessionByBuildId,\n} from \"../../../../store/actions/session-actions\";\n\nconst getBuildStatusIcon = (build: Build) => {\n const { session } = build;\n\n if (session.running > 0 ) {\n return <Spinner size=\"M\" />;\n } else if (session.failed > 0) {\n return <Icon name=\"error\" size={Sizes.XL} color=\"red\" />;\n } else if (session.timeout > 0 ) {\n return <Icon name=\"exclamation\" size={Sizes.XL} color=\"red\" />;\n } else {\n return <Icon name=\"success\" size={Sizes.XL} color=\"green\" />;\n }\n};\n\nconst Container = styled.div`\n padding: 10px 15px;\n border-bottom: 1px solid\n ${(props) => chroma(props.theme.colors.border).brighten(0.7).hex()};\n cursor: pointer;\n background-color: ${(props) =>\n props.theme.colors.components.session_card_default_bg};\n\n &:hover {\n background-color: ${(props) => props.theme.colors.greyscale[4]};\n }\n\n &.active {\n background-color: ${(props) =>\n props.theme.colors.components.session_card_active_bg};\n }\n`;\n\nconst TextWithIcon = styled.div`\n font-size: 12px;\n display: flex;\n flex-direction: row;\n align-items: center;\n white-space: nowrap;\n overflow: hidden;\n\n & > span {\n padding-right: 5px;\n }\n`;\n\nconst DeviceName = styled(TextWithIcon)`\n color: ${(props) => props.theme.colors.greyscale[2]};\n font-weight: 400;\n max-width: 120px;\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nconst Name = styled.div`\n font-weight: 400;\n font-size: 11px;\n text-transform: capitalize;\n`;\n\nconst ExecutionTime = styled.div`\n color: ${(props) => props.theme.colors.greyscale[2]};\n`;\n\ntype PropsType = {\n build: Build;\n selected: boolean;\n};\n\nfunction getDuration(startDate: Date) {\n return CommonUtils.convertTimeToReadableFormat(\n new Date(startDate),\n new Date(),\n ).split(\" \")[0];\n}\n\nexport default function BuildCard(props: PropsType) {\n const { build , selected } = props;\n const { build_id, build_name , created_at, session, platform_name } = build;\n const dispatch = useDispatch();\n const formattedStartTime = getDuration(created_at);\n const history = useHistory();\n\n return (\n <Container\n className={selected ? \"active\" : \"\"}\n onClick={() => {\n history.push(getBuildDetailsUrl(build_id));\n dispatch(fetchSessionByBuildId(build_id));\n }}\n >\n <ParallelLayout>\n <Column grid={9}>\n <SerialLayout>\n <Row padding=\"10px 30px 10px 0\">\n <Name>{build_name}</Name>\n </Row>\n\n <Row padding=\"0 0 5px 0\">\n <ParallelLayout>\n\n <Column grid={4}>\n <ExecutionTime>{formattedStartTime} ago</ExecutionTime>\n </Column>\n\n <Column grid={4}>\n <Tooltip title=\"the test platform\" arrow={true}>\n <DeviceName>\n <Icon name={platform_name.toLowerCase()} />\n {platform_name}\n </DeviceName>\n </Tooltip>\n </Column>\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </Column>\n\n <Column grid={3}>\n <Centered>\n <ParallelLayout>\n <div style={ {paddingRight : '5px'}}>{session.total} tests</div>\n <div>{getBuildStatusIcon(build)}</div>\n </ParallelLayout>\n </Centered>\n </Column>\n\n </ParallelLayout>\n <Column grid={12}>\n <span>By <strong>{build.user}</strong></span>\n </Column>\n </Container>\n );\n}\n","export const PLATFORM = [\n {\n label: \"IOS\",\n value: \"ios\",\n },\n {\n label: \"ANDROID\",\n value: \"android\",\n },\n];\n\nexport const PROJECT = [\n {\n label: \"Stage\",\n value: \"Stage\",\n },\n {\n label: \"Production\",\n value: \"Production\",\n },\n]\n\nexport const USER = [\n {\n label: \"anass.arakia@tractive.com\",\n value: \"anass.arakia@tractive.com\",\n },\n {\n label: \"Jenkins\",\n value: \"jenkins\",\n },\n]","import { useSelector } from \"react-redux\";\nimport {\n getBuildFilters,\n} from \"../../../../store/selectors/ui/filter-selector\";\nimport React, { useCallback, useEffect, useState } from \"react\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Select from \"../../atoms/select\";\nimport { PLATFORM, PROJECT, USER } from \"../../../../constants/build-filter-options\";\nimport styled from \"styled-components\";\nimport Button from \"../../atoms/button\";\n\nconst Container = styled.div`\n width: 400px;\n padding: 10px;\n`;\n\nconst Label = styled.div``;\n\nconst Control = styled.div``;\n\nconst Actions = styled.div``;\n\nconst StyledButton = styled(Button)`\n && {\n margin: 0px 10px;\n }\n`;\n\ntype Propstype = {\n onApply: (payload: any) => void;\n};\n\nexport default function BuildListFilter(props: Propstype) {\n const { onApply } = props;\n\n const filterState = useSelector(getBuildFilters);\n const [user,setUser] = useState(filterState.user);\n const [project,setProject] = useState(filterState.project);\n const [platformName,setPlatformName] = useState(filterState.platform_name);\n const [showClearButton, setShowClearButton] = useState(false);\n\n const apply = useCallback(() => {\n onApply({\n user,\n project,\n platformName\n });\n }, [user, project, platformName]);\n\n const reset = useCallback(() => {\n onApply({\n user,\n project,\n platformName\n });\n }, [user, project, platformName]);\n\n useEffect(() => {\n setShowClearButton(\n [user, project, platformName].some((val) => !!val));\n }, [user, project, platformName]);\n\n return (\n <Container>\n <SerialLayout>\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>Platform:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Select\n multiple={true}\n options={PLATFORM}\n onChange={(value) => setPlatformName(value)}\n selected={platformName}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>Project:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Select\n multiple={true}\n options={PROJECT}\n onChange={(value) => setProject(value)}\n selected={project}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n\n <Row padding=\"10px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Label>User:</Label>\n </Column>\n <Column grid={6}>\n <Control>\n <Select\n multiple={false}\n options={USER}\n onChange={(value) => setUser(value)}\n selected={user}\n />\n </Control>\n </Column>\n </ParallelLayout>\n </Row>\n\n <Row align=\"center\" padding=\"20px 0px 0px\">\n <ParallelLayout>\n <Column grid={6}>\n <Actions>\n <StyledButton onClick={apply}>Apply</StyledButton>\n </Actions>\n </Column>\n {showClearButton ? (\n <Column grid={6}>\n <Actions>\n <StyledButton onClick={reset}>Clear</StyledButton>\n </Actions>\n </Column>\n ) : (\n <></>\n )}\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </Container>\n );\n\n\n}","import React, { useState } from \"react\";\nimport styled from \"styled-components\";\nimport EmptyMessage from \"../../molecules/empty-message\";\nimport SerialLayout, { Row } from \"../../layouts/serial-layout\";\nimport { useDispatch, useSelector } from \"react-redux\";\n\nimport { useCallback } from \"react\";\nimport { useEffect } from \"react\";\nimport {\n APP_HEADER_HEIGHT,\n SUB_APP_HEADER_HEIGHT,\n} from \"../../../../constants/ui\";\nimport { getHeaderStyle } from \"../../../../utils/ui\";\nimport Utils from \"../../../../utils/common-utils\";\nimport {\n addPollingTask,\n removePollingTask,\n} from \"../../../../store/actions/polling-actions\";\nimport {\n getBuilds, getSelectedBuild\n} from \"../../../../store/selectors/entities/builds-selector\";\nimport {\n fetchBuildInit,\n setBuildFilter\n} from \"../../../../store/actions/build-actions\";\nimport Build from \"../../../../interfaces/build\";\nimport BuildCard from \"./build-card\";\nimport ParallelLayout, { Column } from \"../../layouts/parallel-layout\";\nimport Dropdown from \"../../atoms/dropdown\";\nimport Icon, { Sizes } from \"../../atoms/icon\";\nimport Spinner from \"../../atoms/spinner\";\nimport {\n getBuildFilterCount\n} from \"../../../../store/selectors/ui/filter-selector\";\nimport { Badge } from \"@material-ui/core\";\nimport {\n getIsSessionsLoading\n} from \"../../../../store/selectors/entities/sessions-selector\";\nimport BuildListFilter from \"./build-list-filter\";\n\nconst Container = styled.div`\n border-right: 1px solid ${(props) => props.theme.colors.border};\n width: 100%;\n`;\n\nconst List = styled.div``;\n\nconst Header = styled.div`\n ${(props) => getHeaderStyle(props.theme)};\n padding: 7px 5px;\n`;\n\nconst FilterTrigger = styled.div`\n padding: 10px;\n`;\n\nconst FilterTriggerLabel = styled.div`\n display: inline-block;\n font-size: 13px;\n padding-left: 4px;\n`;\n\nconst FilterDropdown = styled.div``;\n\nconst StyledBadge = styled(Badge)`\n positive: relative;\n left: 17px;\n top: -2px;\n`;\n\nfunction getFiltersFromQueryParams(searchQuery: string) {\n const urlParams = new URLSearchParams(searchQuery);\n\n const allowedFilters: any = {\n name: \"\",\n os: {\n valid: [\"ios\", \"android\"],\n },\n status: {\n valid: [\"running\", \"failed\", \"passed\", \"timeout\"],\n },\n device_udid: \"\",\n start_time: {\n valid: (dateString: string) => {\n return !isNaN(new Date(dateString).getDate());\n },\n },\n };\n\n return Utils.parseJsonSchema(\n allowedFilters,\n Utils.urlParamsToObject(urlParams),\n );\n}\n\nexport default function BuildList() {\n const dispatch = useDispatch();\n const builds = useSelector(getBuilds);\n const urlFilters = getFiltersFromQueryParams(window.location.search);\n const selectedBuild = useSelector(getSelectedBuild);\n\n\n useEffect(() => {\n if (Object.keys(urlFilters).length) {\n setFilter(urlFilters);\n } else {\n dispatch(fetchBuildInit());\n }\n }, []);\n\n\n\n useEffect(() => {\n if (!selectedBuild) {\n dispatch(fetchBuildInit());\n }\n }, [selectedBuild]);\n\n\n /** Add polling for builds **/\n useEffect(() => {\n dispatch(addPollingTask(fetchBuildInit()));\n\n return () => {\n dispatch(removePollingTask(fetchBuildInit()));\n };\n }, []);\n\n /**\n * Filters\n */\n const isLoading = useSelector(getIsSessionsLoading);\n const [isFilterOpen, setIsFilterOpen] = useState(false);\n const filterCount = useSelector(getBuildFilterCount);\n\n const setFilter = useCallback((payload) => {\n dispatch(setBuildFilter(payload));\n\n /* Reset filters polling with newly applied filters */\n dispatch(removePollingTask(fetchBuildInit()));\n dispatch(addPollingTask(fetchBuildInit(payload)));\n }, []);\n\n return (\n <Container>\n <SerialLayout>\n <Row height={`${SUB_APP_HEADER_HEIGHT}px`}>\n <Header>\n <ParallelLayout>\n <Column grid={10}>\n <Dropdown\n controlled\n onOpen={() => setIsFilterOpen(true)}\n onClose={() => setIsFilterOpen(false)}\n open={isFilterOpen}\n >\n <FilterTrigger>\n <Icon name=\"filter\" size={Sizes.S} />\n <FilterTriggerLabel>FILTERS</FilterTriggerLabel>\n <StyledBadge badgeContent={filterCount} color=\"secondary\" />\n </FilterTrigger>\n <FilterDropdown>\n <BuildListFilter\n onApply={(payload) => {\n setFilter(payload);\n setIsFilterOpen(false);\n }}\n />\n </FilterDropdown>\n </Dropdown>\n </Column>\n {isLoading ? (\n <Column grid={2}>\n <Spinner />\n </Column>\n ) : null}\n </ParallelLayout>\n </Header>\n </Row>\n <Row\n height={`calc(100vh - ${\n SUB_APP_HEADER_HEIGHT + APP_HEADER_HEIGHT\n }px)`}\n scrollable\n >\n <List>\n {builds.length > 0 ? (\n <>\n {builds.map((build: Build) => (\n <BuildCard\n key = {build.build_id}\n build={build}\n selected={ selectedBuild?.build_id === build.build_id\n }/>\n ))}\n </>\n ) : (\n <EmptyMessage>No Builds found for given filter.</EmptyMessage>\n )}\n </List>\n </Row>\n </SerialLayout>\n </Container>\n );\n}\n","import React from \"react\";\nimport { NavLink } from \"react-router-dom\";\nimport './header.css';\nimport DeviceFarmLogo from '../../../../assets/logo-tractive-white.png';\nimport { BASE_URL, METRICS_URL } from \"../../../../constants/routes\";\n\nexport const Header = () => {\n\n return(\n <div className=\"header-container\">\n <div className=\"header-logo-container\">\n <img src={DeviceFarmLogo} alt=\"Tractive Appium Dashboard\" className=\"header-logo-image\" />\n <div className=\"header-logo\">Tractive Appium Dashboard</div>\n </div>\n <nav className=\"header-nav\">\n <NavLink\n exact\n to={BASE_URL || \"/\"}\n className=\"header-nav-link\"\n activeClassName=\"header-nav-link--active\"\n isActive={(match, location) =>\n !!match || !location.pathname.startsWith(METRICS_URL)\n }\n >\n Dashboard\n </NavLink>\n <NavLink\n to={METRICS_URL}\n className=\"header-nav-link\"\n activeClassName=\"header-nav-link--active\"\n >\n Metrics\n </NavLink>\n </nav>\n </div>\n )\n}","export default \"data:image/png;base64,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\"","import React from \"react\";\nimport { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n Route,\n Router,\n Switch,\n useHistory,\n useLocation,\n} from \"react-router-dom\";\nimport {\n getBuildDetailsUrl,\n getSessionDetailsUrl\n} from \"../../constants/routes\";\nimport { APP_HEADER_HEIGHT } from \"../../constants/ui\";\nimport {\n fetchSessionInit,\n setSelectedSession\n} from \"../../store/actions/session-actions\";\nimport { getSessions } from \"../../store/selectors/entities/sessions-selector\";\nimport ParallelLayout, { Column } from \"../UI/layouts/parallel-layout\";\nimport SerialLayout, { Row } from \"../UI/layouts/serial-layout\";\nimport AppHeader from \"../UI/organisms/app-header\";\nimport SessionDetails from \"../UI/organisms/session/session-details\";\nimport SessionList from \"../UI/organisms/session/session-list\";\nimport BuildList from \"../UI/organisms/build/build-list\";\nimport { getBuilds } from \"../../store/selectors/entities/builds-selector\";\nimport { setSelectedBuild } from \"../../store/actions/build-actions\";\nimport { extractBuildIdFromUrl } from \"../../utils/utility\";\nimport { RootState } from \"../../store\";\nimport Session from \"../../interfaces/session\";\nimport { Header } from \"../UI/organisms/header/header\";\n\nfunction extractSessionidFromUrl(url: string): string | null {\n const matches = url.match(new RegExp(/dashboard\\/session\\/(.*)/));\n return matches?.length ? matches[1] : null;\n}\n\nexport default function DashboardTemplate() {\n const history = useHistory();\n const dispatch = useDispatch();\n const location = useLocation();\n const sessions = useSelector(getSessions);\n const session_id = extractSessionidFromUrl(location.pathname);\n\n const builds = useSelector(getBuilds);\n const buildIdFromUrl = extractBuildIdFromUrl(location.pathname);\n\n useEffect(() => {\n if (!session_id) return;\n\n const matchedSession = sessions.find((s) => s.session_id === session_id);\n\n if (matchedSession) {\n dispatch(setSelectedSession(matchedSession));\n } else {\n // Session isn't loaded yet — fetch it by ID\n dispatch(fetchSessionInit(session_id));\n }\n }, [session_id, sessions]);\n\n //session now exists\n const selectedSession = useSelector((state:RootState) =>\n state.entities.sessions.items.find((s:Session) => s.session_id === session_id)\n );\n\n useEffect(() => {\n if (selectedSession) {\n dispatch(setSelectedSession(selectedSession));\n\n if (selectedSession.build_id) {\n const matchingBuild = builds.find(\n (b) => b.build_id === selectedSession.build_id\n );\n\n if (matchingBuild) {\n dispatch(setSelectedBuild(matchingBuild));\n } else {\n // Optional: trigger fetch build by ID if needed\n // dispatch(fetchBuildInit(selectedSession.build_id));\n }\n }\n }\n }, [selectedSession, builds]);\n\n\n useEffect(() => {\n // Only update builds selection if we are on a build page\n if (!location.pathname.includes(\"/session/\")) {\n const selectedBuild = !!buildIdFromUrl\n ? builds.find((d) => d.build_id === buildIdFromUrl) || builds[0]\n : builds[0];\n\n if (selectedBuild) {\n const sessionsUrl = getBuildDetailsUrl(selectedBuild.build_id);\n\n if (\n buildIdFromUrl &&\n (buildIdFromUrl !== selectedBuild.build_id ||\n !location.pathname.includes(\"/sessions\"))\n ) {\n // Always redirect to /builds/:id/sessions explicitly\n history.push(sessionsUrl);\n }\n\n dispatch(setSelectedBuild(selectedBuild));\n }\n }\n }, [buildIdFromUrl, builds, location.pathname]);\n\n return (\n <>\n <SerialLayout>\n <Row height={`${APP_HEADER_HEIGHT}px`}>\n <Header/>\n </Row>\n <Row height={`calc(100vh - ${APP_HEADER_HEIGHT}px)`}>\n <ParallelLayout>\n {/** Build List View **/}\n <Column grid={2.5}>\n <BuildList />\n </Column>\n {/** End Build List View **/}\n\n\n {/** Sessions List View **/}\n <Column grid={2.5}>\n <SessionList />\n </Column>\n {/** End Session List View **/}\n\n\n {/** Session Details View **/}\n <Column grid={7.5}>\n <Router history={history}>\n <Switch>\n <Route>\n <SessionDetails />\n </Route>\n </Switch>\n </Router>\n </Column>\n {/** End Session Details View **/}\n\n\n </ParallelLayout>\n </Row>\n </SerialLayout>\n </>\n );\n}\n","import React from \"react\";\nimport DashboardTemplate from \"../templates/dashboard-template\";\n\nexport default function Dashboard() {\n return <DashboardTemplate />;\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { MetricsFilter } from \"../../../../interfaces/metrics\";\n\nconst Bar = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 20px;\n flex-wrap: wrap;\n`;\n\nconst Label = styled.span`\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: #8892a8;\n margin-right: 4px;\n`;\n\nconst Group = styled.div`\n display: inline-flex;\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 8px;\n overflow: hidden;\n`;\n\nconst Chip = styled.button<{ active?: boolean }>`\n background: ${(p) => (p.active ? \"rgba(91, 127, 255, 0.2)\" : \"transparent\")};\n color: ${(p) => (p.active ? \"#dde1ef\" : \"#8892a8\")};\n border: none;\n padding: 7px 14px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s, color 0.15s;\n\n &:hover {\n color: #dde1ef;\n background: rgba(91, 127, 255, 0.1);\n }\n\n & + & {\n border-left: 1px solid #1f2235;\n }\n`;\n\nconst Input = styled.input`\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 8px;\n padding: 7px 12px;\n font-size: 12px;\n color: #dde1ef;\n outline: none;\n min-width: 140px;\n\n &::placeholder {\n color: #4a5068;\n }\n\n &:focus {\n border-color: #5b7fff;\n }\n`;\n\ntype Props = {\n filter: MetricsFilter;\n onChange: (patch: Partial<MetricsFilter>) => void;\n};\n\nconst RANGES: { label: string; days: number }[] = [\n { label: \"24h\", days: 1 },\n { label: \"7d\", days: 7 },\n { label: \"30d\", days: 30 },\n { label: \"90d\", days: 90 },\n];\n\nconst PLATFORMS = [\"ANDROID\", \"IOS\"];\n\nexport default function MetricsFiltersBar({ filter, onChange }: Props) {\n const platformSet = new Set(\n (filter.platform || \"\").split(\",\").filter(Boolean)\n );\n\n const togglePlatform = (p: string) => {\n if (platformSet.has(p)) platformSet.delete(p);\n else platformSet.add(p);\n const next = Array.from(platformSet).join(\",\");\n onChange({ platform: next || undefined });\n };\n\n return (\n <Bar>\n <Label>Range</Label>\n <Group>\n {RANGES.map((r) => (\n <Chip\n key={r.days}\n active={filter.days === r.days}\n onClick={() => onChange({ days: r.days })}\n >\n {r.label}\n </Chip>\n ))}\n </Group>\n\n <Label>Platform</Label>\n <Group>\n {PLATFORMS.map((p) => (\n <Chip\n key={p}\n active={platformSet.has(p)}\n onClick={() => togglePlatform(p)}\n >\n {p}\n </Chip>\n ))}\n </Group>\n\n <Input\n placeholder=\"App version\"\n value={filter.app_version || \"\"}\n onChange={(e) =>\n onChange({ app_version: e.target.value || undefined })\n }\n />\n <Input\n placeholder=\"User\"\n value={filter.user || \"\"}\n onChange={(e) => onChange({ user: e.target.value || undefined })}\n />\n </Bar>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport { MetricsKpis } from \"../../../../interfaces/metrics\";\n\nconst Grid = styled.div`\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n`;\n\nconst Card = styled.div`\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 10px;\n padding: 16px 18px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n`;\n\nconst Label = styled.div`\n font-size: 11px;\n color: #8892a8;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 500;\n`;\n\nconst Value = styled.div<{ accent?: string }>`\n font-size: 24px;\n font-weight: 600;\n color: ${(p) => p.accent || \"#dde1ef\"};\n`;\n\nconst Sub = styled.div`\n font-size: 11px;\n color: #8892a8;\n`;\n\nfunction fmtDuration(seconds: number): string {\n if (!seconds || seconds < 0) return \"—\";\n if (seconds < 60) return `${seconds.toFixed(0)}s`;\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}m ${s}s`;\n}\n\nexport default function MetricsKpiRow({ kpis }: { kpis: MetricsKpis }) {\n const passColor = kpis.pass_rate >= 90 ? \"#2dd975\" : kpis.pass_rate >= 70 ? \"#e8c14a\" : \"#f45858\";\n return (\n <Grid>\n <Card>\n <Label>Total sessions</Label>\n <Value>{kpis.total.toLocaleString()}</Value>\n <Sub>\n {kpis.passed} passed · {kpis.failed} failed\n {kpis.timeout ? ` · ${kpis.timeout} timeout` : \"\"}\n {kpis.running ? ` · ${kpis.running} running` : \"\"}\n </Sub>\n </Card>\n <Card>\n <Label>Pass rate</Label>\n <Value accent={passColor}>{kpis.pass_rate.toFixed(1)}%</Value>\n <Sub>of completed sessions</Sub>\n </Card>\n <Card>\n <Label>Avg duration</Label>\n <Value>{fmtDuration(kpis.avg_duration_sec)}</Value>\n <Sub>per session</Sub>\n </Card>\n <Card>\n <Label>Flaky tests</Label>\n <Value accent={kpis.flaky_rate > 5 ? \"#e8c14a\" : \"#dde1ef\"}>\n {kpis.flaky_tests}\n </Value>\n <Sub>{kpis.flaky_rate.toFixed(1)}% of named tests</Sub>\n </Card>\n <Card>\n <Label>Builds</Label>\n <Value>{kpis.unique_builds}</Value>\n <Sub>tested in window</Sub>\n </Card>\n <Card>\n <Label>App versions</Label>\n <Value>{kpis.unique_app_versions}</Value>\n <Sub>distinct</Sub>\n </Card>\n </Grid>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport {\n Chart as ChartJS,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n BarElement,\n Title,\n Tooltip,\n Legend,\n Filler,\n} from \"chart.js\";\nimport { Bar, Line } from \"react-chartjs-2\";\nimport { MetricsTrendPoint } from \"../../../../interfaces/metrics\";\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n BarElement,\n Title,\n Tooltip,\n Legend,\n Filler\n);\n\nconst Card = styled.div`\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 10px;\n padding: 18px 20px;\n`;\n\nconst Title2 = styled.div`\n font-size: 13px;\n font-weight: 600;\n color: #dde1ef;\n margin-bottom: 16px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n`;\n\nconst ChartBox = styled.div`\n height: 240px;\n`;\n\nconst baseOptions: any = {\n responsive: true,\n maintainAspectRatio: false,\n interaction: { mode: \"index\", intersect: false },\n plugins: {\n legend: {\n position: \"top\",\n labels: { color: \"#8892a8\", usePointStyle: true, boxWidth: 8 },\n },\n tooltip: {\n backgroundColor: \"rgba(12, 13, 18, 0.95)\",\n borderColor: \"#1f2235\",\n borderWidth: 1,\n titleColor: \"#dde1ef\",\n bodyColor: \"#dde1ef\",\n },\n },\n scales: {\n x: {\n ticks: { color: \"#8892a8\", maxRotation: 0, autoSkip: true },\n grid: { color: \"rgba(31, 34, 53, 0.5)\" },\n },\n y: {\n ticks: { color: \"#8892a8\" },\n grid: { color: \"rgba(31, 34, 53, 0.5)\" },\n beginAtZero: true,\n },\n },\n};\n\nexport function PassFailTrend({ trend }: { trend: MetricsTrendPoint[] }) {\n const data = {\n labels: trend.map((d) => d.day.slice(5)),\n datasets: [\n {\n label: \"Passed\",\n data: trend.map((d) => d.passed),\n backgroundColor: \"#2dd975\",\n stack: \"s\",\n },\n {\n label: \"Failed\",\n data: trend.map((d) => d.failed),\n backgroundColor: \"#f45858\",\n stack: \"s\",\n },\n {\n label: \"Timeout\",\n data: trend.map((d) => d.timeout),\n backgroundColor: \"#e8c14a\",\n stack: \"s\",\n },\n ],\n };\n const options = {\n ...baseOptions,\n scales: {\n x: { ...baseOptions.scales.x, stacked: true },\n y: { ...baseOptions.scales.y, stacked: true },\n },\n };\n return (\n <Card>\n <Title2>Sessions per day</Title2>\n <ChartBox>\n <Bar data={data} options={options} />\n </ChartBox>\n </Card>\n );\n}\n\nexport function DurationTrend({ trend }: { trend: MetricsTrendPoint[] }) {\n const data = {\n labels: trend.map((d) => d.day.slice(5)),\n datasets: [\n {\n label: \"Avg duration (s)\",\n data: trend.map((d) => d.avg_duration_sec),\n borderColor: \"#5b7fff\",\n backgroundColor: \"rgba(91, 127, 255, 0.15)\",\n fill: true,\n tension: 0.3,\n pointRadius: 2,\n },\n ],\n };\n return (\n <Card>\n <Title2>Average session duration</Title2>\n <ChartBox>\n <Line data={data} options={baseOptions} />\n </ChartBox>\n </Card>\n );\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport {\n Chart as ChartJS,\n ArcElement,\n Tooltip,\n Legend,\n} from \"chart.js\";\nimport { Doughnut } from \"react-chartjs-2\";\nimport { MetricsPlatformSplit } from \"../../../../interfaces/metrics\";\n\nChartJS.register(ArcElement, Tooltip, Legend);\n\nconst Card = styled.div`\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 10px;\n padding: 18px 20px;\n display: flex;\n flex-direction: column;\n`;\n\nconst Title = styled.div`\n font-size: 13px;\n font-weight: 600;\n color: #dde1ef;\n margin-bottom: 16px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n`;\n\nconst Body = styled.div`\n display: grid;\n grid-template-columns: 180px 1fr;\n gap: 24px;\n align-items: center;\n`;\n\nconst ChartBox = styled.div`\n width: 180px;\n height: 180px;\n`;\n\nconst Stats = styled.div`\n display: flex;\n flex-direction: column;\n gap: 10px;\n`;\n\nconst Row = styled.div`\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: #dde1ef;\n padding-bottom: 8px;\n border-bottom: 1px solid #1f2235;\n &:last-child {\n border-bottom: none;\n }\n`;\n\nconst Dot = styled.span<{ color: string }>`\n display: inline-block;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: ${(p) => p.color};\n margin-right: 8px;\n`;\n\nconst COLORS = [\"#5b7fff\", \"#2dd975\", \"#e8c14a\", \"#f45858\", \"#a06bff\"];\n\nexport default function MetricsPlatformSplitView({\n data,\n}: {\n data: MetricsPlatformSplit[];\n}) {\n if (!data.length) {\n return (\n <Card>\n <Title>Platform split</Title>\n <div style={{ color: \"#8892a8\", fontSize: 12 }}>No data</div>\n </Card>\n );\n }\n\n const chartData = {\n labels: data.map((d) => d.platform),\n datasets: [\n {\n data: data.map((d) => d.total),\n backgroundColor: data.map((_, i) => COLORS[i % COLORS.length]),\n borderColor: \"#0c0d12\",\n borderWidth: 2,\n },\n ],\n };\n const options: any = {\n responsive: true,\n maintainAspectRatio: false,\n cutout: \"65%\",\n plugins: {\n legend: { display: false },\n tooltip: {\n backgroundColor: \"rgba(12, 13, 18, 0.95)\",\n borderColor: \"#1f2235\",\n borderWidth: 1,\n titleColor: \"#dde1ef\",\n bodyColor: \"#dde1ef\",\n },\n },\n };\n\n return (\n <Card>\n <Title>Platform split</Title>\n <Body>\n <ChartBox>\n <Doughnut data={chartData} options={options} />\n </ChartBox>\n <Stats>\n {data.map((d, i) => (\n <Row key={d.platform}>\n <span>\n <Dot color={COLORS[i % COLORS.length]} />\n {d.platform}\n </span>\n <span style={{ color: \"#8892a8\" }}>\n {d.total} · {d.pass_rate.toFixed(1)}% pass\n </span>\n </Row>\n ))}\n </Stats>\n </Body>\n </Card>\n );\n}\n","import React from \"react\";\nimport { useHistory } from \"react-router-dom\";\nimport styled from \"styled-components\";\nimport moment from \"moment\";\nimport {\n MetricsBuildHealth,\n MetricsDeviceReliability,\n MetricsTopFailingTest,\n MetricsAppVersion,\n} from \"../../../../interfaces/metrics\";\nimport { getBuildDetailsUrl } from \"../../../../constants/routes\";\n\nconst Card = styled.div`\n background: #13151d;\n border: 1px solid #1f2235;\n border-radius: 10px;\n padding: 18px 20px;\n`;\n\nconst Title = styled.div`\n font-size: 13px;\n font-weight: 600;\n color: #dde1ef;\n margin-bottom: 12px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n`;\n\nconst Table = styled.div`\n display: block;\n width: 100%;\n overflow-x: auto;\n`;\n\nconst TableInner = styled.table`\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n color: #dde1ef;\n\n th,\n td {\n text-align: left;\n padding: 8px 10px;\n border-bottom: 1px solid #1f2235;\n white-space: nowrap;\n }\n\n th {\n font-size: 11px;\n font-weight: 500;\n color: #8892a8;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n tbody tr:hover {\n background: #1a1d28;\n }\n\n tbody tr {\n cursor: default;\n }\n\n tbody tr.clickable {\n cursor: pointer;\n }\n`;\n\nconst Pill = styled.span<{ color: string }>`\n color: ${(p) => p.color};\n font-weight: 600;\n`;\n\nconst Empty = styled.div`\n color: #8892a8;\n font-size: 12px;\n padding: 12px 0;\n`;\n\nfunction passRateColor(rate: number) {\n if (rate >= 90) return \"#2dd975\";\n if (rate >= 70) return \"#e8c14a\";\n return \"#f45858\";\n}\n\nfunction fmtDuration(seconds: number): string {\n if (!seconds || seconds < 0) return \"—\";\n if (seconds < 60) return `${seconds.toFixed(0)}s`;\n const m = Math.floor(seconds / 60);\n const s = Math.round(seconds % 60);\n return `${m}m ${s}s`;\n}\n\nexport function TopFailingTestsTable({\n rows,\n}: {\n rows: MetricsTopFailingTest[];\n}) {\n return (\n <Card>\n <Title>Top failing tests</Title>\n {!rows.length ? (\n <Empty>No failing tests in this window 🎉</Empty>\n ) : (\n <Table>\n <TableInner>\n <thead>\n <tr>\n <th>Test</th>\n <th>Failed</th>\n <th>Passed</th>\n <th>Pass rate</th>\n <th>Last failure</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr key={r.name}>\n <td title={r.name}>\n {r.name.length > 70 ? r.name.slice(0, 70) + \"…\" : r.name}\n </td>\n <td>\n <Pill color=\"#f45858\">{r.failed}</Pill>\n </td>\n <td>{r.passed}</td>\n <td>\n <Pill color={passRateColor(r.pass_rate)}>\n {r.pass_rate.toFixed(1)}%\n </Pill>\n </td>\n <td style={{ color: \"#8892a8\" }}>\n {r.last_failure_at\n ? moment(r.last_failure_at).fromNow()\n : \"—\"}\n </td>\n </tr>\n ))}\n </tbody>\n </TableInner>\n </Table>\n )}\n </Card>\n );\n}\n\nexport function DeviceReliabilityTable({\n rows,\n}: {\n rows: MetricsDeviceReliability[];\n}) {\n return (\n <Card>\n <Title>Device reliability</Title>\n {!rows.length ? (\n <Empty>No device data</Empty>\n ) : (\n <Table>\n <TableInner>\n <thead>\n <tr>\n <th>Device</th>\n <th>Platform</th>\n <th>Sessions</th>\n <th>Pass rate</th>\n <th>Avg duration</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr key={`${r.device_name}-${r.udid}`}>\n <td>\n <div>{r.device_name}</div>\n <div style={{ color: \"#8892a8\", fontSize: 11 }}>\n {r.udid}\n </div>\n </td>\n <td style={{ color: \"#8892a8\" }}>{r.platform}</td>\n <td>{r.total}</td>\n <td>\n <Pill color={passRateColor(r.pass_rate)}>\n {r.pass_rate.toFixed(1)}%\n </Pill>\n </td>\n <td style={{ color: \"#8892a8\" }}>\n {fmtDuration(r.avg_duration_sec)}\n </td>\n </tr>\n ))}\n </tbody>\n </TableInner>\n </Table>\n )}\n </Card>\n );\n}\n\nexport function BuildHealthTable({ rows }: { rows: MetricsBuildHealth[] }) {\n const history = useHistory();\n return (\n <Card>\n <Title>Recent builds</Title>\n {!rows.length ? (\n <Empty>No builds</Empty>\n ) : (\n <Table>\n <TableInner>\n <thead>\n <tr>\n <th>Build</th>\n <th>User</th>\n <th>Platform</th>\n <th>App version</th>\n <th>Sessions</th>\n <th>Pass rate</th>\n <th>Avg duration</th>\n <th>Created</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr\n key={r.build_id}\n className=\"clickable\"\n onClick={() => history.push(getBuildDetailsUrl(r.build_id))}\n >\n <td>{r.build_name || r.build_id}</td>\n <td style={{ color: \"#8892a8\" }}>{r.user || \"—\"}</td>\n <td style={{ color: \"#8892a8\" }}>{r.platform || \"—\"}</td>\n <td style={{ color: \"#8892a8\" }}>{r.app_version || \"—\"}</td>\n <td>{r.total}</td>\n <td>\n <Pill color={passRateColor(r.pass_rate)}>\n {r.pass_rate.toFixed(1)}%\n </Pill>\n </td>\n <td style={{ color: \"#8892a8\" }}>\n {fmtDuration(r.avg_duration_sec)}\n </td>\n <td style={{ color: \"#8892a8\" }}>\n {r.created_at ? moment(r.created_at).fromNow() : \"—\"}\n </td>\n </tr>\n ))}\n </tbody>\n </TableInner>\n </Table>\n )}\n </Card>\n );\n}\n\nexport function AppVersionTable({ rows }: { rows: MetricsAppVersion[] }) {\n return (\n <Card>\n <Title>App version breakdown</Title>\n {!rows.length ? (\n <Empty>No version data</Empty>\n ) : (\n <Table>\n <TableInner>\n <thead>\n <tr>\n <th>App version</th>\n <th>Sessions</th>\n <th>Passed</th>\n <th>Failed</th>\n <th>Pass rate</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((r) => (\n <tr key={r.app_version}>\n <td>{r.app_version}</td>\n <td>{r.total}</td>\n <td>{r.passed}</td>\n <td>\n <Pill color=\"#f45858\">{r.failed}</Pill>\n </td>\n <td>\n <Pill color={passRateColor(r.pass_rate)}>\n {r.pass_rate.toFixed(1)}%\n </Pill>\n </td>\n </tr>\n ))}\n </tbody>\n </TableInner>\n </Table>\n )}\n </Card>\n );\n}\n","import { AppState } from \"../..\";\n\nexport const getMetricsData = (state: AppState) => state.entities.metrics.data;\n\nexport const getMetricsFilter = (state: AppState) =>\n state.entities.metrics.filter;\n\nexport const getIsMetricsLoading = (state: AppState) =>\n state.entities.metrics.isLoading;\n\nexport const getMetricsError = (state: AppState) =>\n state.entities.metrics.error;","import React, { useEffect } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport styled from \"styled-components\";\nimport { APP_HEADER_HEIGHT } from \"../../constants/ui\";\nimport { Header } from \"../UI/organisms/header/header\";\nimport SerialLayout, { Row } from \"../UI/layouts/serial-layout\";\nimport MetricsFiltersBar from \"../UI/organisms/metrics/metrics-filters\";\nimport MetricsKpiRow from \"../UI/organisms/metrics/metrics-kpis\";\nimport {\n PassFailTrend,\n DurationTrend,\n} from \"../UI/organisms/metrics/metrics-trend-chart\";\nimport MetricsPlatformSplitView from \"../UI/organisms/metrics/metrics-platform-split\";\nimport {\n AppVersionTable,\n BuildHealthTable,\n DeviceReliabilityTable,\n TopFailingTestsTable,\n} from \"../UI/organisms/metrics/metrics-tables\";\nimport Spinner from \"../UI/atoms/spinner\";\nimport {\n fetchMetricsInit,\n setMetricsFilter,\n} from \"../../store/actions/metrics-actions\";\nimport {\n getIsMetricsLoading,\n getMetricsData,\n getMetricsError,\n getMetricsFilter,\n} from \"../../store/selectors/entities/metrics-selector\";\nimport { MetricsFilter } from \"../../interfaces/metrics\";\n\nconst Page = styled.div`\n height: calc(100vh - ${APP_HEADER_HEIGHT}px);\n overflow-y: auto;\n padding: 28px 32px 64px 32px;\n background: #0c0d12;\n`;\n\nconst PageHeading = styled.h1`\n font-size: 22px;\n font-weight: 600;\n color: #dde1ef;\n margin: 0 0 6px 0;\n`;\n\nconst SubHeading = styled.div`\n font-size: 12px;\n color: #8892a8;\n margin-bottom: 24px;\n`;\n\nconst TwoCol = styled.div`\n display: grid;\n grid-template-columns: 2fr 1fr;\n gap: 16px;\n margin-bottom: 16px;\n\n @media (max-width: 1100px) {\n grid-template-columns: 1fr;\n }\n`;\n\nconst FullRow = styled.div`\n margin-bottom: 16px;\n`;\n\nconst Center = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n`;\n\nconst ErrorBox = styled.div`\n color: #f45858;\n background: rgba(244, 88, 88, 0.08);\n border: 1px solid rgba(244, 88, 88, 0.3);\n border-radius: 8px;\n padding: 14px 16px;\n font-size: 13px;\n`;\n\nexport default function MetricsTemplate() {\n const dispatch = useDispatch();\n const data = useSelector(getMetricsData);\n const filter = useSelector(getMetricsFilter);\n const isLoading = useSelector(getIsMetricsLoading);\n const error = useSelector(getMetricsError);\n\n useEffect(() => {\n dispatch(fetchMetricsInit(filter));\n }, []);\n\n const handleFilterChange = (patch: Partial<MetricsFilter>) => {\n dispatch(setMetricsFilter(patch));\n };\n\n return (\n <SerialLayout>\n <Row height={`${APP_HEADER_HEIGHT}px`}>\n <Header />\n </Row>\n <Row height={`calc(100vh - ${APP_HEADER_HEIGHT}px)`}>\n <Page>\n <PageHeading>Metrics</PageHeading>\n <SubHeading>\n Analytics and reporting across recent test runs and builds\n </SubHeading>\n\n <MetricsFiltersBar filter={filter} onChange={handleFilterChange} />\n\n {error && <ErrorBox>{error}</ErrorBox>}\n\n {isLoading && !data ? (\n <Center>\n <Spinner />\n </Center>\n ) : data ? (\n <>\n <MetricsKpiRow kpis={data.kpis} />\n\n <TwoCol>\n <PassFailTrend trend={data.trend} />\n <MetricsPlatformSplitView data={data.platform_split} />\n </TwoCol>\n\n <FullRow>\n <DurationTrend trend={data.trend} />\n </FullRow>\n\n <FullRow>\n <BuildHealthTable rows={data.build_health} />\n </FullRow>\n\n <TwoCol>\n <TopFailingTestsTable rows={data.top_failing_tests} />\n <AppVersionTable rows={data.app_versions} />\n </TwoCol>\n\n <FullRow>\n <DeviceReliabilityTable rows={data.device_reliability} />\n </FullRow>\n </>\n ) : null}\n </Page>\n </Row>\n </SerialLayout>\n );\n}\n","import React from \"react\";\nimport MetricsTemplate from \"../templates/metrics-template\";\n\nexport default function Metrics() {\n return <MetricsTemplate />;\n}","export default function PageNotFound() {\n return null;\n}\n","import React from \"react\";\nimport styled from \"styled-components\";\nimport Spinner, { Sizes } from \"../atoms/spinner\";\nimport Centered from \"./centered\";\n\nconst Container = styled.div`\n height: 100vh;\n`;\n\nconst Message = styled.p`\n text-align: center;\n`;\n\nexport default function AppLoader() {\n return (\n <Container>\n <Centered>\n <>\n <Spinner size={Sizes.XL} />\n <Message>Loading</Message>\n </>\n </Centered>\n </Container>\n );\n}\n","import React from \"react\";\nimport { useEffect } from \"react\";\nimport { connect, useDispatch } from \"react-redux\";\nimport {\n BrowserRouter as Router,\n Switch,\n Route,\n} from \"react-router-dom\";\nimport styled, { ThemeProvider } from \"styled-components\";\nimport Dashboard from \"./components/pages/dashboard\";\nimport Metrics from \"./components/pages/metrics\";\nimport PageNotFound from \"./components/pages/page-not-found\";\nimport AppLoader from \"./components/UI/molecules/app-loader\";\nimport { BASE_URL, METRICS_URL } from \"./constants/routes\";\nimport { ThemeConfig } from \"./constants/themes\";\nimport { AppState } from \"./store\";\nimport ReduxActionTypes from \"./store/redux-action-types\";\nimport { getSelectedTheme } from \"./store/selectors/ui/theme-selector\";\n\nconst Container = styled.div`\n font-family: 'Inter', system-ui, -apple-system, sans-serif;\n font-size: ${(props) => props.theme.fonts.size.L};\n color: ${(props) => props.theme.colors.greyscale[0]};\n background: ${(props) => props.theme.colors.greyscale[6]};\n min-height: 100vh;\n`;\n\ntype PropsType = {\n theme: ThemeConfig;\n isAppInitialised: boolean;\n};\n\nfunction AppRouter(props: PropsType) {\n const { theme, isAppInitialised } = props;\n const dispatch = useDispatch();\n\n useEffect(() => {\n dispatch({\n type: ReduxActionTypes.INIT_APP,\n });\n }, []);\n return (\n <ThemeProvider theme={theme}>\n <Container>\n {isAppInitialised ? (\n <Router>\n <Switch>\n <Route path={METRICS_URL} component={Metrics} />\n <Route path={BASE_URL} component={Dashboard} />\n <Route component={PageNotFound} />\n </Switch>\n </Router>\n ) : (\n <AppLoader />\n )}\n </Container>\n </ThemeProvider>\n );\n}\n\nexport default connect((state: AppState) => {\n return {\n theme: getSelectedTheme(state),\n isAppInitialised: state.ui.appInitialised,\n };\n})(AppRouter);\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport \"./index.css\";\nimport reportWebVitals from \"./reportWebVitals\";\nimport { Provider } from \"react-redux\";\nimport Store from \"./store\";\nimport AppRouter from \"./App-router\";\n\nReactDOM.render(\n <React.StrictMode>\n <Provider store={Store}>\n {/* <BrowserRouter>\n <App />\n </BrowserRouter> */}\n <AppRouter />\n </Provider>\n </React.StrictMode>,\n document.getElementById(\"root\"),\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}
|