siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
1,165 lines (833 loc) • 38.4 kB
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
<script type="text/javascript">
function highlight() {
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
}
</script>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js">/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
// workaround for: http://www.sencha.com/forum/showthread.php?299660-5.1.0.107-Exception-thrown-when-opening-any-example-in-Chrome-touch-simulation-mode&p=1094459#post1094459
// this condition seems to point that Chrome is opened in device simulation mode, w/o touch events enabled from command line
// seems "TouchEvents" + "!Touch" confuses Ext and exception is thrown
if (Ext.supports && Ext.supports.TouchEvents && !Ext.supports.Touch) {
// w/o these, UI throws exceptions
Ext.supports.Touch = false
Ext.supports.touchScroll = false
}
// eof workaround
Ext.define('Siesta.Project.Browser.UI.Viewport', {
extend : 'Ext.container.Viewport',
mixins : [
'Siesta.Project.Browser.UI.CanFillAssertionsStore'
],
controller : 'viewport',
requires : [
'Siesta.Project.Browser.UI.ViewportController',
'Ext.state.LocalStorageProvider',
'Ext.state.CookieProvider',
'ExtX.Reference.Slot',
'Siesta.Project.Browser.UI.TestGrid',
'Siesta.Project.Browser.UI.ResultPanel',
'Siesta.Project.Browser.Model.AssertionTreeStore',
'Siesta.Project.Browser.Model.FilterableTreeStore',
'Siesta.Project.Browser.Model.TestFile',
'Siesta.Project.Browser.Model.Assertion',
'Siesta.Project.Browser.UI.VersionUpdateButton',
'Siesta.Project.Browser.UI.Override',
// requiring "Ext.Img" for it to be in the "siesta-all.js" bundle
// otherwise it is included into "siesta-coverage-all.js" bundle and when using "siesta-no-ext-all.js" setup
// Ext.Img is double included
'Ext.Img'
],
title : null,
project : null,
// need to set stateful properties before `initComponent`
stateful : false,
layout : 'border',
// stateful
selection : null,
filter : null,
filterGroups : false,
// eof stateful
testsStore : null,
contextMenu : null,
enableVersionCheck : true,
collapsedNodes : null,
showSizeControls : false,
expectedExtJSVersion : '6.0.1.250',
viewportSizes : [
[640, 480],
[800, 600],
[1024, 768],
[1920, 1080],
[2048, 1536]
],
idGenSequence : 1,
isReadOnlyReport : false,
dataUrl : 'report-data.json',
autoLaunch : false,
initComponent : function () {
var project
if (this.isReadOnlyReport) {
project = new Siesta.Project.Browser()
project.configure({
stateful : false
})
this.project = project
} else
project = this.project;
Ext.getBody().addCls('siesta')
Ext.getBody().on('keydown', this.onBodyKeyDown, this)
Ext.setGlyphFontFamily('FontAwesome');
Ext.state.Manager.setProvider(Ext.supports.LocalStorage ? new Ext.state.LocalStorageProvider() : new Ext.state.CookieProvider())
this.selection = {}
// config given during viewport instantiation
var filter = this.filter
if (project.stateful) this.applyState(this.loadState())
// config given during viewport instantiation - comes from query string ?filter= overrides everything
if (filter) {
this.filter = filter
this.filterGroups = false
}
var data = this.buildTreeData({
id : 'root',
group : 'test suite' + this.title,
items : project.descriptors
}).children;
var testsStore = this.testsStore = new Siesta.Project.Browser.Model.FilterableTreeStore({
model : 'Siesta.Project.Browser.Model.TestFile',
sortOnLoad : false,
root : {
expanded : true,
children : data
},
proxy : 'memory',
listeners : {
nodecollapse : this.saveState,
nodeexpand : this.saveState,
scope : this
}
})
Ext.apply(this, {
slots : true,
items : [
{
region : 'west',
xtype : 'testgrid',
store : testsStore,
stateful : project.stateful,
slot : 'filesTree',
id : project.id.replace(/\W/g, '_') + '-testTree',
showSizeControls : this.showSizeControls,
viewportSizes : this.viewportSizes,
stateConfig : this.getState(),
project : this.project,
isReadOnlyReport : this.isReadOnlyReport,
animate : !Ext.isIE,
split : {
size : 7
},
filter : this.filter,
filterGroups : this.filterGroups,
listeners : {
viewready : this.onFilterApplied,
scope : this
}
},
{
xtype : 'resultpanel',
region : 'center',
slot : 'resultPanel',
cls : 'resultPanel-panel',
viewDOM : this.getOption('viewDOM'),
scaleToFit : this.getOption('scaleToFit'),
scaleToFitMode : this.getOption('scaleToFitMode'),
stateConfig : this.getState(),
id : project.id.replace(/\W/g, '_') + '-resultpanel',
project : project,
recorderConfig : project.recorderConfig,
isReadOnlyReport : this.isReadOnlyReport,
maintainViewportSize : project.maintainViewportSize,
domContainerRegion : project.domContainerRegion,
listeners : {
newjsonreport : this.onNewJsonReport,
scope : this
}
}
]
// eof main content area
})
this.callParent()
this.slots.filesTree.store.on({
'filter-set' : this.saveState,
'filter-clear' : this.saveState,
scope : this
})
this.on('statechange', this.saveState, this)
project.on('testendbubbling', this.onEveryTestEnd, this)
project.on('testsuitelaunch', this.onTestSuiteLaunch, this)
project.on('assertiondiscard', this.onAssertionDiscarded, this)
if (window.location.href.match('^file:///') && !(this.isReadOnlyReport && Ext.browser.is('Firefox'))) {
var R = Siesta.Resource('Siesta.Project.Browser.UI.Viewport');
Ext.Msg.alert(R.get('httpWarningTitle'), R.get('httpWarningDesc'))
} else
if (this.isReadOnlyReport) this.fetchJsonReport()
},
onNewJsonReport : function (field, report) {
this.loadJsonReport(report)
},
buildTreeData : function (descriptor) {
var data = {
id : descriptor.id,
title : descriptor.group || descriptor.title || descriptor.name,
descriptor : descriptor,
// HACK, bypass Ext JS cloning
nodeType : 1,
cloneNode : function () { return this; }
// EOF HACK
}
data.tooltip = descriptor.desc || data.title
var me = this
var prevId = data.id
var collapsedNodes = this.collapsedNodes || {}
if (descriptor.group) {
var children = []
Ext.each(descriptor.items, function (desc) {
children.push(me.buildTreeData(desc))
})
Ext.apply(data, {
expanded : (collapsedNodes[prevId] != null || descriptor.expanded === false) ? false : true,
// || false is required for TreeView - it checks that "checked" field contains Boolean
checked : me.selection.hasOwnProperty(prevId) || false,
folderStatus : 'yellow',
children : children,
leaf : false
})
} else {
Ext.apply(data, {
url : descriptor.url,
leaf : true,
// || false is required for TreeView - it checks that "checked" field contains Boolean
checked : me.selection.hasOwnProperty(prevId) || false,
passCount : 0,
failCount : 0,
time : 0,
assertionsStore : new Siesta.Project.Browser.Model.AssertionTreeStore({
//autoDestroy : true,
model : 'Siesta.Project.Browser.Model.Assertion',
proxy : 'memory',
root : {
id : '__ROOT__',
expanded : true
}
})
})
}
return data
},
onBodyKeyDown : function (e) {
if (e.ctrlKey) {
var project = this.project
if (e.getKey() == Ext.event.Event[ project.rerunHotKey ]) {
this.runTest();
e.preventDefault();
}
if (e.getKey() == Ext.event.Event[ project.observerModeHotKey ]) {
var mode = !project.observerMode
var menuItem = this.down('#observerModeMenuItem')
menuItem.setChecked(mode)
menuItem.fireEvent('click', menuItem)
e.preventDefault();
}
}
},
buildTreeDataFromJSONSReportNode : function (reportNode) {
var data = {
id : this.idGenSequence++,
title : reportNode.group || reportNode.name || reportNode.url.replace(/(?:.*\/)?([^/]+)$/, '$1'),
descriptor : reportNode,
// HACK, bypass Ext JS cloning
nodeType : 1,
cloneNode : function () {
return this;
}
}
var me = this
if (reportNode.group) {
var children = []
Ext.each(reportNode.items, function (reportNode) {
children.push(me.buildTreeDataFromJSONSReportNode(reportNode))
})
Ext.apply(data, {
expanded : true,
// disable checkbox selection
checked : null,
leaf : false,
folderStatus : 'yellow',
children : children
})
} else {
var parentTest = new Siesta.Test.Browser({
project : this.project,
url : reportNode.url,
name : reportNode.name,
startDate : new Date(reportNode.startDate)
})
Ext.apply(data, {
url : reportNode.url,
leaf : true,
// disable checkbox selection
checked : null,
time : reportNode.endDate - reportNode.startDate,
test : parentTest,
assertionsStore : new Siesta.Project.Browser.Model.AssertionTreeStore({
model : 'Siesta.Project.Browser.Model.Assertion',
proxy : 'memory',
root : {
id : '__ROOT__',
expanded : true,
children : this.buildAssertionDataFromJSONSReportNode(reportNode.assertions, parentTest)
}
})
})
parentTest.endDate = new Date(reportNode.endDate)
Ext.apply(data, {
passCount : parentTest.getPassCount(),
failCount : parentTest.getFailCount(),
todoPassCount : parentTest.getTodoPassCount(),
todoFailCount : parentTest.getTodoFailCount()
})
}
return data
},
buildAssertionDataFromJSONSReportNode : function (assertions, parentTest) {
var me = this
var res = Joose.A.map(assertions, function (assertionNode) {
var isSubTest = assertionNode.type == 'Siesta.Result.SubTest'
var result
var data = {
id : me.idGenSequence++,
leaf : !isSubTest,
expanded : isSubTest && (assertionNode.bddSpecType != 'it' || !assertionNode.passed)
}
if (isSubTest) {
var subTest = new Siesta.Test.Browser({
trait : Siesta.Test.Sub,
name : assertionNode.name,
isTodo : assertionNode.isTodo,
startDate : new Date(assertionNode.startDate),
url : parentTest.url,
parent : parentTest,
specType : assertionNode.bddSpecType
})
data.children = me.buildAssertionDataFromJSONSReportNode(assertionNode.assertions, subTest)
subTest.endDate = new Date(assertionNode.endDate)
result = subTest.getResults()
} else {
var resultCls = Joose.S.strToClass(assertionNode.type)
result = new resultCls(assertionNode)
}
parentTest.addResult(result)
data.result = result
return data
})
if (!parentTest.parent) {
var summary = new Siesta.Result.Summary({
isFailed : parentTest.isFailed(),
description : parentTest.getSummaryMessage()
})
parentTest.addResult(summary)
res.push({
id : this.idGenSequence++,
result : summary,
loaded : true,
leaf : true,
expanded : false
})
}
return res
},
loadJsonReport : function (report) {
this.title = report.testSuiteName || ''
this.testsStore.setRootNode(this.buildTreeDataFromJSONSReportNode({
group : 'TOP',
items : report.testCases
}))
this.testsStore.getRootNode().cascadeBy(function (node) {
if (node.parentNode && !node.isLeaf()) node.updateFolderStatus()
})
this.updateStatusIndicator();
},
fetchJsonReport : function () {
var me = this
var loadingMask = new Ext.LoadMask({
target : this,
msg : Siesta.Resource('Siesta.Project.Browser.UI.CoverageReport', 'loadingText')
});
loadingMask.show()
// use this code for testing
// setTimeout(function () {
// loadingMask.hide()
//
// me.loadHtmlReport(me.htmlReport)
// }, 2000)
Ext.Ajax.request({
url : this.dataUrl,
success : function (response) {
loadingMask.hide()
me.loadJsonReport(Ext.JSON.decode(response.responseText))
},
failure : function () {
loadingMask.hide()
Ext.Msg.show({
title : Siesta.Resource('Siesta.Project.Browser.UI.CoverageReport', 'loadingErrorText'),
msg : Siesta.Resource('Siesta.Project.Browser.UI.CoverageReport', 'loadingErrorMessageText') + me.dataUrl,
buttons : Ext.MessageBox.OK,
icon : Ext.MessageBox.ERROR
})
}
})
},
onFilterApplied : function () {
if (this.autoLaunch) {
this.runAll()
} else
if (this.getOption('autoRun')) {
var checked = this.getChecked()
// either launch the suite for checked tests or for all
this.project.launch(checked.length && checked || this.project.descriptors)
}
},
setNodeChecked : function (testFile, checked, doNotCascade, skipSave) {
var me = this
var id = testFile.getId()
if (checked)
this.selection[id] = 1
else
delete this.selection[id]
testFile.set('checked', checked)
// when unchecking the node - uncheck the parent node (folder) as well
if (!checked && testFile.parentNode) me.setNodeChecked(testFile.parentNode, false, true, true)
// only cascade for folders and when `doNotCascade` is false
if (!testFile.isLeaf() && !doNotCascade) Ext.each(testFile.childNodes, function (childNode) {
me.setNodeChecked(childNode, checked, false, true)
})
if (!skipSave) this.saveState()
},
forEachTestFile : function (func, scope) {
scope = scope || this
var testsStore = this.testsStore
var root = testsStore.getRootNode()
root.cascadeBy(function (node) {
var isFilteredIn = testsStore.isNodeFilteredIn(node)
if (node != root && isFilteredIn) func.call(scope, node)
// do not cascade for child nodes if parent is not filtered in - faster tree traversing
return isFilteredIn
})
},
getChecked : function () {
var descriptors = []
this.forEachTestFile(function (testFileRecord) {
if (testFileRecord.get('checked') && testFileRecord.isLeaf()) descriptors.push(testFileRecord.get('descriptor'))
})
return descriptors
},
runChecked : function () {
var checked = this.getChecked();
if (checked.length > 0) {
this.project.launch(this.getChecked())
}
},
runFailed : function () {
var descriptors = []
this.forEachTestFile(function (testFileRecord) {
var test = testFileRecord.get('test')
if (test && test.isFailed()) descriptors.push(testFileRecord.get('descriptor'))
})
if (descriptors.length > 0) {
this.project.launch(descriptors)
}
},
runAll : function () {
var allDesc = []
this.forEachTestFile(function (testFile) {
if (testFile.isLeaf()) allDesc.push(testFile.get('descriptor'))
})
if (allDesc.length > 0) {
this.project.launch(allDesc)
}
},
// this method is never called currently, because there's no corresponding button in the test grid bottom bar
stopSuite : function (button) {
button.disable()
this.project.stopCurrentLaunch();
setTimeout(function () {
button.enable()
}, 1000)
},
onTestSuiteStop : function (sourceTest) {
this.testsStore.forEach(function (testFileRecord) {
if (testFileRecord.get('isStarting')) {
testFileRecord.set('isStarting', false);
}
});
if (sourceTest) {
var testRecord = this.testsStore.getNodeById(sourceTest.url)
this.slots.filesTree.getSelectionModel().select(testRecord);
}
},
// looks less nice than setting it only after preload for some reason
onBeforeScopePreload : function (scopeProvider, url) {
var testRecord = this.testsStore.getNodeById(url)
},
isTestRunningVisible : function (test) {
// return false for test's running in popups (not iframes), since we can't show any visual accompaniment for them
if (!(test.scopeProvider instanceof Scope.Provider.IFrame)) return false;
// if there is a "forced to be on top" test then we only need to compare the tests instances
if (this.project.testOfForcedIFrame) {
return this.project.testOfForcedIFrame.isFromTheSameGeneration(test)
}
// otherwise the only possibly visible test is the one of the current assertion grid
var resultPanel = this.slots.resultPanel;
// if resultPanel has no testRecord it hasn't yet been assigned a test record
if (!resultPanel.test || !resultPanel.test.isFromTheSameGeneration(test)) {
return false;
}
// now we know that visible assertion grid is from our test and there is no "forced on top" test
// we only need to check visibility (collapsed / expanded of the right panel
return resultPanel.isFrameVisible()
},
resetDescriptors : function (descriptors) {
var testsStore = this.testsStore;
Joose.A.each(this.project.flattenDescriptors(descriptors), function (descriptor) {
var testRecord = testsStore.getNodeById(descriptor.id);
testRecord.get('assertionsStore').removeAll(true)
testRecord.reject();
// || false is required for TreeView - it checks that "checked" field contains Boolean
testRecord.set('checked', this.selection.hasOwnProperty(descriptor.id) || false)
}, this);
},
// method is called when test suite (any several tests) starts - before caching the script contents
// at this point we don't know yet about missing test files
onTestSuiteStart : function (descriptors) {
Ext.getBody().addCls('testsuite-running');
var filesTree = this.slots.filesTree
var selModel = filesTree.getSelectionModel()
var prevSelection = selModel.getLastSelected()
var testsStore = this.testsStore
this.resetDescriptors(descriptors);
// restore the selection after data reload
if (prevSelection) selModel.select(testsStore.getNodeById(prevSelection.getId()))
},
// method is called when test suite (any several tests) launches - after the caching the script contents
// has completed and 1st test is about to start
// at this point we know about missing files and `desc.isMissing` property is set
onTestSuiteLaunch : function (event, descriptors) {
var testsStore = this.testsStore
var updated = {}
Joose.A.each(this.project.flattenDescriptors(descriptors), function (descriptor) {
var testRecord = testsStore.getNodeById(descriptor.id)
testRecord.set({
isMissing : descriptor.isMissing,
isStarting : true
})
var groupNode = testRecord.parentNode
if (groupNode && !updated[groupNode.getId()]) {
// trying hard to prevent extra updates
for (var node = groupNode; node; node = node.parentNode) updated[node.getId()] = true
groupNode.updateFolderStatus()
}
})
},
onTestSuiteEnd : function (descriptors) {
Ext.getBody().removeCls('testsuite-running');
this.updateStatusIndicator();
// Without this the keyboard hotkey won't work (since one of the frames will steal focus likely)
if (Ext.isChrome) {
window.focus();
} else {
document.body.tabIndex = -1;
document.body.focus();
}
},
onTestStart : function (test) {
var testRecord = this.testsStore.getNodeById(test.url)
if (!this.isTestUpdateActual(test, testRecord)) return
testRecord.beginEdit()
// will trigger an update in grid
testRecord.set({
test : test,
isRunning : true
})
testRecord.endEdit()
var currentSelection = this.slots.filesTree.getSelectionModel().getLastSelected()
// activate the assertions grid for currently selected row, or, if the main area is empty
if (currentSelection && currentSelection.getId() == test.url) {
var resultPanel = this.slots.resultPanel
resultPanel.showTest(test, testRecord.get('assertionsStore'))
resultPanel.setInitializing(false);
T = test
}
},
// this method checks that test update, coming from given `test` is actual
// update may be not actual, if user has re-launched the test, so new test already presents
isTestUpdateActual : function (test, testRecord) {
return test.launchId == this.project.currentLaunchId
},
onTestUpdate : function (test, result, parentResult) {
var testRecord = this.testsStore.getNodeById(test.url)
// need to check that test record contains the same test instance as the test in arguments (or its sub-test)
// test instance may change if user has restarted a test for example
if (this.isTestUpdateActual(test, testRecord)) {
this.processNewResult(testRecord.get('assertionsStore'), test, result, parentResult)
}
},
onAssertionDiscarded: function (event, test, result) {
var testRecord = this.testsStore.getNodeById(test.url)
// need to check that test record contains the same test instance as the test in arguments (or its sub-test)
// test instance may change if user has restarted a test for example
if (this.isTestUpdateActual(test, testRecord)) {
var assertionStore = testRecord.get('assertionsStore')
assertionStore.getNodeById(result.id).remove()
}
},
// only triggered for "root" tests
onTestEnd : function (test) {
var testRecord = this.testsStore.getNodeById(test.url)
// need to check that test record contains the same test instance as the test in arguments (or its sub-test)
// test instance may change if user has restarted a test for example
if (this.isTestUpdateActual(test, testRecord)) {
testRecord.beginEdit()
testRecord.set({
'passCount' : test.getPassCount(),
'failCount' : test.getFailCount(),
'todoPassCount' : test.getTodoPassCount(),
'todoFailCount' : test.getTodoFailCount(),
'time' : test.getDuration() + 'ms'
});
testRecord.endEdit()
testRecord.parentNode && testRecord.parentNode.updateFolderStatus()
}
this.updateStatusIndicator()
},
// is bubbling and thus triggered for all tests (including sub-tests)
onEveryTestEnd : function (event, test) {
var testRecord = this.testsStore.getNodeById(test.url)
// need to check that test record contains the same test instance as the test in arguments (or its sub-test)
// test instance may change if user has restarted a test for example
if (this.isTestUpdateActual(test, testRecord)) {
this.processEveryTestEnd(testRecord.get('assertionsStore'), test)
}
},
onTestFail : function (test, exception, stack) {
var testRecord = this.testsStore.getNodeById(test.url)
// need to check that test record contains the same test instance as the test in arguments
// test instance may change if user has restarted a test for example
if (this.isTestUpdateActual(test, testRecord) && !test.isTodo) {
testRecord.set('isFailed', true)
testRecord.parentNode && testRecord.parentNode.updateFolderStatus()
}
},
getOption : function (name, onlyOwn) {
switch (name) {
case 'selection' :
return this.selection
default :
var project = this.project
if (onlyOwn) return project.hasOwnProperty(name) ? project[ name ] : undefined
return project[ name ]
}
},
setOption : function (name, value) {
var project = this.project
switch (name) {
case 'selection' :
return this.selection = value || {}
case 'collapsedNodes' :
return this.collapsedNodes = value
case 'filter' :
return this.filter = value
case 'filterGroups' :
return this.filterGroups = value
case 'observerMode' :
project.setObserverMode(value)
break
// UI only option, does not correspond to viewport/project config
case 'mouseSimSlow' :
if (value) {
project[ 'speedRun' ] = false
project[ 'turboMode' ] = false
}
break
// UI only option, does not correspond to viewport/project config
case 'mouseSimFast' :
if (value) {
project[ 'speedRun' ] = true
project[ 'turboMode' ] = false
}
break
// UI only option, does not correspond to viewport/project config
case 'mouseSimFastest' :
if (value) {
project[ 'speedRun' ] = true
project[ 'turboMode' ] = true
}
break
default :
return project[ name ] = value
}
},
getState : function (onlyOwnProperties) {
// getState is also called early, when there's no child components
// the absense of "this.slots" indicates this
var domContainer = this.slots && this.down('domcontainer')
var state = {
// UI configs
scaleToFit : domContainer ? domContainer.scaleToFit : this.scaleToFit,
scaleToFitMode : domContainer ? domContainer.scaleToFitMode : this.scaleToFitMode,
selection : this.getCheckedNodes(),
collapsedNodes : this.getCollapsedFolders(),
filter : this.slots ? this.slots.filesTree.getFilterValue() : this.filter,
filterGroups : this.slots ? this.slots.filesTree.getFilterGroups() : this.filterGroups
}
var me = this
// project configs
Joose.A.each([
'autoRun', 'speedRun', 'turboMode', 'viewDOM', 'transparentEx', 'breakOnFail',
'debuggerOnFail', 'observerMode'
], function (name) {
var value = me.getOption(name, onlyOwnProperties)
if (onlyOwnProperties) {
if (value !== undefined) state[ name ] = value
} else
state[ name ] = value
})
return state
},
getCheckedNodes : function () {
var checked = {}
this.testsStore.forEach(function (treeNode) {
if (treeNode.get('checked')) checked[treeNode.getId()] = 1
})
return checked
},
getCollapsedFolders : function () {
var collapsed = {}
this.testsStore.forEach(function (treeNode) {
if (!treeNode.isLeaf() && !treeNode.isExpanded()) collapsed[treeNode.getId()] = 1
})
return collapsed
},
applyState : function (state) {
var me = this
if (state) Joose.O.each(state, function (value, name) {
me.setOption(name, value)
})
},
getStateId : function () {
return 'test-run-' + this.title
},
loadState : function () {
var stateId = this.getStateId()
var state = Ext.state.Manager.get(stateId)
if (!state) return
if (!state.collapsedNodes) state.collapsedNodes = Ext.state.Manager.get(stateId + '-collapsed')
if (!state.selection) state.selection = Ext.state.Manager.get(stateId + '-selection')
return state
},
saveState : function () {
var stateId = this.getStateId()
var state = this.getState(true)
Ext.state.Manager.set(stateId + '-collapsed', state.collapsedNodes)
Ext.state.Manager.set(stateId + '-selection', state.selection)
delete state.collapsedNodes
delete state.selection
Ext.state.Manager.set(stateId, state)
},
uncheckAllExcept : function (testFile) {
var me = this
this.testsStore.forEach(function (node) {
if (node != testFile) me.setNodeChecked(node, false, true)
})
},
launchTest : function (testFile) {
if (this.isReadOnlyReport) return
var resultPanel = this.slots.resultPanel
var isLeaf = testFile instanceof Ext.data.Model ? testFile.data.leaf : true;
var descriptor = testFile instanceof Siesta.Test ? this.project.getScriptDescriptor(testFile) : testFile.get('descriptor');
// clear the content of the result panel when launching a single test
if (isLeaf) {
Ext.History.add(descriptor.url);
// assertions of the tests being launched will be cleared in the `onTestSuiteStart` method
resultPanel.setInitializing(true);
}
this.project.launch([ descriptor ])
},
updateStatusIndicator : function () {
// can remain neutral if all files are missing for example
// var isNeutral = true
// var allGreen = true
// var hasFailures = false
var totalPassed = 0
var totalFailed = 0
this.testsStore.forEach(function (testFileRecord) {
var test = testFileRecord.get('test')
// if there's at least one test - state is not neutral
if (test && test.isFinished()) {
// isNeutral = false
// allGreen = allGreen && test.isPassed()
// hasFailures = hasFailures || test.isFailed()
totalPassed += test.getPassCount()
totalFailed += test.getFailCount()
}
})
this.slots.filesTree.updateStatus(totalPassed, totalFailed);
},
<span id='global-method-runTest'> /**
</span> * Re-runs the latest executed test
*/
runTest : function () {
if (this.isReadOnlyReport) return
var toRun = this.slots.filesTree.getSelectionModel().getSelection()[0] ||
this.slots.resultPanel.test;
if (toRun) {
this.launchTest(toRun);
}
},
afterRender : function () {
this.callParent(arguments);
if (Ext.versions.extjs.isLessThan(this.expectedExtJSVersion) && window.console) {
console.log('Wrong Ext JS version detected.', 'Siesta expects that you use Ext JS version >= ' + this.expectedExtJSVersion + '. You may experience errors when using another version');
}
if (!this.project.isAutomated) setTimeout(Ext.Function.bind(this.deferredSetup, this), 1000);
},
deferredSetup : function() {
Ext.QuickTips && Ext.QuickTips.init();
if (this.enableVersionCheck && Siesta.Project.Browser.UI.VersionUpdateButton) {
new Siesta.Project.Browser.UI.VersionUpdateButton();
}
},
onManualCloseOfForcedIframe : function (test) {
var domContainer = this.down('domcontainer')
if (domContainer && domContainer.test == test) domContainer.alignIFrame(true)
}
})
//eof Siesta.Project.Browser.UI.Viewport
</pre>
</body>
</html>