Example: Custom date ElementHandler combining multiple HTML elements

Creates a new Element Handler for a date that is compiled into a form via 3 drop downs. By defining a custom ElementHandler that date can be approached in steps as one element. This example also illustrates the use of the Date object Values.

 Use

 

* dateSelect "Startdatum" in div "Levering" should equal "#{date.today.addDays(5,'mon,tue,wed,thu,fri')}"
* i fill in dateSelect "Startdatum" with "#{date.today.addMonths(3)}"

Java code

@Component
public class DataSelectElementHandler extends ElementHandler
{
	public static String DATE_SELECT = "dateSelect";

	@Autowired
	private ElementHandleService elementHandleService;

	@Override
	public boolean canHandle( ElementDescriptor descriptor ) {
		return StringUtils.equalsIgnoreCase( DATE_SELECT, descriptor.getType() );
	}

	@Override
	public ElementStub find( ElementDescriptor descriptor ) {
		ElementDescriptor selectDescriptor =
				new ElementDescriptor( descriptor.getLocator(), descriptor.getPosition(), SelectElementHandler.TYPE );
		selectDescriptor.setParent( descriptor.getParent() );

		// Return the first select in the set (which is day selector, HTML_NAME_day)
		return elementHandleService.find( selectDescriptor );
	}

	@Override
	public void set( ElementDescriptor descriptor ) {
		ElementStub day = find( descriptor );

		if ( day.exists() ) {
			String prefix = StringUtils.replace( day.getAttribute( "name" ), "_day", "" );

			ElementStub month = addParents( browser.select( prefix + "_month" ), descriptor );
			ElementStub year = addParents( browser.select( prefix + "_year" ), descriptor );

			Date dateToSet = getDateFromDescriptor( descriptor );
			LOG.debug( "Setting date selector {} to  {}", descriptor, dateToSet );

			if ( dateToSet != null ) {
				Calendar cal = Calendar.getInstance();
				cal.setTime( dateToSet );

				day.choose( "" + cal.get( Calendar.DATE ) );
				month.choose( "" + ( cal.get( Calendar.MONTH ) + 1 ) );
				year.choose( "" + cal.get( Calendar.YEAR ) );
			}
			else {
				day.choose( "0" );
				month.choose( "0" );
				year.choose( "0" );
			}
		}
	}

	@Override
	public void verify( ElementDescriptor descriptor, boolean expectedOutcome ) {
		ElementStub day = find( descriptor );

		if ( day.exists() ) {
			String prefix = StringUtils.replace( day.getAttribute( "name" ), "_day", "" );

			ElementStub month = addParents( browser.select( prefix + "_month" ), descriptor );
			ElementStub year = addParents( browser.select( prefix + "_year" ), descriptor );

			String dayValue = day.getValue();
			String monthValue = month.getValue();
			String yearValue = year.getValue();

			Date expectedDate = getDateFromDescriptor( descriptor );
			Date selectedDate = parseDate( yearValue + "-" + monthValue + "-" + dayValue );

			LOG.debug( "Date selector {}: comparing {} with expected {}", descriptor, selectedDate, expectedDate );

			if ( expectedDate != null ) {
				assertNotNull( "No valid date was selected in " + descriptor, selectedDate );
				assertEquals( "Expected date did not match in " + descriptor, expectedDate, selectedDate );
			}
			else {
				assertNull( "Valid date was selected but should not have been in " + descriptor, selectedDate );
			}
		}
	}

	private Date getDateFromDescriptor( ElementDescriptor descriptor ) {
		Object valueSet = descriptor.getValueAsType();

		if ( valueSet instanceof DateWrapper ) {
			return ( (DateWrapper) valueSet ).getRawDate();
		}
		if ( valueSet instanceof Date ) {
			return (Date) valueSet;
		}

		return parseDate( ObjectUtils.toString( valueSet ) );
	}

	private Date parseDate( String dateString ) {
		try {
			return StringUtils.isBlank( dateString ) ? null : DateUtils.parseDate( dateString, "yyyy-M-d", "yyyy-MM-dd",
			                                                                       "yyyy-MM-dd HH:ss:mm" );
		}
		catch ( ParseException pe ) {
			return null;
		}
	}
}