Wednesday, July 30, 2014

ScrollDown utility - Selenium Webdriver

Scroll Down Utility

Step 1: 
Create a method scrollDown

public void scrollDown(int iter) throws InterruptedException{
JavascriptExecutor jse = (JavascriptExecutor)driver;
for(int i = 1;i<=iter;i++){
Thread.sleep(1000);
jse.executeScript("window.scrollBy(0,3000)", "");
Thread.sleep(1000);
}

}

Step 2: 
Call the method when ever you want to scroll.
scrollDown(1);



Archive Test Results after every run

Save the below script as archive_utility.vbs and add this in startup
'archive utility - Created on 24 -August-2012 by k.s.karthikeyan@gmail.com
Dim objFSO
strFilename = "emailable-report"
strExtn = ".html"
strFilename2 = "testng-failed"
strExtn2 = ".xml"
strSourceFolder = "c:\ebox\Karthik\2\MyProject\test-output"
'strSourceFolder1 = Replace(strSourceFolder,"\","\\\\")
'Wscript.echo strSourceFolder1
strDestFolder = "c:\Documents and Settings\ksankarappan\Desktop\archive\"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & _
        strComputer & "\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
    ("Select * From __InstanceCreationEvent Within 5 Where " _
    & "Targetinstance Isa 'CIM_DirectoryContainsFile' and " _
    & "TargetInstance.GroupComponent= " _
    & "'Win32_Directory.Name=""c:\\\\ebox\\\\Karthik\\\\2\\\\MyProject\\\\test-output""'")
Do
    Set objLatestEvent = colMonitoredEvents.NextEvent
    temp = objLatestEvent.TargetInstance.PartComponent
   temp = Replace(Mid(temp, InStr(temp, Chr(34)) + 1), "\\", "\")
    temp = Left(temp, Len(temp) - 1)
Wscript.Echo temp
Wscript.Echo strSourceFolder & "\" & strFilename2 & strExtn
    if temp = strSourceFolder & "\" & strFilename & strExtn Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Today = "_" + Replace(Date, "/", "_") + "_" + Replace(FormatDateTime(Time, 3), ":","_")
 
objFSO.MoveFile strSourceFolder & "\" & strFilename & strExtn, strDestFolder & strFilename & Today & strExtn
'Wscript.echo "Emailable-Report.html is moved to the path : " & strDestFolder
    End If
    if temp = strSourceFolder & "\" & strFilename2 & strExtn2 Then
Set objFSO2 = CreateObject("Scripting.FileSystemObject")
Today = "_" + Replace(Date, "/", "_") + "_" + Replace(FormatDateTime(Time, 3), ":","_")
 
objFSO2.MoveFile strSourceFolder & "\" & strFilename2 & strExtn2, strDestFolder & strFilename2 & Today & strExtn2
'Wscript.echo "testng-failed.xml is moved to the path : " & strDestFolder
    End If
Loop

Tuesday, July 29, 2014

Alternative of Selenium Webdriver's drag and drop

At times, I felt Webdriver's drag and drop doesn't make us happy. I found an alternative which helps to perform drag and drop without any hustle. Just follow these 3 steps to make your test case working :)


Step 1: Save this below code in your build location and name it as "drag_and_drop_helper2.js"

(function( $ ) {

    var rkeyEvent = /^key/,
        rmouseEvent = /^(?:mouse|contextmenu)|click*/,
        rdndEvent = /^drag*|drop*/;

    $.fn.simulate = function( type, options ) {
        return this.each(function() {
            new $.simulate( this, type, options );
        });
    };

    $.simulate = function( elem, type, options ) {
        var method = $.camelCase( "simulate-" + type );

        this.target = elem;
        this.options = options;

        if ( this[ method ] ) {
            this[ method ]();
        } else {
            this.simulateEvent( elem, type, options );
        }
    };

    $.extend( $.simulate.prototype, {
        simulateEvent: function( elem, type, options ) {
            var event = this.createEvent( type, options );
            this.dispatchEvent( elem, type, event, options );

            if(type == "dragstart"){
                console.log("dragstart dropTarget: " + options.dropTarget
                )
            }

            if(type == "dragstart" && options.dropTarget){
                this._performDND(event, options);
            }
            var message = "simulated event " + type + " on " + elem.id;
            console.log(message);
        },

        _performDND: function(event, options){
            console.log("performing dnd, dropping on " + options.dropTarget.id)
            var dropEvent = this.createEvent("drop", {});
            dropEvent.dataTransfer = event.dataTransfer;
            this.dispatchEvent($(options.dropTarget)[0], "drop", dropEvent, {});
        },

        createEvent: function( type, options ) {
            if ( rkeyEvent.test( type ) ) {
                return this.keyEvent( type, options );
            }
            if(rmouseEvent.test(type)){
                return this.mouseEvent( type, options );
            }
            if(rdndEvent.test(type)){
                return this.dndEvent( type, options );
            }
        },

        dndEvent: function(type, options, dataTransfer){
            var event = document.createEvent("CustomEvent");
            event.initCustomEvent(type, true, true, null);
            event.dataTransfer = {
                data: {
                },
                setData: function(type, val){
                    this.data[type] = val;
                },
                getData: function(type){
                    return this.data[type];
                }
            };
            return event;
        },

        mouseEvent: function( type, options ) {
            var event, eventDoc, doc, body;
            options = $.extend({
                bubbles: true,
                cancelable: (type !== "mousemove"),
                view: window,
                detail: 0,
                screenX: 0,
                screenY: 0,
                // TODO: default clientX/Y to a position within the target element
                clientX: 1,
                clientY: 1,
                ctrlKey: false,
                altKey: false,
                shiftKey: false,
                metaKey: false,
                button: 0,
                relatedTarget: undefined
            }, options );

            if ( document.createEvent ) {
                event = document.createEvent( "MouseEvents" );
                event.initMouseEvent( type, options.bubbles, options.cancelable,
                    options.view, options.detail,
                    options.screenX, options.screenY, options.clientX, options.clientY,
                    options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
                    options.button, options.relatedTarget || document.body.parentNode );
                // IE 9+ creates events with pageX and pageY set to 0.
                // Trying to modify the properties throws an error,
                // so we define getters to return the correct values.
                if ( event.pageX === 0 && event.pageY === 0 && Object.defineProperty ) {
                    eventDoc = event.relatedTarget.ownerDocument || document;
                    doc = eventDoc.documentElement;
                    body = eventDoc.body;

                    Object.defineProperty( event, "pageX", {
                        get: function() {
                            return options.clientX +
                                ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
                                ( doc && doc.clientLeft || body && body.clientLeft || 0 );
                        }
                    });
                    Object.defineProperty( event, "pageY", {
                        get: function() {
                            return options.clientY +
                                ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
                                ( doc && doc.clientTop || body && body.clientTop || 0 );
                        }
                    });
                }
            } else if ( document.createEventObject ) {
                event = document.createEventObject();
                $.extend( event, options );
                // TODO: what is this mapping for?
                event.button = { 0:1, 1:4, 2:2 }[ event.button ] || event.button;
            }

            return event;
        },

        keyEvent: function( type, options ) {
            var event;
            options = $.extend({
                bubbles: true,
                cancelable: true,
                view: window,
                ctrlKey: false,
                altKey: false,
                shiftKey: false,
                metaKey: false,
                keyCode: 0,
                charCode: undefined
            }, options );

            if ( document.createEvent ) {
                try {
                    event = document.createEvent( "KeyEvents" );
                    event.initKeyEvent( type, options.bubbles, options.cancelable, options.view,
                        options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
                        options.keyCode, options.charCode );
                    // TODO: what is this supporting?
                } catch( err ) {
                    event = document.createEvent( "Events" );
                    event.initEvent( type, options.bubbles, options.cancelable );
                    $.extend( event, {
                        view: options.view,
                        ctrlKey: options.ctrlKey,
                        altKey: options.altKey,
                        shiftKey: options.shiftKey,
                        metaKey: options.metaKey,
                        keyCode: options.keyCode,
                        charCode: options.charCode
                    });
                }
            } else if ( document.createEventObject ) {
                event = document.createEventObject();
                $.extend( event, options );
            }

            // TODO: can we hook into core's logic?
            if ( $.browser.msie || $.browser.opera ) {
                // TODO: is charCode ever <0 ? Can we just use charCode || keyCode?
                event.keyCode = (options.charCode > 0) ? options.charCode : options.keyCode;
                event.charCode = undefined;
            }

            return event;
        },

        // TODO: does this need type? Can't we just check event.type?
        dispatchEvent: function( elem, type, event ) {
            if ( elem.dispatchEvent ) {
                elem.dispatchEvent( event );
            } else if ( elem.fireEvent ) {
                elem.fireEvent( "on" + type, event );
            }
        },

        simulateFocus: function() {
            var focusinEvent,
                triggered = false,
                element = $( this.target );

            function trigger() {
                triggered = true;
            }

            element.bind( "focus", trigger );
            element[ 0 ].focus();

            if ( !triggered ) {
                focusinEvent = $.Event( "focusin" );
                focusinEvent.preventDefault();
                element.trigger( focusinEvent );
                element.triggerHandler( "focus" );
            }
            element.unbind( "focus", trigger );
        },

        simulateBlur: function() {
            var focusoutEvent,
                triggered = false,
                element = $( this.target );

            function trigger() {
                triggered = true;
            }

            element.bind( "blur", trigger );
            element[ 0 ].blur();

            // blur events are async in IE
            setTimeout(function() {
                // IE won't let the blur occur if the window is inactive
                if ( element[ 0 ].ownerDocument.activeElement === element[ 0 ] ) {
                    element[ 0 ].ownerDocument.body.focus();
                }

                // Firefox won't trigger events if the window is inactive
                // IE doesn't trigger events if we had to manually focus the body
                if ( !triggered ) {
                    focusoutEvent = $.Event( "focusout" );
                    focusoutEvent.preventDefault();
                    element.trigger( focusoutEvent );
                    element.triggerHandler( "blur" );
                }
                element.unbind( "blur", trigger );
            }, 1 );
        }
    });



    /** complex events **/

    function findCenter( elem ) {
        var offset,
            document = $( elem.ownerDocument );
        elem = $( elem );
        offset = elem.offset();

        return {
            x: offset.left + elem.outerWidth() / 2 - document.scrollLeft(),
            y: offset.top + elem.outerHeight() / 2 - document.scrollTop()
        };
    }

    $.extend( $.simulate.prototype, {
        simulateDrag: function() {
            var target = this.target,
                options = this.options,
                center = findCenter( target ),
                x = Math.floor( center.x ),
                y = Math.floor( center.y ),
                dx = options.dx || 0,
                dy = options.dy || 0,
                target = this.target,
                coord = { clientX: x, clientY: y , dropTarget: options.dropTarget || undefined };

            console.log("simulateDrag of " + target.id +
                " from {" + coord.clientX + ", " + coord.clientY + "} " +
                "by {" + dx + ", " + dy + "}" );

            this.simulateEvent( target, "dragstart", coord );
            coord = { clientX: x + 1, clientY: y + 1 };
            this.simulateEvent( document, "mousemove", coord );
            coord = { clientX: x + dx, clientY: y + dy };
            this.simulateEvent( document, "mousemove", coord );
            this.simulateEvent( document, "mousemove", coord );
            this.simulateEvent( target, "mouseup", coord );
            this.simulateEvent( target, "dragend", coord );
        }
    });

})( jQuery );



Step 2: Add this method drag_and_drop_js . Change the path you just saved the helper file

private void drag_and_drop_js(WebElement source ,WebElement target){
         
         try {
                   
            String js_filepath =               System.getProperty("user.dir")+"/src/test/resources/drag_and_drop_helper2.js";   // Change the path here               
                   
                   String java_script="";
                   String text;

                   BufferedReader input = new BufferedReader(new FileReader(js_filepath));
                   StringBuffer buffer = new StringBuffer();

                   while ((text = input.readLine()) != null)
                       buffer.append(text + "\n");
                       java_script = buffer.toString();

                   input.close();

                         String load_jquery = "var jqueryUrl = \"http://code.jquery.com/jquery-2.1.1.min.js\";\n"
                                        + "var scriptElt = document.createElement('script');\n"
                                        + "scriptElt.type = 'text/javascript';\n"
                                        + "scriptElt.src = jqueryUrl;\n"
                                        + "scriptElt.src = jqueryUrl;\n"
                                        + "document.getElementsByTagName('head')[0].appendChild(scriptElt);";

   
                   JavascriptExecutor js = (JavascriptExecutor) driver;
                   driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
                   
                   String drag_drop_script = "jQuery(arguments[0]).simulate('drag', { dropTarget: arguments[1] });";
                   Object o1 = js.executeScript(load_jquery);
                   Object o2 = js.executeScript(java_script);
                   Object o3 = js.executeScript(drag_drop_script,source,target);
                                 
         } catch (Exception e) {
             
                 System.out.println("Error :" + e.toString());
           }
         
        } 

Step 3: Get the source and destination elements, and your are done.

WebElement from = driver.findElement(By.xxxx("xxxx"));
WebElement to = driver.findElement(By.xxxx("xxxx"));
from.click();

drag_and_drop_js(from,to);


Happy Testing!!!