UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

499 lines (407 loc) 17.2 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Ext.define('Siesta.Project.Browser.UI.TestGrid', { extend : 'Ext.tree.Panel', alias : 'widget.testgrid', requires : [ 'Siesta.Project.Browser.UI.FilterableTreeView', 'Siesta.Project.Browser.UI.TestGridController', 'Siesta.Project.Browser.UI.TestNameColumn' ], controller : 'testgrid', stateful : true, rootVisible : false, header : false, rowLines : false, useArrows : true, border : false, cls : 'tr-testgrid', iconCls : 'tr-status-neutral-small', width : 340, collapsible : true, expanded : true, viewType : 'filterabletreeview', enableColumnMove : false, project : null, lines : false, filter : null, filterGroups : false, resultSummary : null, stateConfig : null, showSizeControls : false, isReadOnlyReport : false, menuHideTimeout : false, viewConfig : { enableTextSelection : true, toggleOnDblClick : false, markDirty : false, trackOver : false, getRowClass : function(record) { if (record.get('descriptor').isSystemDescriptor) { return 'siesta-system-descriptor'; } }, // Avoid DOM updates when irrelevant shouldUpdateCell : function(record, column, changedFieldNames) { if (column.dataIndex === 'passCount' && changedFieldNames && !( Ext.Array.contains(changedFieldNames, 'passCount') || Ext.Array.contains(changedFieldNames, 'todoPassCount') ) ) { return 0; } if (column.dataIndex === 'failCount' && changedFieldNames && !( Ext.Array.contains(changedFieldNames, 'failCount') || Ext.Array.contains(changedFieldNames, 'todoFailCount') ) ) { return 0; } return Ext.tree.View.prototype.shouldUpdateCell.apply(this, arguments); } }, initComponent : function () { var me = this; var R = Siesta.Resource('Siesta.Project.Browser.UI.TestGrid'); var state = this.stateConfig; Ext.apply(this, { title : R.get('title'), columns : { // Hack, prevent Ext JS grid column to react to click/keys in filter field createFocusableContainerKeyNav : Ext.emptyFn, // EOF Hack items : [ { xtype : 'testnamecolumn', store : this.store, project : this.project }, { header : R.get('passText'), width : 35, sortable : false, tdCls : 'x-unselectable result-cell', menuDisabled : true, dataIndex : 'passCount', align : 'center', renderer : this.passedColumnRenderer, scope : this }, { header : R.get('failText'), width : 35, sortable : false, tdCls : 'x-unselectable result-cell', menuDisabled : true, dataIndex : 'failCount', align : 'center', renderer : this.failedColumnRenderer, scope : this }, { header : 'Time', width : 50, sortable : false, dataIndex : 'time', align : 'center', renderer : function (value, meta, record) { if (!record.isLeaf()) return '' return value + 'ms'; }, hidden : !(this.project.showTestDurationColumn || this.isReadOnlyReport) } ] }, bbar : { xtype : 'toolbar', cls : 'main-bbar siesta-toolbar', border : false, height : 45, defaults : { scale : 'large', width : 30, tooltipType : 'title' }, items : this.getBottomBarItems(state, R) }, dockedItems : this.showSizeControls ? [ { xtype : 'toolbar', cls : 'size-toolbar', border : true, dock : 'bottom', items : [ { xtype : 'slider', itemId : 'framesizeSlider', width : 130, value : 3, increment : 1, minValue : 0, maxValue : this.viewportSizes.length - 1, listeners : { change : this.onDimensionOrOrientationChange, scope : this } }, { xtype : 'label', cls : 'size-label', itemId : 'sizeLabel', width : 65 }, { boxLabel : R.get('landscape'), itemId : 'orientationCheckbox', xtype : 'checkbox', checked : true, listeners : { change : this.onDimensionOrOrientationChange, scope : this } } ] } ] : [] }) this.callParent(arguments); this.getView().on('beforerefresh', function () { var trigger = me.down('#trigger') if (me.filterGroups) trigger.setFilterGroups(me.filterGroups) if (me.filter) trigger.setValue(me.filter) // cancel refresh if there's a filter - in this case an additional refresh will be triggered by // the filtering which will be already not canceled since this is 1 time listener return !me.filter }, null, { single : true }) this.on('viewready', this.onMyViewReady, this, { delay : 10 }); }, getBottomBarItems : function (state, R) { var items = [] if (!this.isReadOnlyReport) { items.push( { glyph : 0xf04b, cls : 'run-checked', text : '<span class="subicon fa-check"></span>', tooltip : R.get('runCheckedText'), actionName : 'run-checked' }, { glyph : 0xf04e, cls : 'run-all', tooltip : R.get('runAllText'), actionName : 'run-all' }, { glyph : 0xf04b, cls : 'run-failed', text : '<span class="subicon fa-bug"></span>', tooltip : R.get('runFailedText'), actionName : 'run-failed' }, { glyph : 0xf013, tooltip : R.get('optionsText'), cls : 'options', action : 'options', listeners : { mouseover : this.onOptionsButtonMouseOver, mouseout : this.onOptionsButtonMouseOut, scope : this }, menu : { itemId : 'tool-menu', listeners : { mouseenter : { fn : this.onOptionsMenuMouseEnter, // delay to cancel the hide _after_ the "mouseleave" from the sub-menu delay : 100 }, mouseover : { fn : this.onOptionsMenuMouseEnter, delay : 100 }, mouseleave : this.onOptionsMenuMouseLeave, scope : this }, items : [ { text : R.get('transparentExText'), option : 'transparentEx', checked : state.transparentEx, tooltip : R.get('transparentExTooltip') }, // { // text : R.get('cachePreloadsText'), // option : 'cachePreload', // checked : state.cachePreload // }, { text : R.get('breakOnFailText'), option : 'breakOnFail', checked : state.breakOnFail, tooltip : R.get('breakOnFailTooltip') }, { text : R.get('debuggerOnFailText'), option : 'debuggerOnFail', checked : state.debuggerOnFail, tooltip : R.get('debuggerOnFailTooltip') }, { itemId : 'observerModeMenuItem', text : R.get('observerModeText'), option : 'observerMode', checked : state.observerMode, tooltip : R.get('observerModeTooltip') }, { text : R.get('autoLaunchText'), option : 'autoRun', checked : state.autoRun, tooltip : R.get('autoLaunchTooltip') }, { xtype : 'menuseparator' }, { text : R.get('aboutText'), itemId : 'aboutSiesta' }, { text : R.get('documentationText'), href : R.get('siestaDocsUrl'), hrefTarget : '_blank' } ] } } ) } items.push( '->', { xtype : 'component', cls : 'summary-bar', border : false, width : 55, itemId : 'result-summary', data : { pass : 0, fail : 0 }, tpl : '<div><span class="total-pass">{pass}</span><span class="icon fa-check"></span></div><div><span class="total-fail">{fail}</span><span class="icon fa-bug"></span></div>' } ) return items }, onHistoryChange : function(token) { if (token) { var testFile = this.store.getNodeById(token) if (testFile) { this.selectTestFile(testFile); } } }, onDimensionOrOrientationChange : function (slider, val) { var newSize = this.viewportSizes[this.framesizeSlider.getValue()]; var landscape = this.orientationCheckbox.getValue(); this.sizeLabel.setText(newSize.join('x')); this.fireEvent('framesizechange', slider, newSize[0], newSize[1], landscape); }, getFilterValue : function () { return this.down('#trigger').getValue() }, getFilterGroups : function () { return this.down('#trigger').getFilterGroups() }, passedColumnRenderer : function (value, meta, record) { if (!record.isLeaf()) return '' if (record.data.todoPassCount > 0) { value += ' <span title="' + record.data.todoPassCount + ' ' + Siesta.Resource('Siesta.Project.Browser.UI.TestGrid', 'todoPassedText') + '" class="tr-test-todo tr-test-todo-pass">+ ' + record.data.todoPassCount + '</span>'; } return value; }, failedColumnRenderer : function (value, meta, record) { if (!record.isLeaf()) return '' if (record.data.todoFailCount > 0) { value += ' <span title="' + record.data.todoFailCount + ' ' + Siesta.Resource('Siesta.Project.Browser.UI.TestGrid', 'todoFailedText') + '" class="tr-test-todo tr-test-todo-fail">+ ' + record.data.todoFailCount + '</span>'; } return value; }, onOptionsButtonMouseOver : function (button) { clearTimeout(this.menuHideTimeout) button.showMenu() button.menu.hide = function () {} setTimeout(function () { delete button.menu.hide }, 1000) }, onOptionsButtonMouseOut : function (button) { var me = this if (this.menuHideTimeout) return this.menuHideTimeout = setTimeout(function () { delete button.menu.hide button.hideMenu() me.menuHideTimeout = null }, 500) }, onOptionsMenuMouseEnter : function (menu) { clearTimeout(this.menuHideTimeout) this.menuHideTimeout = null }, onOptionsMenuMouseLeave : function () { var me = this var menu = this.down('#tool-menu') if (this.menuHideTimeout) return this.menuHideTimeout = setTimeout(function () { delete menu.hide menu.hide() me.menuHideTimeout = null }, 500) }, afterRender : function () { this.callParent(arguments); this.summaryPassEl = this.el.down('.total-pass'); this.summaryFailEl = this.el.down('.total-fail'); if (this.showSizeControls) { this.orientationCheckbox = this.down('#orientationCheckbox'); this.sizeLabel = this.down('#sizeLabel'); this.framesizeSlider = this.down('#framesizeSlider'); var size = this.viewportSizes[ this.framesizeSlider.getValue() ]; this.sizeLabel.setText(size.join('x')); } }, onMyViewReady : function() { Ext.History.on('change', this.onHistoryChange, this); var hash = window.location.hash; if (hash) { this.onHistoryChange(hash.substring(1)); } }, updateStatus : function (pass, fail) { this.summaryPassEl.update(String(pass)); this.summaryFailEl.update(String(fail)); }, setFilterValue : function (value) { this.down('treefilter').setValue(value) }, selectTestFile : function(testFile) { if (testFile) { testFile.bubble(function(parent) { parent.expand(); }); // Make sure test is not filtered out if (this.store.getById(testFile.id) && this.store.indexOf(testFile) >= 0 ) { if (!this.getCollapsed() && this.getView().getNodes().length > 0) { this.ensureVisible(testFile); } this.getSelectionModel().select(testFile) } } } })