Testing web sites with Selenium

Introduction

EcFeed has been originally written to facilitate modeling and executing tests written in Java. As such, it is naturally supporting all test frameworks that are compatible with Java, including Selenium. Selenium is a wonderful piece of software created to test web applications. If you haven’t heard of it, go immediately to http://www.seleniumhq.org/ and check it out. This tutorial will not teach you about Selenium. It will demonstrate, how powerful it will get when used with ecFeed.

FlightFinder

In this tutorial we will test our example web app that is available under this URL: http://ecfeed.com/samples/FlightFinder. We have already created the test model in the previous tutorial. If you haven’t don that you should go there and create a test model according to the guide.
You can also download it from here. After download you have to import this file to your Java project: Select your Java project in Eclipse Package Explorer > Select src source folder > display context menu (right mouse click) > select Import > in window: Select an import source select File system > click Browse button after field: From directory > select directory containing ect file > click Ok > In the right box select file FlightFinderTest.ect > click Finish button.

Now you should install the selenium web driver. Download Selenium WebDriver for Java from http://www.seleniumhq.org/download. Unpack the downloaded file – it contains libraries which will be used in our project. Add those jars (also from subdirs) to the project path. Another thing we need to do is to download driver for the browser we want to use in our test. As this is tutorial about ecFeed and not about Selenium, we will demonstrate only one browser that will be Chrome. The driver for chrome is available here. Download the driver for your system and unpack it somewhere.
Depending on the Selenium version it also may be necessary to include JUnit library in Java project.

FlightFinderTest ect file contains FlightFinderTest class. Implement this class and paste the following code as class implementation.

	package com.ecfeed.test;
	import org.openqa.selenium.WebDriver;
	import org.openqa.selenium.chrome.ChromeDriver;
	import static org.junit.Assert.assertTrue;
	import java.util.Calendar;
	import java.util.Date;
	import java.util.List;
	import org.openqa.selenium.By;
	import org.openqa.selenium.WebElement;
	public class FlightFinderTest {
	    
	    private WebDriver fDriver;
	    
		public void initialTest() {
			System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
		    WebDriver driver = new ChromeDriver();
		    driver.get("http://ecfeed.com/samples/FlightFinder");
		    try {
		    	sleep(3000);
		    } finally {
		        driver.quit();
		    }
		}	    
	  
	    //The test method. Sets the input according to parameters' values click the Search button and 
	    //check the max price 
	    public void findFlightsTest(String airportFrom, String airportTo, int daysToFlyOut, 
	                                boolean isReturnFlight, int daysBetweenFlights, TicketClass ticketClass, 
	                                float maxPrice) {
	    	
	    	if (airportFrom.equals(airportTo)) {
	    		// we do not perform test when airportFrom and to are equal (we can not block this case in ecFeed)
	    		return;
	    	}
	    
	        //setup the selenium drive
	        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
	        fDriver = new ChromeDriver();
	        fDriver.get("http://ecfeed.com/samples/FlightFinder");
	        try {
	            //set input
	            setFields(airportFrom, airportTo, daysToFlyOut, isReturnFlight, daysBetweenFlights, ticketClass);
	  
	            //click 'Search'
	            fDriver.findElement(By.id("searchFlights")).click();
	            //give the app time for response
	            sleep(1000);
	            //make sure that max price does not exceed the limit set in the parameter
	            assertTrue(getMaxPrice() <= maxPrice);
	        } finally {
	        fDriver.quit();
	        }
	    }
	    
	    private void setFields(String airportFrom, String airportTo, int daysToFlyOut,
	                           boolean isReturnFlight, int daysBetweenFlights,
	                           TicketClass ticketClass) {
	    
	        setAirports(airportFrom, airportTo);
	        Date today = new Date();
	        Date flyOutDate = addDays(today, daysToFlyOut);
	        Date returnDate = addDays(today, daysToFlyOut + daysBetweenFlights);    
	        setDate("dateFlyOut", flyOutDate);
	        if(isReturnFlight){
	            setDate("dateReturn", returnDate);
	        }
	        setJourneyType(isReturnFlight);
	        setTicketClass(ticketClass);
	    }
	  
	    private void setAirports(String airportFrom, String airportTo) {
	        setSelectField("airportFrom", airportFrom);
	        setSelectField("airportTo", airportTo);
	    }
	  
	    private void setDate(String prefix, Date date) {
	        setDateFields(prefix + "Year", prefix + "Month", prefix + "Day", date);
	    }
	  
	    private void setDateFields(String yearId, String monthId, String dayId, Date dateToSet) {
	                               Calendar calendar = Calendar.getInstance();
	        calendar.setTime(dateToSet);
	    
	        String day = String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH));
	        String month = String.format("%02d", calendar.get(Calendar.MONTH));
	        String year = String.valueOf(calendar.get(Calendar.YEAR));
	    
	        setSelectField(yearId, year);
	        setSelectField(monthId, month);
	        setSelectField(dayId, day);
	    }
	  
	    private void setJourneyType(boolean journeyType) {
	        String id;
	        if (journeyType == true) {
	            id = "radioReturn";
	        } else {
	            id = "radioOneWay";
	        }
	        fDriver.findElement(By.id(id)).click();
	    }
	  
	    private Date addDays(Date date, int days)
	    {
	        Calendar calendar = Calendar.getInstance();
	        calendar.setTime(date);
	        calendar.add(Calendar.DATE, days);
	        return calendar.getTime();
	    }
	  
	    private void setTicketClass(TicketClass ticketClass) {
	        setSelectField("ticketClass", ticketClassName(ticketClass));
	    }
	  
	    private String ticketClassName(TicketClass ticketClass) {
	        switch (ticketClass) {
	        case ECONOMY: return "Economy";
	        case PREMIUM_ECONOMY: return "Premium economy";
	        case BUSINESS: return "Business";
	        case FIRST: return "First";
	        default: throw new RuntimeException("Invalid ticket class.");
	        }
	    }
	  
	    private void setSelectField(String fieldId, String value) {
	        WebElement select = fDriver.findElement(By.id(fieldId));
	        List<WebElement> options = select.findElements(By.tagName("option"));
	        for(WebElement option : options){
	            if(option.getText().equals(value)) {
	                option.click();
	                break;
	            }
	        }
	    }
	    private float getMaxPrice() {
	        WebElement maxPriceElement = fDriver.findElement(By.id("maxPrice"));
	        if (maxPriceElement == null) {
	            return 0;
	        }
	        return Float.parseFloat(maxPriceElement.getText());
	    }
	    
	    private void sleep(int milliseconds) {
	        try {
	            Thread.sleep(milliseconds);
	        } catch(InterruptedException ex) {
	            Thread.currentThread().interrupt();
	        }
	    }	    
	}

Replace "/path/to/chromedriver" with the path to unpacked chrome driver.

In our first test we will just check if we can open browser on the page with our flights search app from ecFeed GUI. Select initialTest method and click Test online button. You should see Chrome browser opening the Flight Finder web site and closing.

Now we can check the parametrized method. Select findFlightsTest() method and click Test online. All tests should pass.