package com.framework.site.objects.header; import ch.lambdaj.Lambda; import com.framework.asserts.JAssertion; import com.framework.driver.event.HtmlElement; import com.framework.driver.event.HtmlObject; import com.framework.driver.exceptions.ApplicationException; import com.framework.driver.objects.AbstractWebObject; import com.framework.driver.objects.Link; import com.framework.driver.objects.PageObject; import com.framework.site.config.SiteSessionManager; import com.framework.site.objects.header.enums.LevelOneMenuItem; import com.framework.site.objects.header.enums.MenuItems; import com.framework.site.objects.header.interfaces.Header; import com.framework.site.pages.activities.ActivitiesPage; import com.framework.site.pages.bookedguest.BookedGuestLogonPage; import com.framework.site.pages.bookingengine.FindACruisePage; import com.framework.site.pages.core.*; import com.framework.site.pages.core.cruisefrom.CruiseFromPortPage; import com.framework.site.pages.core.cruiseto.CruiseToPage; import com.framework.site.pages.dining.DiningPage; import com.framework.site.pages.funshops.FunShopsPage; import com.framework.site.pages.funville.ForumsPage; import com.framework.site.pages.loyalty.VifpClubPage; import com.framework.utils.error.PreConditions; import com.google.common.base.Optional; import org.apache.commons.io.FilenameUtils; import org.openqa.selenium.By; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.Locale; import static com.framework.utils.datetime.TimeConstants.FIVE_SECONDS; import static com.framework.utils.datetime.TimeConstants.THREE_SECONDS; import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.is; class NavigationAdditionalObject extends AbstractWebObject implements Header.NavigationAdditional { //region NavigationAdditionalObject - Variables Declaration and Initialization Section. private static final Logger logger = LoggerFactory.getLogger( NavigationAdditionalObject.class ); // ------------------------------------------------------------------------| // --- WEB-OBJECTS CACHING ------------------------------------------------| // ------------------------------------------------------------------------| private HtmlElement flyouts; private HtmlElement data_ccl_flyout_learn, data_ccl_flyout_explore; private HtmlElement data_ccl_flyout_plan, data_ccl_flyout_manage, data_ccl_flyout_search; private List<HtmlElement> learns, explores, plans, manages, popular_searches; private HtmlElement search_box, popular_box; private HtmlElement ccl_header_site_search, ccl_header_site_search_submit; //endregion //region NavigationAdditionalObject - Constructor Methods Section NavigationAdditionalObject( final HtmlElement rootElement ) { super( rootElement, LOGICAL_NAME ); initWebObject(); } //endregion //region NavigationAdditionalObject - Initialization and Validation Methods Section @Override protected void initWebObject() { logger.info( "validating static elements for web object id: < {} >, name:< {} >...", getQualifier(), getLogicalName() ); final String REASON = "assert that element \"%s\" exits"; final String REASON1 = "assert element list size \"%s\""; JAssertion assertion = getRoot().createAssertion(); Optional<List<HtmlElement>> e = getRoot().allChildrenExists( By.cssSelector( "div.flyout" ), FIVE_SECONDS ); assertion.assertThat( String.format( REASON, "div.flyout" ), e.isPresent(), is( true ) ); assertion.assertThat( String.format( REASON1, "div.flyout" ), e.get().size(), is( 5 ) ); for( HtmlElement he : e.get() ) { String attribute = he.getAttribute( "data-ccl-flyout" ); switch ( attribute ) { case "learn": data_ccl_flyout_learn = he; break; case "explore": data_ccl_flyout_explore = he; break; case "plan": data_ccl_flyout_plan = he; break; case "manage": data_ccl_flyout_manage = he; break; case "search": data_ccl_flyout_search = he; break; } } } //endregion //region NavigationAdditionalObject - Service Methods Section private HtmlElement getRoot() { return getBaseRootElement( Header.NavigationAdditional.ROOT_BY ); } //endregion //region NavigationAdditionalObject - Business Methods Section @Override public boolean isDisplayed() { return getRoot().isDisplayed(); } @Override public PageObject clickOnMenuItem( final LevelOneMenuItem level1, final MenuItems level2 ) { PreConditions.checkState( isDisplayed(), "The NaNavigationAdditional section is not displayed." ); logger.info( "Clicking on menu item < '{}';'{}' >", level1.getTitle(), level2.getTitle() ); Link link = new Link( findMenuItemAnchor( level1, level2 ) ); return clickOnMenuItem( link, level2 ); } @Override public PageObject clickOnMenuItem( final Link link, final MenuItems level2 ) { logger.info( "clicking on menu item < {} >", level2.name() ); link.click(); Locale locale = SiteSessionManager.get().getCurrentLocale(); switch( level2 ) { case WHY_CARNIVAL : return new CruisingPage(); case WHATS_IT_LIKE : return new What2ExpectPage(); case WHERE_CAN_I_GO : return new CruiseDestinationsAndPortsPage(); case HOW_MUCH_IS_IT : return new CruiseCostPage(); case HELP_ME_DECIDE : return new VacationPlannerPage(); case DESTINATIONS : { if( locale.equals( Locale.UK ) ) { logger.info( "current locale is < {} > returning new instance of BeginnersGuidePage", locale.getDisplayCountry() ); return new BeginnersGuidePage(); } if( locale.equals( Locale.US ) ) { logger.info( "current locale is < {} > returning new instance of CruiseToPage", locale.getDisplayCountry() ); return new CruiseToPage(); } } case FIND_A_CRUISE : return new FindACruisePage(); case FIND_A_PORT : return new CruiseFromPortPage(); // CloseToHomePage(); 11-Mar-2015 changed by marketing case FAQ_S : return new FaqPage(); case FORUMS : return new ForumsPage(); case MY_BOOKING : case CHECK_IN : { if( locale.equals( HomePage.AU ) ) { return new OnlineCheckInPage(); } else { return new BookedGuestLogonPage(); } } case PLAN_ACTIVITIES : { if( locale.equals( Locale.US ) ) { return new BookedGuestLogonPage(); } else { return new ActivitiesPage(); } } case VIFP_CLUB : return new VifpClubPage(); case ONBOARD_ACTIVITIES : return new OnboardActivitiesPage(); case DINING : return new DiningPage(); case ACCOMMODATIONS : return new StateRoomsPage(); case OUR_SHIPS : { if( locale.equals( HomePage.AU ) ) { logger.info( "current locale is < {} > returning new instance of CruiseToPage", locale.getDisplayCountry() ); return new BaseCruiseShipsPage(); } logger.info( "current locale is < {} > returning new instance of CruiseShipsPage", locale.getDisplayCountry() ); return new CruiseShipsPage(); } case CARIBBEAN : return new UKCaribbeanPage(); case WHATS_INCLUDED : case ON_THE_SHIP : return new BeginnersGuidePage(); case SHORE_EXCURSIONS : { if( locale.equals( Locale.UK ) ) { logger.info( "current locale is < {} > returning new instance of BeginnersGuidePage", locale.getDisplayCountry() ); return new BeginnersGuidePage(); } else if( locale.equals( Locale.US ) ) { logger.info( "current locale is < {} > returning new instance of ActivitiesPage", locale.getDisplayCountry() ); return new ActivitiesPage(); } } case IN_ROOM_GIFTS_AND_SHOPPING : return new FunShopsPage(); case ALREADY_BOOKED : return new AlreadyBookedPage(); case NOUVEAU_RESERVATION : return new NouveauReservationPage(); default: { throw new IllegalArgumentException( "The menu item <'{" + level2.getTitle() + "}'> was not found" ); } } } /** * Hovers over the {@code menuItem} link, provided by {@code links} * procedure: * <ul> * <li>Waiting for 3 conditions * <ul> * <li>1. div.flyout.exposed </li> * <li>2. div.flyout.active.showUL</li> * <li>3. div.header-nav-additional is displayed</li> * </ul> * </li> * <li> * select the first link that matches the requested item-menu * </li> * <li> * validates that image src before hover as expected ( bundle value ) * </li> * <li> * hovering over image * </li> * <li> * validates that image src after hover as expected ( bundle value ) * </li> * </ul> * * @param level1 a level-1 menu item * @param level2 a sub-menu item * * @return the hovered link * * @see com.framework.driver.objects.Link * @see com.framework.utils.spring.AppContextProxy * @see ch.lambdaj.Lambda#selectFirst(Object, org.hamcrest.Matcher) * */ @Override public Link hoverOnMenuItem( final LevelOneMenuItem level1, final MenuItems level2 ) { logger.info( "Hovering over menu item < '{}';'{}' >", level1.getTitle(), level2.getTitle() ); PreConditions.checkState( isDisplayed(), "The NaNavigationAdditional section is not displayed." ); findFlyoutsDiv().waitAttributeToMatch( "class", endsWith( "exposed" ), THREE_SECONDS ); Link menuItemL2 = new Link( findMenuItemAnchor( level1, level2 ) ); menuItemL2.hover( false ); return menuItemL2; } @Override public void hoverOnMenuItem( final Link link ) { PreConditions.checkState( isDisplayed(), "The NaNavigationAdditional section is not displayed." ); link.hover( false ); } @Override public HtmlElement getImage( final Link link ) { HtmlElement img = link.getHtmlElement().findElement( By.tagName( "img" ) ); logger.info( "returning img object with src < {} >", img.getAttribute( "src" ) ); return img; } @Override public Link getLink( final LevelOneMenuItem level1, final MenuItems level2 ) { return new Link( findMenuItemAnchor( level1, level2 ) ); } @Override public String getDataDefaultImg( final Link link ) { HtmlElement img = findMenuItemImg( link ); String value = img.getAttribute( "data-default" ); String def = FilenameUtils.getName( value ); logger.info( "Returning data default for img < {} >", def ); return def; } @Override public String getDataHoverImg( final Link link ) { HtmlElement img = findMenuItemImg( link ); String value = img.getAttribute( "data-hover" ); String hover = FilenameUtils.getName( value ); logger.info( "Returning data hover for img < {} >", hover ); return hover; } @Override public List<String> getChildMenuItemsNames( LevelOneMenuItem level1 ) { List<HtmlElement> elements = findMenuItemsAnchors( level1 ); List<String> list = HtmlObject.extractAttribute( elements, "textContent" ); logger.info( "return a list of child-menu items names < {} >", Lambda.join( list, ", " ) ); return list; } //endregion //region NavigationAdditionalObject - Element Finder Methods Section private HtmlElement findDataCclFlyoutLevelOneItem( LevelOneMenuItem item ) { final By findBy = By.cssSelector( String.format( "div.flyout[data-ccl-flyout=\"%s\"]", item.name().toLowerCase() ) ); switch ( item ) { case LEARN: { if( null == data_ccl_flyout_learn ) { data_ccl_flyout_learn = getRoot().findElement( findBy ); } return data_ccl_flyout_learn; } case EXPLORE: { if( null == data_ccl_flyout_explore ) { data_ccl_flyout_explore = getRoot().findElement( findBy ); } return data_ccl_flyout_explore; } case PLAN: { if( null == data_ccl_flyout_plan ) { data_ccl_flyout_plan = getRoot().findElement( findBy ); } return data_ccl_flyout_plan; } case MANAGE: { if( null == data_ccl_flyout_manage ) { data_ccl_flyout_manage = getRoot().findElement( findBy ); } return data_ccl_flyout_manage; } default: { if( null == data_ccl_flyout_search ) { data_ccl_flyout_search = getRoot().findElement( findBy ); } return data_ccl_flyout_search; } } } private List<HtmlElement> findMenuItemsAnchors( LevelOneMenuItem item ) { final By findBy = By.tagName( "a" ); switch ( item ) { case LEARN: { if( null == learns ) learns = findDataCclFlyoutLevelOneItem( item ).findElements( findBy ); return learns; } case EXPLORE: { if( null == explores ) explores = findDataCclFlyoutLevelOneItem( item ).findElements( findBy ); return explores; } case PLAN: { if( null == plans ) plans = findDataCclFlyoutLevelOneItem( item ).findElements( findBy ); return plans; } case MANAGE: { if( null == manages ) manages = findDataCclFlyoutLevelOneItem( item ).findElements( findBy ); return manages; } default: throw new ApplicationException( new IllegalArgumentException( "Invalid menu item " + item.getTitle() ) ); } } private HtmlElement findSearchBoxLi() { final By findBy = By.className( "search-box" ); if( null == search_box ) { search_box = findDataCclFlyoutLevelOneItem( LevelOneMenuItem.SEARCH ).findElement( findBy ); } return search_box; } private HtmlElement findPopularBoxLi() { final By findBy = By.className( "popular-box" ); if( null == popular_box ) { popular_box = findDataCclFlyoutLevelOneItem( LevelOneMenuItem.SEARCH ).findElement( findBy ); } return popular_box; } private HtmlElement findCclHeaderSiteSearch() { final By findBy = By.id( "ccl_header_site-search" ); if( null == ccl_header_site_search ) { ccl_header_site_search = findSearchBoxLi().findElement( findBy ); } return ccl_header_site_search; } private HtmlElement findCclHeaderSiteSearchSubmit() { final By findBy = By.id( "ccl_header_site-search-submit" ); if( null == ccl_header_site_search_submit ) { ccl_header_site_search_submit = findSearchBoxLi().findElement( findBy ); } return ccl_header_site_search_submit; } private List<HtmlElement> findPopularSearchesAnchors() { final By findBy = By.tagName( "a" ); if( null == popular_searches ) { popular_searches = findPopularBoxLi().findElements( findBy ); } return popular_searches; } private HtmlElement findMenuItemAnchor( LevelOneMenuItem menuItem, MenuItems item ) { final By findBy = By.xpath( String.format( ".//span[@class=\"title\" and normalize-space(.)=\"%s\"]/..", item.getTitle() ) ); return findDataCclFlyoutLevelOneItem( menuItem ).findElement( findBy ); } private HtmlElement findMenuItemImg( Link link ) { return link.getHtmlElement().findElement( By.tagName( "img" ) ); } private HtmlElement findMenuItemTitleSpan( Link link ) { return link.getHtmlElement().findElement( By.cssSelector( "span.title" ) ); } private HtmlElement findFlyoutsDiv() { final By findBy = By.className( "header-flyouts" ); if( null == flyouts ) { flyouts = getRoot().findElement( findBy ); } return flyouts; } //endregion }