Monday, November 29, 2010

How to pass parameters to JUNIT or TestNG test case.

You can parametrize your test cases using excel sheet. With the help you TestNG we can pass different set of data to our test cases by following steps

1. create a data file excel rename column as username and fill below data like


username
test1
test2
test3
test4


2. create a dsn through control pannel--> administrative tool--> Data source (ODBC) --> select system dsn --> click add
then select "dirver do microsoft excel" select workbook your data file which you created above.

now your data source and provider is ready now connect this in your test cases using java class for

Class.forName("sun.jdbc.odbc.
JdbcOdbcDriver");


3. Write the test cases


import org.openqa.selenium.server.RemoteControlConfiguration;
import com.thoughtworks.selenium.*;
import org.openqa.selenium.server.*;
import org.testng.annotations.*;
public class TestExcel extends SeleneseTestBase {
@BeforeClass
public void setUp()throws Exception{

RemoteControlConfiguration rc = new RemoteControlConfiguration();
rc.trustAllSSLCertificates();
seleniumServer = new SeleniumServer(rc);
selenium = new DefaultSelenium("localhost",4444,"*iexplore","http://www.yahoo.com");
seleniumServer.start();
selenium.start();
}
@Test
public void testread()throws Exception{
// Connection connection = null;


try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection( "jdbc:odbc:nk" );
// Connection con = DriverManager.getConnection( "jdbc:odbc:nk" ); here you write your driver which you created using ODBC connecting excel workbook.

Statement st = con.createStatement();
ResultSet rs = st.executeQuery( "Select * from [Sheet1$]" );

ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();

while (rs.next()) {

for (int i = 1; i <= numberOfColumns; i++) {
if (i > 1) System.out.print(", ");
String columnValue = rs.getString(i);
System.out.print(columnValue);
selenium.open("/");

pause(5000);
selenium.click("link=Sign in");
selenium.waitForPageToLoad("30000");


try {
if (selenium.isElementPresent("//a[@id='overridelink']"))
selenium.click("//a[@id='overridelink']");
}
catch (Exception e) {}
pause(30000);
selenium.type("userid", columnValue);
selenium.type("pass","password");
selenium.click("//button[@class='bfbt' and @type='submit']");
pause(8000);
String wc = selenium.getTable("//div[@id='dynamicmenu-hdrCtr']/table[1].0.1");
System.out.print(wc);

selenium.click("link=Sign out");
selenium.waitForPageToLoad("20000");
selenium.isTextPresent("Welcome!");

}
System.out.println("");

}

st.close();
con.close();

} catch(Exception ex) {
System.err.print("Exception: ");
System.err.println(ex.getMessage());
}
}
}

How to setup Selenium RC with TestNG in eclipse

TestNG Annotation

@BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run.

@AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the tag have run.

@BeforeClass: The annotated method will be run before the first test method in the current class is invoked.

@AfterClass: The annotated method will be run after all the test methods in the current class have been run.

@Parameters: Describes how to pass parameters to a @Test method.


Test case

goolgesearch.java


import org.openqa.selenium.server.RemoteControlConfiguration;
import org.openqa.selenium.server.SeleniumServer;
import org.testng.annotations.*;
import com.thoughtworks.selenium.*;

public class googlesearch extends SeleneseTestCase{

Selenium selenium;
public static final String MAX_WAIT_TIME_IN_MS="60000";
private SeleniumServer seleniumServer;


@BeforeClass
@Parameters({"selenium.host","selenium.port","selenium.browser","selenium.url"})
public void setUp(String host, String port, String browser , String url ) throws Exception {
RemoteControlConfiguration rc = new RemoteControlConfiguration();

rc.setSingleWindow(true);

seleniumServer = new SeleniumServer(rc);
selenium = new DefaultSelenium(host, Integer.parseInt(port), browser, url);
seleniumServer.start();
selenium.start();

}

@Test
@Parameters({"search","expected"})
public void googling(String search, String expected) {
selenium.open("/");
selenium.waitForPageToLoad("6000");
selenium.type("q", search);
selenium.click("btnG");
selenium.waitForPageToLoad(MAX_WAIT_TIME_IN_MS);
assertTrue(selenium.isTextPresent(expected));

}
@AfterTest
public void tearDown() throws InterruptedException{
selenium.stop();
seleniumServer.stop();

}
}

# Install TestNG plug-in in your eclipse.
# Set the java build path and pointing to RC sever.
Go to Java project and right click on it then select properties then select java build path then select library tab and select external jar pointing you selenium RC server.
# Run the test case as TestNG test suite.
Go to googlesearch.java page right click on the page the click on Run as... and select the suite in the dialog box which you created above.

How to upload a file in selenium

How to upload a file in selenium with the help of AutoIT

Recently, I had the challenge of writing some automation for a workflow which included uploading a file because uloading a file works on windows component.
selenium is unable to access windows components and it will be handled through AutoIT.
Once you are able to click on browse button and a dialog box is open to choose the file then you just run a AutoIT script which will help to select the file from your local or remote drive and control will come to your web page to proceed with selenium.

Step to choose a file from your local or remote drive

Step 1.

Download the AutoIT and intall it.

Download AutoIT from its homepage

step 2.

write a AutoIT script to choose a file from your local or remote drive.


#include
; Internet Explorer is partly integrated in shell.application
$oShell = ObjCreate("shell.application") ; Get the Windows Shell Object
$oShellWindows=$oShell.windows ; Get the collection of open shell Windows
$MyIExplorer=""
for $Window in $oShellWindows ; Count all existing shell windows
; Note: Internet Explorer appends a slash to the URL in it's window name
if StringInStr($Window.LocationURL,"http://") then
$MyIExplorer=$Window
exitloop
endif
next
$oForm = _IEGetObjByName ($MyIExplorer, "UploadedFile")
_IEAction($oForm, "click")
WinActivate("Choose file");
Local $file = "C:\Documents and Settings\intelizen\Desktop\selenium.txt"
ControlSetText("Choose file", "", "Edit1", $file )
ControlClick("Choose file", "", "Button2")

setp 3.

Complie AutoIT script and make exe of that script.

Right click on that saved script file and click on "Compile script" from context menu. This will make an exe file of that script.


setp 4.

Call that exe in selenium.

Process proc = Runtime.getRuntime().exec("C:\\farheen\\FileUpload.exe");

If you want to test this script then just download the script exe file and click on browse button on web page and run this exe file. Just make sure you have your file in correct path by changing this line of script in the second step
Local $file = "c:\yourpath\howtoupload.doc"
in above line of script change your file path then make exe of your script then click on browse button on your web page then run this exe . I am sure this would work.

Above script work for Firefox.Below for IE.

#include
; Internet Explorer is partly integrated in shell.application
$oShell = ObjCreate("shell.application") ; Get the Windows Shell Object
$oShellWindows=$oShell.windows ; Get the collection of open shell Windows
$MyIExplorer=""
for $Window in $oShellWindows ; Count all existing shell windows
; Note: Internet Explorer appends a slash to the URL in it's window name
if StringInStr($Window.LocationURL,"http://") then
$MyIExplorer=$Window
exitloop
endif
next
$oForm = _IEGetObjByName ($MyIExplorer, "UploadedFile")
_IEAction($oForm, "click")

WinActivate("File Upload");
Local $file = "c:\yourpath\howtoupload.doc"
ControlSetText("File Upload", "", "Edit1", $file )
ControlClick("File Upload", "", "Button2")

In above script you might need to change your file path and browse button name and the title of you dialog box.

How to locate an element based on their label in selenium

Some time it difficult to locate an element usiing DOM, HTML and xpath. In that case we use to locate the element with the
help of their lables.

For example : Go to yahoo login page


selenium.open("https://login.yahoo.com");

Based on the lable "Yahoo ! ID" we will read the text box and type in.

selenium.type("css=label:contains(\"Yahoo! ID\")+input", "farheen");

Based on the lable "Password" we will locate the text box for password and type in.

selenium.type("css=label:contains(\"Password\")+input", "pass");

Go to yahoo registrantion page.


selenium.open("https://edit.yahoo.com/registration?.intl=us");

Based on Name label we will type in First Name text box.

selenium.type("css=label:contains(\"Name\")+div>input", "farheen");

Based on Name label we will type in Last name text box.

selenium.type("css=label:contains(\"Name\")+div>input+input", "khan");

Based on Gender lable we will select the gender from drop down.

selenium.select("css=label:contains(\"Gender\")+div>select", "label=Male");

Based on Birthday lable we will select the month from drop down.

selenium.select("css=label:contains(\"Birthday\")+div>select", "label=January");

Based on Birthday lable we will type the date in date text box.

selenium.type("css=label:contains(\"Birthday\")+div>select+input", "2");

Based on Birthday lable we will type the year in year text box.

selenium.type("css=label:contains(\"Birthday\")+div>select+input+input", "1982");

Based on country lable we will select India in country drop down box.

selenium.select("css=div>label:contains(\"Country\")+div>select",
"label=India");


+ Is used to point the element on the same node in tree of css.





to access firstname text box
selenium.type("css=label:contains(\"Name\")+div>input", "farheen");
to access secondname its the same label of div but on the second place
selenium.type("css=label:contains(\"Name\")+div>input+input", "khan");


> Is used to point the element one node down in the tree of css.
to access firstname text box
selenium.type("css=label:contains(\"Name\")+div>input", "farheen");

How to use CSS in Selenium to locate an element

XPath locator is one of the most precise locator. But this has a disadvantage of its locator types thats is its slowness.

This disadvantage of xpath you can see when running the tests under IE while Firefox works with xpath pretty faster than IE.

The main thing is that tests which intensively use XPath work extremely slow under IE and this feature is the cause of huge variety of problems related to execution speed as well as quality of the tests itself especially during operations with dynamic content.

For this reason CSS locators can be good alternative of XPath. What can we do with CSS locators?



CSS locator will give you clear picture of your element hierarchy

lets say your xpath of an element is like,



xpath=//div//span/a



the same locatore can be identified by CSS is .



css=div * span > a



from the above example there are two symbol are being used to locate an element.



1) "/" in xpath is just a next level of DOM element hierarchy and same used in CSS is ">"

2) "//" in xpath is any DOM object hierarchy level under current object and same used in CSS is "*"



The way we use attributes in xpath we can use attributes in css as well. lets say your element's xpath is like this



//input[@name='continue' and @type='button']



can be written in CSS



css=input[name='continue'][type='button']

or

css=input[name=continue][type=button]



in xpath we can check the partial attribute value matching but in CSS we can't.



lets say your element is like this







so the xpath to locate this element is .



xpath=//div[contains(@title,"title")]



and same can be used in CSS like



css=div[title~=title]



But if your element is like this







then CSS locator css=div[title~=title] wont work here .



CSS provides us the easy way to specify the element.

lets say your element is like this,







we can write in xpath like this



xpath=//input[@id="username"]



and same can be specified in CSS



css=input#username



so whenever we want to identify any element with their id then we use #



lets say your element is like this,







then xpath is



xpath=//input[@class="password"]



and corresponding CSS is



css=input.password



so whenever we want to identify any element with their class then we use .



below are the element sturcture used in above examples.































An interesting feature of CSS in Selenium :Sub-String matches.



^= Match a prefix

$= Match a suffix

*= Match a substring



1 css=a[id^='id_prefix_']



A link with an “id” that starts with the text “id_prefix_”



2 css=a[id$='_id_sufix']



A link with an “id” that ends with the text “_id_sufix”



3 css=a[id*='id_pattern']



A link with an “id” that contains the text “id_pattern”



these CSS features are awesome more details can be found on

How to use CSS in Selenium extensively

and if you want to know in depth then visit this page.

http://www.w3.org/TR/css3-selectors/

How to verify value in drop down list.

Take an example How to find some value is in drop down list or now? To find element drop down is easy but to find a drop down having some specific
value in their list is difficult.

Go to www.ebay.in you will see there is drop down along with search text box.
How to veify a specific value "Collectibles" is in drop down list.

Using Xpath:



verifyElementPresent
//select[@id='_sacat']/option[contains(text(),'Collectibles')]



verifyTrue(selenium.isElementPresent("//select[@id='_sacat']/option[contains(text(),'Collectibles')]"));


Using CSS:



verifyElementPresent
css=select#_sacat>option:contains("Fun")



verifyTrue(selenium.isElementPresent("css=select#_sacat>option:contains(\"Fun\")"));


verifyElementPresent
css=select>option:contains("Fun")

Monday, November 15, 2010

Extend Selenium Server with the help of Default Selenium

Default Selenium
DefaultSelenium is the base class that you instantiate early on in your test class to get the selenium object which you later use in almost every line of you test script.


.
.
Selenium selenium=new DefaultSelenium("localhost",4444,"*chrome","http://www.google.com/");
selenium.start();
selenium.open("/");
.
.
.
                  OR            

/*Creates a new DefaultSelenium object and starts it using the specified baseUrl and browser string*/
setUp("http://www.imdb.com/", "*firefox");
selenium.open("/");
selenium.click("nb15go_image");
.
.
.
does that ring a bell?


What do you mean by extending the default selenium?
Extending the default selenium means enhancing or customizing or modifying the existing features of selenium class. We are reusing the existing class after adding some enhancements so as to customize the existing features to our taste and requirement. Programming languages such as JAVA provide the facility of extending/modifying the behavior of a class without having to re-write the entire class. We can create a new class that inherits the attributes and methods of another. We don't need a copy of the original source code (as is the case with many other languages) to extend the usefulness of a class/library.

Why do I need to extend selenium?
If you want certain operations to be done every time before a step is executed then you would have to extend the default selenium. For example let’s say that you wish to wait 5 seconds after every step or you want to highlight the element before clicking on it or you want to record every step in log file or you want to poll for a element’s existence for a certain amount of time before performing an operation (click, type) on it. For all these to happen you would have to extend the default selenium class that you use in your RC test script.

Below is a simple example that demonstrates this concept. The class
MySelenium extends the class DefaultSelenium. The methods click and type of the base class have been over-ridden in such a way that the target element (which is to be clicked on or typed into) is highlighted thrice before the click or type operation. The class UsingMySelenium by the means of a simple example demonstrates the usage of our extended class.

Class MySelenium
package seleniumExtention;

import com.thoughtworks.selenium.DefaultSelenium;

public class MySelenium extends DefaultSelenium{

public MySelenium(String seleniumSeverHost, int port,String browserString,String autURL){
super(seleniumSeverHost, port,browserString, autURL);
}

@Override
public void click(String target) {
try {
for (int i=0;i<3;i++){ i="0;i<3;i++){">


Class UsingMySelenium
package seleniumExtention;

import org.junit.Test;
import org.junit.BeforeClass;
import org.openqa.selenium.server.SeleniumServer;

import com.thoughtworks.selenium.SeleneseTestCase;

public class UsingMySelenium extends SeleneseTestCase{
public MySelenium selenium;

@BeforeClass
public void setUp() throws Exception {

SeleniumServer seleniumserver=new SeleniumServer();
seleniumserver.boot();
seleniumserver.start();

/*using the customized selenium class that we created earlier instead of the default selenium*/
selenium=new MySelenium ("localhost",4444,"*iexplore","http://www.google.com/");
selenium.start();
selenium.windowMaximize();

}

@Test
public void testSimpleGoogleSearch() throws Exception {
selenium.open("/");
selenium.waitForPageToLoad("5000");
selenium.type("q", "Aston Martin volante");
selenium.click("//input[@value='Google Search']");
selenium.waitForPageToLoad("5000");
selenium.click("xpath=/descendant::a[text()=' - The Cars']/em[text()='Aston Martin']/parent::a");
selenium.waitForPageToLoad("25000");
Thread.sleep(5000);
}
}



To make this work you need to do the following
1) Create a package seleniumExtention inside the java project.
2) Create the classes MySelenium & UsingMySelenium and copy paste the content as given above.
3) Run the testSimpleGoogleSearch() given in the class UsingMySelenium (right click Run As-->JUnit Test).

*Following jars need to be referenced
selenium-server.jar
selenium-java-client-driver.jar
junit.jar

good luck with this and keep the questions coming!

Tuesday, November 9, 2010

firefox profile creation for selenium

Hi,
Here i have mentioned steps to handling the pop-ups and browser dialogs in selenium for firefox

Suggested settings for your Selenium Profile

1. From “View\Toolbars” tab, uncheck “Bookmarks Toolbar”
2. Right click from toolbar and click “Customize”
3. Remove “Google search” by dragging it to the “Customize Toolbar” window
4. From the “Customize Toolbar” window, click “Use Small Icons” check box then hit “Done”
5. Click “Tools\Options” then set the following:
a. “Main” tab
- set Home Page to “about:blank”
- uncheck “Show the Downloads..” option
b. “Tabs” tab
- Select “a new window” for new pages
- Uncheck all warning options
c. “Content” tab
- uncheck “Block pop-up” windows option
d. “Privacy” tab
- uncheck all “History” options
e. “Security” tab
- uncheck all “Security” options
- click “Settings” and uncheck all warning options
f. “Advanced” tab
- Uncheck “autoscrolling” option from “General” tab
- uncheck “warn me …” and “Ssearch Engines”option from “Update” tab
6. From “Tools\Add-ons” install the following:
- Firebug: allows you to edit, debug, and monitor CSS, HTML, and JavaScript on your application under test
- Selenium IDE: allows you to record, edit, and debug Selenium tests
- ScreenGrab: saves entire webpages as images.
7. From the address bar type “about:config” and add the following by right-click anywhere on the page and selecting “new”
- extensions.update.notifyUser (type=boolean; value=false)
- extensions.newAddons (type=boolean; value=false)

Wednesday, November 3, 2010

SIMPLIUM-Simple test framework for Selenium.

Overview

Simplium aids the developer to create selenium based unit test that can be executed in different browsers and environment. With environment means the same test can be run against the developers own machine as well as a test machine somewhere on the network or even the production machine.

A Simplium unit tests doesn't have any reference to which URL the test is executed against as well as no reference to which browser the test should be executed in. Instead the Simplium test cases are annotated with Simplium specific annotations which allow Simplium to take control of the test cases when executed.

Simplium looks for which environment it is executed in (development, test or production) and based on this information Simplium will execute the test cases against different servers, against a local selenium remote control or selenium grid and execute each test in the browsers that the environment has specified.

Download:

Download the latest version of Simplium from http://simplium.sektor.se/download.html
Current version is 0.4.

Quick Example

Take a look at a ordinary Selenium test case.

import junit.framework.TestCase;
import com.thoughtworks.selenium.*;
public class ExampleSeleniumTest extends TestCase {
    private Selenium selenium;
    public void setUp() {
        selenium = new DefaultSelenium("localhost",
                4444, "*firefox", "http://www.google.com");
        selenium.start();    }
    public void testGoogleForSomeThings() throws InterruptedException {
        selenium.open("/");
        assertEquals("Google", selenium.getTitle());
    }
    public void tearDown() {
        browser.stop();
    }
}

This test case has the selenium server host and port specificed in the source code, as well as the browser to run the test case in and also which URL the test should run against.

What if we would like to run this test against our development machine and test machine as well? And what if we also would like to run this test in Internet Explorer, Safari and Chrome? It is here Simplium comes to the rescue.

A Simplium based Selenium test case can look like this

package com.company.test;
import junit.framework.Assert; 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.simplium.SimpliumWebTest;
import org.simplium.junit.SimpliumJUnitRunner;
@MyCompanyWebTest
@RunWith(SimpliumJUnitRunner.class)
public class ASimpliumGoogleTest extends SimpliumWebTest {
        @Test
public void testGoogleTitle() {
               selenium.open("/");
               Assert.assertEquals("Google", selenium.getTitle());        }}

The @MyCompanyWebTest is a meta annotation that contains a number of Simplium specific annotation. This annotation combine with a specific JUnit Runner the Simplium can in the backgrund determine the current enviroment, what browser to execute the test case in and to set up a Selenium server.

package com.company.test;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.simplium.annotation.Browsers;
import org.simplium.annotation.Enviroments;
import org.simplium.annotation.Screenshot;
import org.simplium.annotation.Screenshot.CaptureRule;
@Browsers
@Enviroments(
        development = {"localhost","4444","http://localhost:8080"},
        test = {"grid.company.com","4444","http://test.google.com" },
        production = {"grid.company.com","4444","http://www.google.com"}
)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyCompanyWebTest {
}

The @MyCompanyWebTest is listed abow. The @Browsers indicates what browser to use. For now the default browsers are used which means that each test case run in the development enviroment is run in Firefox and Internet Explorer. When using test it is run in a number of other browsers as well.

@Enviroment defines the Selenium server host, port and the URL to test against for each of the three specificed enviroments. This means that for @MyCompanyWebTest a local Selenium server is started in development enviroment and the test is executed against localhost:8080. When running in test Simplium lets a Selenium grid execute the test cases. The grid is located at grid.company.com:4444. The test cases are then executed against test.google.com. Prodution also uses the Selenium grid but the test cases are executed against www.google.com.

To take control of which browser that the test should be executed in and not use the default ones the @Browsers annotation can be feed with this information.

@Browsers(
        development = {"*iexplorer","*firefox"},
        test = {"*iexplorer","*firefox","*googlechrome","*opera","*safari"},
        production = {"*iexplorer","*firefox","*googlechrome","*opera","*safari"}
)

The @Browsers annotation can also be used on a test case method to override the @Browser annotation on the class level. This if some part of the web application can't be executed with certain browser(s).

Simplium also aids the developer to find out why a test case fails. When Simplium javacode that a test case fails, through a assert or by a unknown not caught exception Simplium can be instructed to take a screenshot of the browser so that developer can see exactly what happened on the screen when the fail occured. This is done by marking the meta annotation with the @Screenshot annotation.

@Screenshot(CaptureRule.CAPTURE_WHEN_EXCEPTION_OCCURES)
public @interface MyCompanyWebTest {
}

Simplium will create a .png under the tmp directory followed by the current execution time and the test class that failed.

http://simplium.sektor.se/img/screenshot.jpg

There is a number of other annotation that also can be used, @Delay, @RunOnlyInDevelopment, @RunOnlyInTest and @RunOnlyInProduction.

How to setup a simple Simplium testcase

Step 1 - Create annotation

First we need to create an annotation that all our Simplium test cases must be annotated with.

package com.company.test; 
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
@Documented
@Inherited
public @interface MyCompanyWebTest {
}

Note that we annotate this annotation with other annotation making this a so called meta annotation. The @Inherited makes sure that this annotation is inherited for all sub classes to a MyCompanyWebTest annotated super class. @Documented makes this annotation show up in JavaDoc.

Step 2 - Define the enviroments

The newly created annotation must define to Simplium the test enviroments for development, test and production.

package com.company.test;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import org.simplium.annotation.Enviroments;
@Enviroments(
        development = {"localhost","4444","http://localhost:8080"},
        test = {"grid.selenium.com","4444","http://testenviroment.com" },
        production = {"grid.selenium.com","4444","http://www.company.com"}
)
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCompanyWebTest {
}

Each enviroment takes three parameters, the host name of where the selenium server is located, the port the selenium server is listing on and where the selenium test case should be executed against.

In development if there doesn't exist an selenium server on the specified host and port a server is started in the background. For test and production the selenium grid should be used.

The base url where the selenium test case is executed should in the development mode be set to the developers machine, localhost, combined with the port for the local test enviroment. The base url for test and production should point on some test enviroment and the production URL. When running in test or production enviroment these URL can be changed with a system property.

Step 3 - Define the browsers

So we have definied the enviroment but not which browsers that the test cases should be run in.

package com.company.test;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import org.simplium.annotation.Enviroments;
@Enviroments(
        development = {"localhost","4444","http://localhost:8080"},
        test = {"grid.selenium.com","4444","http://testenviroment.com"},
        production = {"grid.selenium.com","4444","http://www.company.com" }
)
@Browsers(
        development = { "*iexplore"   "*firefox"      },
        test = {
               "*firefox on Windows"
               "*firefox on MacOS"
               "*firefox on Linux"
               "*iexplore on Windows"
               "*iexplore on MacOS"
               "*safari on MacOS"
               "*safari on Windows"
               "*opera on Windows"
               "*opera on MacOS"
               "*opera on Linux"
               "*googlechrome on Windows"
        },
        production = {
               "as test"
        }
)
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCompanyWebTest {
}

With the use of the @Browser annotation we define that in the development enviroment the test case should be executed in iexplore and firefox. For the test enviroment the same test case is run in a number of browser on different plattforms. Here we use Selenium grid to distribute the execution of the test case to machines running the different plattforms and having the different browsers installed. So the machine that starts the test cases doesn't need to have any browsers installed. For production we simply use the same set as for the test enviroment.

Step 4 - Create your Simplium test case

Now we are ready to start developing the test case.

package com.company.test;
import junit.framework.Assert;
 import org.junit.Test;
import org.junit.runner.RunWith;
import org.simplium.SimpliumWebTest;
import org.simplium.junit.SimpliumJUnitRunner;
@MyCompanyWebTest
@RunWith(SimpliumJUnitRunner.class)
public class ASeleniumTest extends SimpliumWebTest {
        @Test
        public void myTestMethod() {
               selenium.open("/mywebapp");
               Assert.assertEquals("Example", selenium.getTitle()); }}

The test case must be annotated with the created annotation @MyCompanyWebTest. To run the test case with JUnit the @RunWith annotation should be presented and the SimpliumJunitRunner class must be used. Also the test case must extend the SimpliumWebTest.

Note that the test case doesn't have any information about the executing enviroment such as where the selenium server is located or which browser the test should be executed in.

Step 5 - Run in development mode

When running the test case in any modern IDE (here in Eclipse) Simplium execute the test cases in the different browsers specified by the @Browsers annotation.

http://simplium.sektor.se/img/development.jpg

Note that the test case is run twice, on for each browser definied in the development enviroment.

Step 6 - Run in test mode

So now the developer has tested the application on his developer machine but what about running the test case again but now against a test machine? Simplium makes this simple. Just add the VM argument -Denviroment=test when running the test cases and Simplium will automaticly use the Selenium grid definied under test and execute the test cases with the browsers that has been defined under test.

Step 7 - Run in production mode

The same applies for running in production mode. Use the VM argument -Denviroment=production to make Simplium execute the test cases with the production settings.

Step 8 - The rest

There is a number of annotation that hasn't been mention so far so to get familiar with these this section explain the usage.

@Screenshot

Simplium also aids the developer to find out why a test case fails. When Simplium javacode that a test case fails, through a assert or by a unknown not caught exception Simplium can be instructed to take a screenshot of the browser so that developer can see exactly what happened on the screen when the fail occured. This is done by marking the meta annotation with the @Screenshot annotation.

@Screenshot(CaptureRule.CAPTURE_WHEN_EXCEPTION_OCCURES)
public @interface MyCompanyWebTest {
 }

@Delay

@Delay marks a class or method that all selenium API calls should be delayed. This is usable when debugging a test case. The defaul delay is 1000ms (1s) and this can be changed by setting the delay with the annotation, @Delay(2000) gives 2 second delay.

package com.company.test;
 import junit.framework.Assert;
 import org.junit.Test;
import org.junit.runner.RunWith;
import org.simplium.SimpliumWebTest;
import org.simplium.junit.SimpliumJUnitRunner;
 @MyCompanyWebTest
@RunWith(SimpliumJUnitRunner.class)
public class ASeleniumTest extends SimpliumWebTest {
    @Test
   @Delay
   public void searchOnGoogleForGoogle() {
      selenium.open("/");
      selenium.type("q", "google");
      selenium.click("btnG");  }}

@RunOnlyIn*

There are three annotations @RunOnlyInDevelopment, @RunOnlyInTest and @RunOnlyInProduction that can be used to mark classes or method so that it is only run in the specified enviroment. In below example the test case searchOnGoogleForGoogle will only be run under the developmen enviroment. When run in test or production this test case will be ignored.

package com.company.test;
 import junit.framework.Assert;
 import org.junit.Test;
import org.junit.runner.RunWith;
import org.simplium.SimpliumWebTest;
import org.simplium.junit.SimpliumJUnitRunner;
 @MyCompanyWebTest
@RunWith(SimpliumJUnitRunner.class)
public class ASeleniumTest extends SimpliumWebTest {
    @Test
   @RunOnlyInTest
   public void searchOnGoogleForGoogle() {
      selenium.open("/");
      selenium.type("q", "google");
      selenium.click("btnG");
   }
}

@Timeout

Annotation that can be used as a meta annotation, class annotation or method annotation to indicate the timeout time Selenium will use for its "open" and the "waitFor*" actions. It is specified in milliseconds.

package com.company.test;
 import junit.framework.Assert;
 import org.junit.Test;
import org.junit.runner.RunWith;
import org.simplium.SimpliumWebTest;
import org.simplium.junit.SimpliumJUnitRunner;
 
@MyCompanyWebTest
@RunWith(SimpliumJUnitRunner.class)
public class ASeleniumTest extends SimpliumWebTest {
    @Test
   @Timeout(60000)
   public void searchOnGoogleForGoogle() {
      selenium.open("/");
      selenium.type("q", "google");
      selenium.click("btnG");
   }
}