Sunday, October 18, 2009

How To Run A Selenium Server With A Firefox Profile

Due to Firefox Certification issues each and every time you may need to accept the security certificate.
so you may feel the testing framework is not fully automate or accepting this security certificate each and every time is a really headache.

you have two options to get rid of this

1.use a valid certificate (you can not do this all the time) :)

2.ask selenium to run FF with a profile.

i'm going to tell how to do the option 2

1.create a Firefox profile (if u need help refer "" written by me).
2.start Firefox from the new profile and accept the security exception.(you will need to do this only once)
3. start Selenium server
java -jar selenium-server.jar -firefoxprofileTemplate
eg.
java -jar selenium-server.jar -firefoxprofileTemplate /home/darshana/newProfile

here newProfile is the location where i saved the new profile.

4.next time when you start the Selenium server, repeat only the 3 step..

have a nice time with testing ....

Wednesday, October 14, 2009

A Small Research on Selenium



I had a great curiosity to analyze how the time elapsed for a test varies with the speed. So I conclude a small research

Environment:

Notebook Asus X51RL

WSO2 Governance Registry 3.0.1

Test suite = Notification test

https://wso2.org/repos/wso2/trunk/commons/qa/web-test-framework/registry/src/test/java/org/wso2/carbon/web/test/registry/NotificationTest.java

This test does not require an Internet connection. So the elapsed time was totally depending on the performance of the hardware and governance server only. Every time I used a fresh instance. This test has 30 test cases and each time test errors and test failures were recorded.

No test failures and no test errors were observed.

The speed varying graph has the shape of y=mx+c. C is depending on the hardware and Greg server and even selenium server. M is roughly 144 s/speed unit in hundreds. I couldn’t test m is hardware independent or hardware dependent.

Programmers frequently use Thread.sleep() to eliminate errors and failures. So there is a constant delay . I measured it. I replace the Thread.sleep() with the Thread.sleep();System.out.println(); I found there is a constant over head of 417 s.


Thursday, October 8, 2009

Selenium Best Practices

Note:I used WSO2 Governance Registry as the example to describe.

1. If you really need to test the product don't think about the time needed to run the test unless the time is the most critical resource.
2. Reduce the dependency between functions (low coupling) as the
failure of a function should not affect to other functions.
e.g. if you add a collection in a function and if another function is going to use it. My advice is you should check the availability of the collection in the second function.
Your code should be able to handle that
3. Before writing a common function analyse the functionality what you are covering from that function and then code it.
Never write a common function without understanding the possible error messages those can occur during the execution.
Analyse all the error messages. Because you can't assure that there won't be any error message during the execution. So give the power to your function to handle it. My advice is to handle it in the common function.
Don't implement it in the test suite unless you are testing for that particular error message.
Write the common function return type as Boolean or Integer ..
I'll tell you the advantage. Have a look at this function

public boolean deleteResource(String path, String name) throws InterruptedException {
gotoBrowsePage(); // this will delete the registered prfile specially or if u want u can
// delete other folders also. eg path ="/system/users/" name ="admin"
Thread.sleep(1000);
int index = 0;
int a, b;
int id = 1;
String path1 = path;
if (!path.equals("/"))
path = path.concat("/");

do {
a = path.indexOf("/", index);
b = path.indexOf("/", a + 1);
if (a == -1 || b == -1)
break;
// System.out.println(path.substring(a+1,b));
id = getId(path.substring(a + 1, b));
if (id == -1)
return false;
else {

Thread.sleep(1000);
selenium.click("resourceView" + id);
Thread.sleep(4000);
}
index = b;

} while (a != -1 && b != -1);
id = getId(name);
if (id == -1)
return false;

Thread.sleep(5000);
selenium.click("actionLink" + id);
Thread.sleep(3000);

if (id == 1) {
selenium.click("link=Delete");
}
else {
selenium.click("//a[@onclick=\"hideOthers(" + id + ",'del');deleteResource('" + path + name + "', '" + path1 + "')\"]");
}
if (selenium.isTextPresent("Are you sure you want to delete ")) {
selenium.click("//button[@type='button']");
}
if (selenium.isTextPresent("Successfully deleted "))
selenium.click("//button[@type='button']");
return true;
}


If the user delete is success it will return true. Otherwise it will return false.
so if u need to verify that the user is deleted, use "assertTrue(deleUser(""))". And if u just need to delete this user, use "deleteUser("")"


3.1 Write a function even for a simple task.. eg. Click on the registry browser root icon.
You may need it anywhere else and if the developer team change the link name you will need to change only a single line. (Krishantha tought me this)
and when you writing a test try to identify the common functions which are available now and use them as much as possible.
Because those common functions are already tested.


4. Rather than using the Thread.sleep() use in built block "wait for". It will wait until the particular string, element is available.
It increases the dynamic of the function. But this has a draw back too.
Default wait time is 60 sec, that mean if there is an error occurred while executing this block, it will wait for 60 sec to say its an error.

eg; in GReg WSDL import function is fully depending one the Internet connection speed.
so some times it will take 10 s , some times it will take 1 min too.



5. Computer is a foolish servant but I will say selenium is a blind servant of that foolish servant
because sometimes though the link is there selenium wont identify it.
eg.
public void gotoSearchPage() throws InterruptedException {
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (selenium.isElementPresent("link=Search")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
selenium.click("link=Search");
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if ("Search".equals(selenium.getText("//div[@id='middle']/h2"))) break; } catch (Exception e) {}
Thread.sleep(1000);
}

}
You can consider this function as a fully dynamic function.

selenium will exit the first wait for block if the element present "link=Search". But some times it will say it no element called "link=Search". Because the element is there , but selenium may unable to use it
so put a simple thread sleep before the " selenium.click"

Thread.sleep(1000);
selenium.click("link=Search");

6. If can run the test suite at a lower speed, it may take more time. But it will reduce the number of errors and failures.

7. Running the whole test frame work at least once a day is a good habit because more and more you run, you can see the failures.

8. There is method in selenium selenium.setSpeed(String) from which you may reduce the time
public int countNotifications() throws InterruptedException {
int i = 1;
gotoNotificationPage();
Thread.sleep(1000);
if (selenium.isTextPresent("There are no subscriptions created at present"))
return 0;
while (selenium.isElementPresent("//table[@id='subscriptionsTable']/tbody/tr[" + i + "]/td[1]"))
i++;
return i - 1;

}

I can increase the execution speed when it executes inside the while loop, because it's Java part. For that you can change the code as follow
public int countNotifications() throws InterruptedException {
int i = 1;
String NewSpeed="20";
String CurrentSpeed="";
CurrentSpeed =selenium.getSpeed();
gotoNotificationPage();
Thread.sleep(1000);
if (selenium.isTextPresent("There are no subscriptions created at present"))
return 0;
selenium.setSpeed(NewSpeed);
while (selenium.isElementPresent("//table[@id='subscriptionsTable']/tbody/tr[" + i + "]/td[1]"))
i++;
selenium.setSpeed(Curspeed);
return i - 1;
}
This is something dangerous because if there is an error occurred while processing the "while" loop, your previous speed won't be restored. So the remaining tests will run at the speed "20".
This is some thing like using "goto" statement in a program. I am still working on this issue and I still cant find a good solution except one.
9. Before exit from the function/test class delete all the files you added and undo all the changes you made as much as you can.
But you can't undo rating a collection, filling the default profile.

Tuesday, October 6, 2009

How to Create a Firefox Custom Profile in Linux

Some cases you may need to run Firefox under different profile rather than it's default profile. So those are the steps to create a new profile.

1. Close all the instances of Firefox (close all the browser windows)
2. Open a terminal
3. Type "firefox -profilemanager" ( without "")
4. Then you will get a small window to configure your Firefox profiles



5. Click on the Create Profile button
6. Enter the new profile name and if you want you can save the new profile in a different location.For that click on the "choose folder" button.

7. Choose the folder and click "open" button


8. Now you finished creating a new Firefox profile.
9. If you don't want to launch the profile manager each startup of Firefox tick "Don't ask at startup". Otherwise It will open profile manager every time you open Firefox.