/******************************************************************************* * Copyright 2014 JHC Systems Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *******************************************************************************/ package jhc.redsniff.action; import static jhc.redsniff.core.FindingExpectations.actionExpectation; import jhc.redsniff.core.Finder; import jhc.redsniff.internal.core.Quantity; import jhc.redsniff.internal.expectations.ExpectationChecker; import jhc.redsniff.internal.expectations.FindingExpectation; import jhc.redsniff.internal.finders.AsActionableFinder; import org.hamcrest.Description; /** * Exposes methods for performing actions on elements, such as clicking, * using a checker to get the elements and a controller to perform the actions * * @param <E> the type of element to interact with * @param <C> the type of context in which the elements may be found */ public class ActionDriver<E, C> { protected ExpectationChecker<C> checker; protected Controller<E> controller; /** * @param checker - for checking the expectation for the elements we require to interact with * @param controller - provides the ability to perform the actions */ public ActionDriver(ExpectationChecker<C> checker, Controller<E> controller){ this.checker = checker; this.controller = controller; } public <Q extends Quantity<E>> void type(String input, Finder<E, Q, C> finder) { type(input,finder,false); } /** * alternate version with optional append flag * @param input * @param finder * @param append */ public <Q extends Quantity<E>> void type(String input, Finder<E, Q, C> finder,boolean append) { performActionOn(actionable(finder), typing(input, append)); } /** * Clear a text field */ public <Q extends Quantity<E>> void clear(Finder<E, Q, C> finder) { performActionOn(actionable(finder), clearing()); } /** * tick a checkbox (same as clicking) */ public <L,Q extends Quantity<E>> void tick(Finder<E, Q, C> finder) { performActionOn(actionable(finder), ticking()); } /** * choose on a drop-down (same as clicking) */ public <L,Q extends Quantity<E>> void choose(Finder<E, Q, C> finder) { performActionOn(actionable(finder), choosing()); } /** * click on an element * @param finder */ public <L,Q extends Quantity<E>> void clickOn(Finder<E, Q, C> finder) { performActionOn(actionable(finder), clicking()); } /** * Submit a form * @param finder */ public <L,Q extends Quantity<E>> void submit(Finder<E, Q, C> finder) { performActionOn(actionable(finder), submitting()); } /** * Tab out of a text field ( */ public <L,Q extends Quantity<E>> void tab(Finder<E, Q, C> finder) { performActionOn(actionable(finder), tabbing()); } @SuppressWarnings("unchecked") public <Q extends Quantity<E>> void performActionOn(ActionableFinder<E, Q, C> finder, FindingExpectation<E, Q, C> actionExpectation, ActionPerformer<E> performer) { Q someOfElement = (Q) checker.quantityFoundBy(actionExpectation); finder.performAction(performer, someOfElement); } private <Q extends Quantity<E>> void performActionOn(ActionableFinder<E, Q, C> finder, ActionPerformer<E> performer) { performActionOn(finder, actionExpectation(performer, finder), performer); } @SuppressWarnings("unchecked") private static <E, Q extends Quantity<E>, C> ActionableFinder<E, Q, C> actionable(Finder<E, Q, C> finder){ if(finder instanceof ActionableFinder) return (ActionableFinder<E, Q, C>) finder; else return (ActionableFinder<E, Q, C>) AsActionableFinder.theOnly(finder); } private ActionPerformer<E> typing(final String input, final boolean append) { return new ActionPerformer<E>() { @Override public void performAction(E item) { if(!append) controller.clear(item); controller.type(input, item); } @Override public void describeTo(Description description) { description.appendText("type '"+input+"' into"); } }; } private ActionPerformer<E> clearing() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.clear(item); } @Override public void describeTo(Description description) { description.appendText("clear"); } }; } private ActionPerformer<E> clicking() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.click(item); } public void describeTo(Description description){ description.appendText("click on"); } }; } private ActionPerformer<E> tabbing() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.tab(item); } public void describeTo(Description description){ description.appendText("tab"); } }; } private ActionPerformer<E> submitting() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.submit(item); } public void describeTo(Description description){ description.appendText("submit"); } }; } private ActionPerformer<E> ticking() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.click(item); } public void describeTo(Description description){ description.appendText("tick"); } }; } private ActionPerformer<E> choosing() { return new ActionPerformer<E>(){ @Override public void performAction(E item) { controller.click(item); } public void describeTo(Description description){ description.appendText("choose"); } }; } }