package org.jboss.seam.examples.booking.ftest; import static org.jboss.arquillian.ajocado.Ajocado.waitForXhr; import static org.jboss.arquillian.ajocado.locator.LocatorFactory.jq; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.jboss.arquillian.ajocado.dom.Event; import org.jboss.arquillian.ajocado.locator.JQueryLocator; import org.jboss.arquillian.ajocado.locator.option.OptionLocator; import org.jboss.arquillian.ajocado.locator.option.OptionValueLocator; import org.junit.Test; /** * This class tests booking functionality of the example. * * @author jbalunas * @author <a href="http://community.jboss.org/people/jharting">Jozef Hartinger</a> */ public class BookingTest extends AbstractBookingTest { public static final JQueryLocator BUTTON_BOOK = jq("[id='actions:bookHotel']"); public static final JQueryLocator BUTTON_PROCEED = jq("[id='bookingForm:proceed']"); public static final JQueryLocator BUTTON_CONFIRM = jq("[id='confirmForm:confirm']"); public static final JQueryLocator BUTTON_CANCEL = jq("[id='confirmForm:cancel']"); public static final JQueryLocator BUTTON_REVISE = jq("[id='confirmForm:revise']"); public static final String BOOKING_MESSAGE = "You're booked to stay at the"; public static final String CANCEL_MESSAGE = "has been canceled."; public static final JQueryLocator COUNT_HOTEL = jq("[id='hotelSelectionForm:hotels'] tbody tr"); public static final JQueryLocator COUNT_BOOKING = jq("[id='bookings:bookings'] tbody tr"); public static final JQueryLocator BOOKING_TABLE_FIRST_ROW_NAME = jq("table[id='bookings:bookings'] tbody tr:first td:first"); public static final JQueryLocator BOOKING_TABLE_FIRST_ROW_LINK = jq("[id='bookings:bookings:0:cancel']"); public static final JQueryLocator BOOKING_CANCEL_MESSAGE = jq("[id='messages'] li"); public static final String BOOKING_CANCEL_MESSAGE_TEXT = "Your booking at the .+? on .+? has been canceled\\."; public static final JQueryLocator DETAILS_CARD_TYPE = jq("[id='bookingForm:creditCardType:type']"); public static final JQueryLocator DETAILS_CARD_NUMBER = jq("[id='bookingForm:creditCardNumber:input']"); public static final JQueryLocator DETAILS_SMOKING = jq("[id='bookingForm:smokingPreference:input:0']"); public static final JQueryLocator DETAILS_NONSMOKING = jq("[id='bookingForm:smokingPreference:input:1']"); public static final JQueryLocator CONFIRM_TEXT = jq("[id='content']"); public static final JQueryLocator SEARCH_PAGE_SIZE = jq("[id='pageSize']"); /** * Tests the hotel search - with both existing and non-existing queries. */ @Test public void testSearch() { enterSearchQuery("Marriott"); assertFalse(selenium.isElementPresent(SEARCH_NO_RESULTS)); assertEquals(2, selenium.getCount(COUNT_HOTEL)); enterSearchQuery("nonExistingHotel"); assertTrue(selenium.isElementPresent(SEARCH_NO_RESULTS)); assertEquals(0, selenium.getCount(COUNT_HOTEL)); } @Test public void testSearchPageSize() { int[] values = {20, 10, 5}; selenium.type(SEARCH_QUERY, "a"); waitForXhr(selenium).fireEvent(SEARCH_QUERY, Event.KEYUP); for (int pageSize : values) { waitForXhr(selenium).select(SEARCH_PAGE_SIZE, new OptionValueLocator(String.valueOf(pageSize))); assertEquals(pageSize, selenium.getCount(COUNT_HOTEL)); } } /** * Simply follows the booking wizard without changing anything. */ @Test public void testSimpleBooking() { String hotelName = "Grand Hyatt"; int bookingCount = selenium.getCount(COUNT_BOOKING); bookHotel(hotelName, CreditCardType.VISA); assertEquals(++bookingCount, selenium.getCount(COUNT_BOOKING)); } /** * Tests "revise" and "cancel" buttons as well as that changed credit card details are propagated across the booking wizard. */ @Test public void testMoreSophisticatedBooking() { String hotelName = "Conrad Miami"; String creditCardNumber1 = "0123456789012347"; CreditCardType creditCardType1 = CreditCardType.DISCOVER; String creditCardNumber2 = "6432109876543210"; CreditCardType creditCardType2 = CreditCardType.AMEX; int bookingCount = selenium.getCount(COUNT_BOOKING); enterSearchQuery(hotelName); selenium.click(SEARCH_RESULT_TABLE_FIRST_ROW_LINK); selenium.waitForPageToLoad(); // booking page selenium.click(BUTTON_BOOK); selenium.waitForPageToLoad(); // booking detail page populateBookingFields(creditCardNumber1, creditCardType1); selenium.click(BUTTON_PROCEED); selenium.waitForPageToLoad(); // confirmation page assertTrue(selenium.getText(CONFIRM_TEXT).contains(creditCardNumber1)); assertTrue(selenium.getText(CONFIRM_TEXT).contains(creditCardType1.getName())); selenium.click(BUTTON_REVISE); selenium.waitForPageToLoad(); // back to booking page populateBookingFields(creditCardNumber2, creditCardType2); selenium.click(BUTTON_PROCEED); selenium.waitForPageToLoad(); // confirmation page assertTrue(selenium.getText(CONFIRM_TEXT).contains(creditCardNumber2)); assertTrue(selenium.getText(CONFIRM_TEXT).contains(creditCardType2.getName())); // cancel booking selenium.click(BUTTON_CANCEL); selenium.waitForPageToLoad(); // check that the booking cound remains unchanged assertEquals(bookingCount, selenium.getCount(COUNT_BOOKING)); } @Test public void testBookingCanceling() { String[] hotelNames = new String[]{"Hilton Diagonal Mar", "Parc 55", "Ritz-Carlton Montreal", "Parc 55"}; int bookingCount = selenium.getCount(COUNT_BOOKING); // make 3 bookings for (String hotelName : hotelNames) { bookHotel(hotelName, CreditCardType.VISA); } bookingCount += hotelNames.length; assertEquals(bookingCount, selenium.getCount(COUNT_BOOKING)); for (int i = 0; i < hotelNames.length; i++) { String hotelName = selenium.getText(BOOKING_TABLE_FIRST_ROW_NAME).trim(); selenium.click(BOOKING_TABLE_FIRST_ROW_LINK); selenium.waitForPageToLoad(); String message = selenium.getText(BOOKING_CANCEL_MESSAGE); assertTrue("Unexpected canceling message: " + message, message.matches(BOOKING_CANCEL_MESSAGE_TEXT)); assertTrue("Unexpected hotel name.", message.contains(hotelName)); assertEquals("Unexpected number of bookings", --bookingCount, selenium.getCount(COUNT_BOOKING)); } } protected void bookHotel(String hotelName, CreditCardType creditCardType) { if (!isLoggedIn()) { fail(); } if (!selenium.isElementPresent(SEARCH_QUERY)) { selenium.open(contextPath); selenium.waitForPageToLoad(); selenium.click(MENU_FIND); selenium.waitForPageToLoad(); } enterSearchQuery(hotelName); selenium.click(SEARCH_RESULT_TABLE_FIRST_ROW_LINK); selenium.waitForPageToLoad(); // booking page selenium.click(BUTTON_BOOK); selenium.waitForPageToLoad(); // hotel page populateBookingFields(creditCardType); selenium.click(BUTTON_PROCEED); selenium.waitForPageToLoad(); // confirm page selenium.click(BUTTON_CONFIRM); selenium.waitForPageToLoad(); // main page assertTrue("Booking failed.", selenium.isTextPresent(BOOKING_MESSAGE)); } protected void populateBookingFields(CreditCardType creditCardType) { selenium.select(DETAILS_CARD_TYPE, creditCardType.getLocator()); } protected void populateBookingFields(String creditCardNumber, CreditCardType creditCardType) { selenium.type(DETAILS_CARD_NUMBER, creditCardNumber); populateBookingFields(creditCardType); } private enum CreditCardType { VISA("VISA"), MASTERCARD("MasterCard"), AMEX("AMEX"), DISCOVER("Discover"); private String name; private CreditCardType(String name) { this.name = name; } public String getName() { return name; } public OptionLocator<?> getLocator() { return new OptionValueLocator(name); } } }