/******************************************************************************* * Copyright (c) 2012 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * BREDEX GmbH - initial API and implementation *******************************************************************************/ package org.eclipse.jubula.rc.common.tester; import static org.eclipse.jubula.rc.common.driver.CheckWithTimeoutQueuer.invokeAndWait; import java.awt.Rectangle; import org.apache.commons.lang.Validate; import org.eclipse.jubula.rc.common.driver.ClickOptions; import org.eclipse.jubula.rc.common.driver.IRunnable; import org.eclipse.jubula.rc.common.exception.StepExecutionException; import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeNodeTraverser; import org.eclipse.jubula.rc.common.implclasses.tree.AbstractTreeTableOperationContext; import org.eclipse.jubula.rc.common.implclasses.tree.ExpandCollapseTreeNodeOperation; import org.eclipse.jubula.rc.common.implclasses.tree.INodePath; import org.eclipse.jubula.rc.common.implclasses.tree.PathBasedTraverser; import org.eclipse.jubula.rc.common.implclasses.tree.SelectTreeNodeOperation; import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperation; import org.eclipse.jubula.rc.common.implclasses.tree.TreeNodeOperationConstraint; import org.eclipse.jubula.rc.common.tester.adapter.interfaces.ITreeTableComponent; import org.eclipse.jubula.rc.common.util.IndexConverter; import org.eclipse.jubula.rc.common.util.MatchUtil; import org.eclipse.jubula.rc.common.util.Verifier; import org.eclipse.jubula.tools.internal.objects.event.EventFactory; import org.eclipse.jubula.tools.internal.objects.event.TestErrorEvent; /** * General implementation for TreeTables. * * @author BREDEX GmbH */ public abstract class AbstractTreeTableTester extends AbstractTreeTester { /** * Checks if a given column exists, respectively does not exist * * @param column * the column * @param columnOperator * the operator to find the column * @param exists * true when the column should be found * @param timeout the maximum amount of time to wait for the check */ public void rcCheckExistenceOfColumn(final String column, final String columnOperator, final boolean exists, int timeout) { invokeAndWait("rcCheckExistenceOfColumn", timeout, //$NON-NLS-1$ new Runnable() { public void run() { checkExistenceOfColumn(column, columnOperator, exists); } }); } /** * Selects the item at the end of the <code>treepath</code> at column * <code>column</code>. * * @param pathType * whether the path is relative or absolute * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param treePath * The tree path. * @param operator * If regular expressions are used to match the tree path * @param clickCount * the click count * @param column * the column of the item to select * @param button * what mouse button should be used * @throws StepExecutionException * If the tree path is invalid, if the double-click to expand * the node fails, or if the selection is invalid. */ public void rcSelect(String pathType, int preAscend, String treePath, String operator, int clickCount, int column, int button) throws StepExecutionException { final int implCol = IndexConverter.toImplementationIndex(column); checkColumnIndex(implCol); selectByPath(pathType, preAscend, createStringNodePath(splitTextTreePath(treePath), operator), ClickOptions.create().setClickCount(clickCount) .setMouseButton(button), implCol); } /** * Selects the last node of the path given by <code>indexPath</code> at * column <code>column</code>. * * @param pathType * whether the path is relative or absolute * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param indexPath * the index path * @param clickCount * the number of times to click * @param column * the column of the item to select * @param button * what mouse button should be used * @throws StepExecutionException * if <code>indexPath</code> is not a valid path */ public void rcSelectByIndices(String pathType, int preAscend, String indexPath, int clickCount, int column, int button) throws StepExecutionException { final int implCol = IndexConverter.toImplementationIndex(column); checkColumnIndex(implCol); selectByPath(pathType, preAscend, createIndexNodePath(splitIndexTreePath(indexPath)), ClickOptions.create().setClickCount(clickCount) .setMouseButton(button), implCol); } /** * Verifies whether the first selection in the tree has a rendered text at * column <code>column</code> that is equal to <code>pattern</code>. * * @param pattern * The pattern * @param column * The column containing the text to verify * @throws StepExecutionException * If no node is selected or the verification fails. * @param timeout * the maximum amount of time to wait for the check */ public void rcVerifySelectedValue(final String pattern, final int column, int timeout) throws StepExecutionException { invokeAndWait("rcVerifySelectedValue", timeout, //$NON-NLS-1$ new Runnable() { public void run() { rcVerifySelectedValue(pattern, MatchUtil.DEFAULT_OPERATOR, column); } }); } /** * Verifies if the selected node underneath <code>treePath</code> at column * <code>column</code> has a rendered text which is equal to * <code>selection</code>. * * @param pattern * the pattern * @param operator * The operator to use when comparing the expected and actual * values. * @param column * The column containing the text to verify * @param timeout * the maximum amount of time to wait for the check * @throws StepExecutionException * If there is no tree node selected, the tree path contains no * selection or the verification fails */ public void rcVerifySelectedValue(final String pattern, final String operator, final int column, int timeout) throws StepExecutionException { invokeAndWait("rcVerifySelectedValue", timeout, //$NON-NLS-1$ new Runnable() { public void run() { final int implCol = IndexConverter .toImplementationIndex(column); checkColumnIndex(implCol); Verifier.match(getRenderedTextOfColumn(implCol), pattern, operator); } }); } /** * * @param index * The 0-based column index to check. * @throws StepExecutionException * if the column index is invalid. */ protected void checkColumnIndex(final int index) throws StepExecutionException { final AbstractTreeTableOperationContext context = getTreeTableAdapter().getContext(0); int numColumns = getEventThreadQueuer().invokeAndWait("checkColumnIndex", //$NON-NLS-1$ new IRunnable<Integer>() { public Integer run() { return new Integer( context.getNumberOfColumns()); } }); if (index < 0 || index >= numColumns) { throw new StepExecutionException( "Invalid column: " //$NON-NLS-1$ + IndexConverter.toUserIndex(index), EventFactory .createActionError(TestErrorEvent.INVALID_INDEX)); } } /** * * @param column * column * @param columnOperator * columnOperator * @param exists * exists */ protected void checkExistenceOfColumn(String column, String columnOperator, boolean exists) { AbstractTreeTableOperationContext context = getTreeTableAdapter().getContext(0); int index = -2; try { index = context.getColumnFromString(column, columnOperator, true); } catch (StepExecutionException see) { // If a column can not be found, an exception is thrown. Because // this is a valid outcome for this method in this context, we // catch the exception. if (exists) { throw see; } } if (index >= 0) { Rectangle bounds = context.getHeaderBounds(index); if (bounds == null || bounds.getWidth() <= 0) { index = -2; } } Verifier.equals(exists, index >= 0); } /** * * @param column * column * @return return * @throws StepExecutionException */ protected String getRenderedTextOfColumn(int column) throws StepExecutionException { AbstractTreeTableOperationContext context = getTreeTableAdapter().getContext(column); return context.getRenderedTextOfColumn(context.getSelectedNode()); } /** * This method is only casting the IComponentAdapter to the wanted * ITreeTableAdapter * * @return The ITreeTableAdapter out of the stored IComponentAdapter */ protected ITreeTableComponent getTreeTableAdapter() { return (ITreeTableComponent) getComponent(); } /** * @param pathType * pathType * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param objectPath * objectPath * @param co * the click options to use * @param column * the column */ protected void selectByPath(String pathType, int preAscend, INodePath objectPath, ClickOptions co, int column) { TreeNodeOperation expOp = new ExpandCollapseTreeNodeOperation(false); TreeNodeOperation selectOp = new SelectTreeNodeOperation(co); INodePath subPath = objectPath.subPath(0, objectPath.getLength() - 1); traverseTreeByPath(subPath, pathType, preAscend, expOp); traverseLastElementByPath(objectPath, pathType, preAscend, selectOp, column); } /** * Traverses the tree by searching for the nodes in the tree path entry and * calling the given operation on the last element in the path. * * @param treePath * The tree path. * @param pathType * For example, "relative" or "absolute". * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param operation * The tree node operation. * @param column * The target column for the operation. * @throws StepExecutionException * If the path traversion fails. */ protected void traverseLastElementByPath(INodePath treePath, String pathType, int preAscend, TreeNodeOperation operation, int column) throws StepExecutionException { Validate.notNull(treePath); Validate.notNull(operation); AbstractTreeTableOperationContext context = getTreeTableAdapter().getContext(column); AbstractTreeNodeTraverser traverser = new PathBasedTraverser(context, treePath, new TreeNodeOperationConstraint()); traverser.traversePath(operation, getStartNode(pathType, preAscend, context)); } /* * Methods from treeTableView (JavaFX) */ /** * Selects the last node of the path given by <code>indexPath</code> at the * column given by the column path * * @param pathType * whether the path is relative or absolute * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param indexPath * the index path * @param clickCount * the number of times to click * @param column * the column or column path of the item to select * @param operator * for the column path * @param button * what mouse button should be used * @throws StepExecutionException * if <code>indexPath</code> is not a valid path */ public void rcSelectByColumnPath(String pathType, int preAscend, String indexPath, int clickCount, String column, String operator, int button) throws StepExecutionException { final int implCol = getTreeTableAdapter().getContext(0) .getColumnFromString(column, operator, true); checkColumnIndex(implCol); selectByPath(pathType, preAscend, createIndexNodePath(splitIndexTreePath(indexPath)), ClickOptions.create().setClickCount(clickCount) .setMouseButton(button), implCol); } /** * Selects the item at the end of the <code>treepath</code> at column * <code>column</code>. * * @param pathType * whether the path is relative or absolute * @param preAscend * Relative traversals will start this many parent nodes above * the current node. Absolute traversals ignore this parameter. * @param treePath * The tree path. * @param operator * If regular expressions are used to match the tree path * @param clickCount * the click count * @param column * the column or column path of the item to select * @param colOperator * the operator for the column path * @param button * what mouse button should be used * @throws StepExecutionException * If the tree path is invalid, if the double-click to expand * the node fails, or if the selection is invalid. */ public void rcSelectColumnPath(String pathType, int preAscend, String treePath, String operator, int clickCount, String column, String colOperator, int button) throws StepExecutionException { final int implCol = getTreeTableAdapter().getContext(0) .getColumnFromString(column, colOperator, true); checkColumnIndex(implCol); selectByPath(pathType, preAscend, createStringNodePath(splitTextTreePath(treePath), operator), ClickOptions.create().setClickCount(clickCount) .setMouseButton(button), implCol); } /** * Verifies if the selected node underneath <code>treePath</code> at column * <code>column</code> has a rendered text which is equal to * <code>selection</code>. * * @param pattern * the pattern * @param operator * The operator to use when comparing the expected and actual * values. * @param column * the column or column path of the item to select * @param colOperator * The operator to use when comparing the * column or column path of the item to select * @param timeout * the maximum amount of time to wait for the check * @throws StepExecutionException * If there is no tree node selected, the tree path contains no * selection or the verification fails */ public void rcVerifySelectedValueAtPath(final String pattern, final String operator, final String column, final String colOperator, int timeout) throws StepExecutionException { invokeAndWait("rcVerifySelectedValueAtPath", timeout, //$NON-NLS-1$ new Runnable() { public void run() { AbstractTreeTableOperationContext context = getTreeTableAdapter() .getContext(0); final int implCol = context.getColumnFromString(column, colOperator, true); checkColumnIndex(implCol); context.setColumn(implCol); String text = context.getRenderedTextOfColumn( context.getSelectedNode()); Verifier.match(text, pattern, operator); } }); } }