Get help with testing, discuss unit testing strategies etc.


Post by hygy »

Hi!

I created my first "bigger" test. Here is the code. Maybe somebody can use as an example. Or if I can do stg. better please feel free to share with me.

newRequest.js:
StartTest(function(t) {
    
    
    t.diag("Vacation request test");
    
    var endUser = "testuser01";
    var menuItem_xType = "vacationrequests";
    var vacationStartDate = "2014-11-03";
    var vacationEndDate = "2014-11-04";
    
    
    var vacationListRequestsGrid;
    
    t.chain(
        
        
        function (next) {
            t.login(endUser, next);
        },
        
        function (next) {
            t.selectMainMenuItemByXType(menuItem_xType, next);
        },
        
        function (next) {
            t.waitForViewportLoadMask(next);
        },

        { waitFor: 100 },
        
        { action: "click", target: ">>#vacationListsTab" },
        
        function (next) {
            
            Ext=this.Ext();
            
            vacationListRequestsGrid = t.cq('#vacationListRequestsGrid')[0]; // search for the grid
            vacationListRequestsGridStore = vacationListRequestsGrid.getStore(); // get the store
            
            var	_vacationStartDate=Ext.Date.parse(vacationStartDate,'Y-m-d');
            var _vacationEndDate=Ext.Date.parse(vacationEndDate,'Y-m-d');
            
            var recordIndex = vacationListRequestsGridStore.findBy( // search for the existing record
                function (record, id) {
                    if (Ext.Date.isEqual(record.get('FromDate'),_vacationStartDate) &&
                        Ext.Date.isEqual(record.get('ToDate'),_vacationEndDate)) {
                        return true; // a record with this data exists
                    }
                    return false; // there is no record in the store with this data
                }
            );
            
            if (recordIndex !== -1) {
                t.fail( 'The record is exist in the store. (startDate: '+vacationStartDate+', endDate: '+vacationEndDate+') Cannot start test.' );
                return false;
            }
            else
            {
                t.ok(!(recordIndex !== -1), 'The record not exist in the store. (startDate: '+vacationStartDate+', endDate: '+vacationEndDate+')');
            }
            
            next();
        },
        
        { action: "click", target: "#btnNewRequest => .x-btn-inner", desc: 'Clicked new request window' },
        
        { action: "click", target: "#firstDay => .x-form-text" },
        
        { action: "type", text: vacationStartDate + "[TAB]" }, // write start date
        
        { action: "type", text: vacationEndDate + "[TAB]" }, // write end date
        
        { action: "click", target: "form textareafield[name=Reason] => .x-form-text", offset: [82, 12] },
        
        { action: "type", text: "Siesta automatic test" },
        
        { action: "click", target: "#btnSave => .x-btn-inner", desc: 'Save started.' },
        
        function (next) { t.waitForViewportLoadMask(next); },

	    { action : "click", target : ".x-grid-row-selected .remove-icon", desc: 'Remove icon clicked in the grid action column.' },

	    function (next) { t.waitForViewportLoadMask(next); },

	    { action : "click", target : "#yes => .x-btn-icon-el" },

	    function (next) { t.waitForViewportLoadMask(next); },
        

        function (next) {
        	t.logout(next);
        }
       
    );  
    
});
Class: AppUtils.js for the common parts
Class('AttendanceTracking.Utils', {

    isa: Siesta.Test.ExtJS,

    methods: {

        login: function (user, next) {
            var me = this;

            this.chain(

                {
                    waitFor: 'selector',
                    args: '#btLogin',
                    timeout: 5000
                },


                {
                    action: 'type',
                    target: '>>field[name=tbAccount]',
                    text: user
                },
                {
                    action: 'click',
                    target: '#btLogin'
                },

                {
                    waitFor: 'pageLoad',
                    timeout: 5000
                },

                { waitFor: 'CQ', args: 'treepanel[itemId=mainMenu]', timeout: 3000, desc: 'Main menu successfully loaded. Logged in with: ' + user },

                { waitFor: 'rowsVisible', args: 'treepanel[itemId=mainMenu]', timeout: 3000 },

                next

            );
        },

        logout: function (next) {
            var me=this;

            this.chain(
                { action : "click", target : "#mainMenu => .x-grid-row:last-child() > .menuItem .x-tree-node-text", desc: 'Logged out.' }
            );

        },

        waitForViewportLoadMask: function(next)
        {
            var me=this;

            var maskDom=this.Ext().DomQuery.select('.x-mask-light');

            if (typeof(maskDom)!='undefined')
            {
                this.chain(

                    { waitFor: 'selectorNotFound', args: ['.x-mask-light'], timeout: 30000 },

                    next

                );                
            }
            else
            {
                this.chain(

                    { waitFor: 'selector', args: ['.x-mask-light'] },

                    { waitFor: 'selectorNotFound', args: ['.x-mask-light'], timeout: 30000 },

                    next

                );                
            }


        },

        selectMainMenuItemByXType: function(menuItem_xType, next)
        {
            var me=this;

            this.chain(

                { waitFor: 300 },

                function(next, grids) {

                    var treePanel=this.cq('#mainMenu')[0];

                    var rootNode=treePanel.getStore().getRootNode();

                    var node = rootNode.findChildBy(function(n) {
                        if (n.raw.menuHandlerParameters) {
                            var menuHandlerParameters=this.global.Ext.decode(n.raw.menuHandlerParameters);
                            var foundMenuItem=menuHandlerParameters.view.xtype==menuItem_xType;
                            return foundMenuItem;
                        }
                    }, this, true);

                    treePanel.selectPath(node.getPath());

                    next();
                },

                { action : "click", target : "#mainMenu => .x-grid-row-selected", desc: 'Selected menu item. ('+menuItem_xType+')' },

                next

            );
        }
    }
});

Post by mats »

        { waitFor: 100 },
Reason for this? Always try to wait for a **condition** not some special number of milliseconds. Test will fail sporadically if the browser is under high load.

Post by hygy »

The original reason for this: there is some times the loadmask appiered and dissapiered to fast and the waitForViewportLoadMask always waited (I modified it ever since), so I try to remove this, thanks.
mats wrote:
        { waitFor: 100 },
Reason for this? Always try to wait for a **condition** not some special number of milliseconds. Test will fail sporadically if the browser is under high load.

Post by hygy »

How can I insert a general rule to this (or any) chain, whenever a css class appiers on the screan (generic error window) then the test fail?

Post by mats »

Hmm, don't understand you completely - can you elaborate?

Post by hygy »

So, while running a test there is many assinc communication running on the system. So If anything goes wrong, an error window is appiering. So I need to check after every chain action to test this window exists, or if I can somehow run a background task what always check this error window this will be helpfull.

So stg like that:

t.chain(
  { waitFor: 'componentQuery', args: 'errorwindow' }
  // wait for error window is appiers while the test is running,
 // if the test is finised this needs to be finished too
);

t.chain(
 // start normal tests
);

Post by nickolay »

Well, its just a code - if you need to periodically check for the absence of some component - just do it in the "setInterval" function or insert a check after every step or something like that. Don't forget to stop the "setInterval" once the test completes.

Post Reply