Sunday, September 12, 2010

Distribute your test suites by STAF(STAX)

STAF is a good Open source "test automation" framework which developed by IBM. I am currently using STAF(STAX) to distribute my test Suites which are organized by TestNG, it is improve your efficiency.

Here is a simple sample how I zip, transfer and execute My Test on 2 machines(please format this XML by yourself, if you need to look at it):

 <?xml version="1.0" encoding="UTF-8" standalone="no"?>  
 <!DOCTYPE stax SYSTEM "stax.dtd">  
 <!-- New document created with EditiX at Fri Jul 09 15:35:49 CST 2010 -->  
 <stax>  
 <script>machinelist = ['Machinename1','Machinename2']</script>  
 <defaultcall function="ZipTest"></defaultcall>  
 <function name="ZipTest">  
 <sequence>  
 <stafcmd>  
 <location>'localhost'</location>  
 <service>'zip'</service>  
 <request>'ADD ZIPFILE D:/Raft_Project/TestPlan.zip DIRECTORY D:/Raft_Project/TestPlan RECURSE RELATIVETO D:/Raft_Project' </request>  
 </stafcmd>  
 <call function="'sleep'"></call>  
 <call function="'DistributionTest'"></call>  
 <call function="'sleep'"></call>  
 <call function="'CleanupTest'"></call>  
 </sequence>  
 </function>  
 <function name="DistributionTest">  
 <paralleliterate var="machinename" in="machinelist">  
 <sequence>  
 <stafcmd>  
 <location>machinename</location>  
 <service>'fs'</service>  
 <request>'DELETE ENTRY D:/Raft_Project/TestPlan RECURSE CONFIRM' </request>  
 </stafcmd>  
 <call function="'sleep'"></call>  
 <stafcmd>  
 <location>'local'</location>  
 <service>'fs'</service>  
 <request>'COPY FILE D:/Raft_Project/TestPlan.zip TODIRECTORY D:/Raft_Project/ TOMACHINE %s' % machinename </request>  
 </stafcmd>  
 <call function="'sleep'"></call>  
 <stafcmd>  
 <location>machinename</location>  
 <service>'zip'</service>  
 <request>'UNZIP ZIPFILE D:/Raft_Project/TestPlan.zip TODIRECTORY D:/Raft_Project/'</request>  
 </stafcmd>  
 <call function="'sleep'"></call>  
 <stafcmd>  
 <location>machinename</location>  
 <service>'fs'</service>  
 <request>'DELETE ENTRY D:/Raft_Project/TestPlan.zip RECURSE CONFIRM'</request>  
 </stafcmd>  
 <process>  
 <location>machinename</location>  
 <command mode='"shell"'>'Runner.bat'</command>  
 <workdir>R'D:\Raft_Project\TestPlan\TestRunner_Module1'</workdir>  
 <returnstdout/>  
 <returnstderr/>  
 </process>  
 </sequence>  
 </paralleliterate>  
 </function>  
 <function name="CleanupTest">  
 <stafcmd>  
 <location>'localhost'</location>  
 <service>'fs'</service>  
 <request>'DELETE ENTRY D:/Raft_Project/TestPlan.zip RECURSE CONFIRM'</request>  
 </stafcmd>  
 </function>  
 <function name="sleep">  
 <stafcmd>  
 <location>'localhost'</location>  
 <service>'delay'</service>  
 <request>'delay 6000'</request>  
 </stafcmd>  
 </function>  
 </stax>  
hope it helps! More detail instruction, please go to STAF official website:http://staf.sourceforge.net/

PS: you may need to modify your under STAF/bin/, so that it can avoid some restrictions.
 # Turn on tracing of internal errors and deprecated options  
 trace enable tracepoints "error deprecated"  
 # Enable TCP/IP connections  
 interface ssl library STAFTCP option Secure=Yes option Port=6550  
 interface tcp library STAFTCP option Secure=No option Port=6500  
 # Set default local trust  
 #trust machine local://local level 5  
 trust default level 5  
 # Add default service loader  
 serviceloader library STAFDSLS  
 SERVICE STAX LIBRARY JSTAF EXECUTE \  
 D:/STAF/services/stax/STAX.jar OPTION J2=-Xmx384m  
 SERVICE EVENT LIBRARY JSTAF EXECUTE \  
 D:/STAF/services/stax/STAFEvent.jar  
 SET MAXQUEUESIZE 10000  
 SERVICE Cron LIBRARY JSTAF EXECUTE D:\STAF\services\cron\STAFCron.jar  

WebDriver Wait is easier after using implicitlyWait()

"WebDriver will wait until the page has fully loaded (that is, the "onload" event has fired) before returning control to your test or script."
The classic example is Javascript starting to run after the page has loaded (onload); while if the website is very "rich", it is always hard for WebDriver to identify some elements by its own blocking API.

Previous solution mentioned/suggested by experts are : Use the Wait class to wait for a specific element to appear:http://groups.google.com/group/webdriver/browse_thread/thread/50c963cd25fb416c/61aae67b8a2560fd?#61aae67b8a2560fd

Here is one example, which i wrapped the presenceOfElementLocated():

 import org.openqa.selenium.By;  
 import org.openqa.selenium.WebDriver;  
 import org.openqa.selenium.WebElement;  
 import org.openqa.selenium.support.ui.WebDriverWait;  
 import com.google.common.base.Function;  
 public class MyWaiter {  
      private WebDriver driver;  
      public MyWaiter(WebDriver driver){  
           this.driver = driver;  
      }  
      public WebElement waitForMe(By locatorname, int timeout){  
           WebDriverWait wait = new WebDriverWait(driver, timeout);  
           return wait.until(MyWaiter.presenceOfElementLocated(locatorname));  
      }  
      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {  
           // TODO Auto-generated method stub  
           return new Function<WebDriver, WebElement>() {  
                @Override  
                public WebElement apply(WebDriver driver) {  
                     return driver.findElement(locator);  
                }  
           };  
      }  
 }  

My test code:
 public static void main(String[] args) {  
           WebDriver driver = new FirefoxDriver();  
           driver.get("http://www.google.com/");  
           MyWaiter myWaiter = new MyWaiter(driver);  
           WebElement search = myWaiter.waitForMe(By.name("btnG"), 10);  
           search.click();  
      }  

This way looks a little bit fussy to me, although it works well.

Now, implicitlyWait() gives tests a "KISS" and most importantly, it did solve the problem.

driver.findElement(By.id("signIn")).click();  
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);  
driver.switchTo().frame("canvas_frame");  
driver.findElement(By.partialLinkText("Buzz")).click();  
driver.findElement(By.linkText("Cheng Chi")).click();  


You may notice that the first sample code using wait.until(), you have to two wait.until() for each link element, otherwise the code will fail; While the second one, you just add one implicitlyWait() in front of the "Buzz" link.
I do not know why, but it shows that implicitlyWait() is a better choice for locating (ajax) elements.

PS: I marked "in front of" as bold above, which means implicitlyWait() is a kind of registration method, you need to tell Webdriver in advance.

Thursday, September 02, 2010

Check and Set Isolation level in SQL Server

Check isolation level:
DBCC useroptions


Default Isolation level in SQL Server is "READ COMMITTED", Once you want to change it:

For example, Set isolation level to READ UNCOMMITTED
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Wednesday, September 01, 2010

Switching Frame and Windows in WebDriver sample code

1> Switch to different Frames:
 List<WebElement> frameset = driver.findElements(By.tagName("frame"));  
 if(frameset.size()>0) {  
 for (WebElement framename : frameset){  
 System.out.println("frameid: " + framename.getAttribute("name"));  
 }  
 }  
 else System.out.println("can not find any frame in HTML");  

Notice when you set the frame index, it starts with 0 for the first frame:
 driver.switchTo().frame(0);  


2> Switch to different Windows:
 Set<string> handlers = driver.getWindowHandles();  
 if (driver.getWindowHandles().size()>= 1){  
 for(String handler : handlers){  
 driver.switchTo().window(handler);  
 if (driver.getCurrentUrl().contains("Popup")){  
 System.out.println("Get focus on Popup window");  
 break;  
 }  
 }  
 }  
 else System.out.println("No windows founded!");  


Writing a common function based you own app for switching will be more helpful for your Code Clean!

Thursday, August 12, 2010

The image makes me feel exciting to fight against!

Typical memory leak pattern taking from VisualVM:

Wednesday, August 11, 2010

Deal with Javascript alert( ) and confrim( ) in WebDriver, as workaround

I posted one blog about Deal with "JS div DialogPane in WebDriver":
http://joychester.blogspot.com/2010/07/js-alert-handling-with-webdriver.html

Currently I met more dialog on different kind of page to deal with

<1> Javascript alert(msg)::
Most of time, I meet this situation when there is a validation on Front end. If you have to deal with this situation, one way to disable alert, before you click on a button which trigger the alert(), so that alert will not be triggered, while the validation always be there:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.alert = function(msg){};");

button.click();



<2> Javascript confrim(msg):
Here I will post an example how to simulate pressing "OK" button to deal with confirmation dialog.
First, find out the JavaScript which is sending a confirmation message by sniffer tool:

confirmed = confirm("Warning! This account is currently in use. Would you like to continue to login?");
if (confirmed)
{
this.document.forms[0].submitAction.value = "TERMINATE";
this.document.forms[0].submit();
}
else
{
this.document.forms[0].submitAction.value = "ABORT";
this.document.forms[0].submit();
}

function doSubmit(url, submitAction){

document.forms[0].action = url;
document.forms[0].target = "_self";
document.forms[0].submitAction.value = submitAction;
document.forms[0].submit();
}


Then, you may need to execute such bellowing javascript to simulate pressing "OK" button:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:doSubmit('/app/login.do','TERMINATE');");


instead of simple click() which will trigger the confirmation dialog:

login.click();


<3> The easiest Walkround:
I like the post on the Watir Wiki, which introduce "the Simplest way to stop JavaScript Pop Ups", the idea can be borrowed from that:
http://wiki.openqa.org/display/WTR/JavaScript+Pop+Ups
Hope this helpful!

Update:
WebDriver-Beta1 will have an implementation of the Alerts and Prompts API for the FirefoxDriver :)

Monday, August 02, 2010

calculate performance by datediff() and aggregation() functions

As we store Raw data in our Database, which just history record without any calculation, just log start timestamp and end timestamp of each action/method. So here is a sample on how to calculate performance by datediff() and aggregation() functions:

declare @starttime varchar(50)

declare @endtime varchar(50)

set @starttime='03/08/2010 10:25:00.000'
set @endtime='03/08/2010 12:00:00.000'

select count(*), avg(datediff(millisecond,starttime, endtime)), min(datediff(millisecond,starttime, endtime)), max(datediff(millisecond,starttime, endtime))
from statistics_log
where event_type='send' and starttime > @starttime and starttime < @endtime

Thursday, July 22, 2010

Deal with JS div DialogPane in WebDriver

Updated: Another related post on js alert and confirmation stuff on http://joychester.blogspot.com/2010/08/deal-with-javascript-alert-and-confrim.html

During my testing, I met one "Send" link which will trigger js DialogPane to get your confirmation, such "OK" or "Cancel", onclick will execute JavaScript function like this for "OK" :

onclick="confirmSend()"

Here is a sample code how I simulate clicking "OK" within the js DialogPane:

driver.switchTo().activeElement();
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("confirmSend()");


Thanks for Shawn's Demo code, she gives me really great suggestion and inspiration!! :)

“Raft” Logo

Friday, July 16, 2010

Take screen shot on WebDriver

Simple code on take screen shot on WebDriver(InternetExplorerDriver,FirefoxDriver and ChromeDriver):

FirefoxDriver driver = new FirefoxDriver();
....
File pngFile = new File("D:\\test\\", "shot.png");
File tmpFile = driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(tmpFile, pngFile);