/*******************************************************************************
* Copyright (c) 2013 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.javafx.tester;
import static org.eclipse.jubula.rc.common.driver.CheckWithTimeoutQueuer.invokeAndWait;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import org.eclipse.jubula.rc.common.driver.ClickOptions;
import org.eclipse.jubula.rc.common.driver.DragAndDropHelper;
import org.eclipse.jubula.rc.common.exception.StepExecutionException;
import org.eclipse.jubula.rc.common.implclasses.table.Cell;
import org.eclipse.jubula.rc.common.logger.AutServerLogger;
import org.eclipse.jubula.rc.common.tester.AbstractTableTester;
import org.eclipse.jubula.rc.common.tester.adapter.interfaces.ITableComponent;
import org.eclipse.jubula.rc.common.util.MatchUtil;
import org.eclipse.jubula.rc.common.util.Verifier;
import org.eclipse.jubula.rc.javafx.driver.EventThreadQueuerJavaFXImpl;
import org.eclipse.jubula.rc.javafx.tester.util.AbstractTraverser;
import org.eclipse.jubula.rc.javafx.tester.util.GenericTraverseHelper;
import org.eclipse.jubula.rc.javafx.tester.util.NodeBounds;
import org.eclipse.jubula.rc.javafx.tester.util.NodeTraverseHelper;
import org.eclipse.jubula.toolkit.enums.ValueSets;
import org.eclipse.jubula.toolkit.enums.ValueSets.SearchType;
import org.eclipse.jubula.tools.internal.constants.TestDataConstants;
import org.eclipse.jubula.tools.internal.objects.event.EventFactory;
import org.eclipse.jubula.tools.internal.objects.event.TestErrorEvent;
import com.sun.javafx.scene.control.skin.TableHeaderRow;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ScrollToEvent;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumnBase;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
/**
* Toolkit specific commands for the <code>TableView</code>
*
* @author BREDEX GmbH
* @created 27.11.2013
*/
public class TableTester extends AbstractTableTester {
/** The AUT Server logger. */
private static AutServerLogger log = new AutServerLogger(TableTester.class);
/**
* EventHandler to consume scroll events during DnD
*/
private EventHandler<ScrollToEvent> m_scrollConsumer =
new EventHandler<ScrollToEvent>() {
@Override
public void handle(ScrollToEvent event) {
event.consume();
}
};
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jubula.rc.common.tester.AbstractTableTester#rcDragCell(int,
* java.lang.String, java.lang.String, java.lang.String, java.lang.String,
* java.lang.String, int, java.lang.String, int, java.lang.String)
*/
@Override
public void rcDragCell(int mouseButton, String modifier, String row,
String rowOperator, String col, String colOperator, int xPos,
String xUnits, int yPos, String yUnits)
throws StepExecutionException {
super.rcDragCell(mouseButton, modifier, row, rowOperator, col,
colOperator, xPos, xUnits, yPos, yUnits);
//Add event filter to prevent scrolling
Node table = ((Node) getRealComponent());
table.addEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper.getInstance().setDragMode(true);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jubula.rc.common.tester.AbstractTableTester#rcDropCell(java.
* lang.String, java.lang.String, java.lang.String, java.lang.String, int,
* java.lang.String, int, java.lang.String, int)
*/
@Override
public void rcDropCell(String row, String rowOperator, String col,
String colOperator, int xPos, String xUnits, int yPos,
String yUnits, int delayBeforeDrop) throws StepExecutionException {
try {
ITableComponent adapter = (ITableComponent) getComponent();
int implRow = adapter.getRowFromString(row, rowOperator);
int implCol = adapter.getColumnFromString(col, colOperator);
TableCell targetCell = getCellAt(implRow + 1, implCol + 1);
if (targetCell == null) {
throw new StepExecutionException("Drop target not visible", //$NON-NLS-1$
EventFactory
.createActionError(TestErrorEvent.NOT_VISIBLE));
}
super.rcDropCell(row, rowOperator, col, colOperator, xPos, xUnits,
yPos, yUnits, delayBeforeDrop);
} finally {
Node table = ((Node) getRealComponent());
table.removeEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper dndHelper = DragAndDropHelper.getInstance();
getRobot().mouseRelease(null, null, dndHelper.getMouseButton());
pressOrReleaseModifiers(dndHelper.getModifier(), false);
dndHelper.setDragMode(false);
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jubula.rc.common.tester.AbstractTableTester#rcDragRowByValue(
* int, java.lang.String, java.lang.String, java.lang.String,
* java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void rcDragRowByValue(int mouseButton, String modifier, String col,
String colOperator, String value, String regexOp,
String searchType) {
super.rcDragRowByValue(mouseButton, modifier, col, colOperator, value,
regexOp, searchType);
//Add event filter to prevent scrolling
Node table = ((Node) getRealComponent());
table.addEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper.getInstance().setDragMode(true);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jubula.rc.common.tester.AbstractTableTester#rcDropRowByValue(
* java.lang.String, java.lang.String, java.lang.String, java.lang.String,
* java.lang.String, int)
*/
@Override
public void rcDropRowByValue(String col, String colOperator, String value,
String regexOp, String searchType, int delayBeforeDrop) {
try {
ITableComponent adapter = (ITableComponent) getComponent();
int implCol = adapter.getColumnFromString(col, colOperator);
int implRow = super.findRow(value, regexOp, searchType, adapter,
implCol);
TableCell targetCell = getCellAt(implRow + 1, implCol + 1);
if (targetCell == null) {
throw new StepExecutionException("Drop target not visible", //$NON-NLS-1$
EventFactory
.createActionError(TestErrorEvent.NOT_VISIBLE));
}
super.rcDropRowByValue(col, colOperator, value, regexOp, searchType,
delayBeforeDrop);
} finally {
Node table = ((Node) getRealComponent());
table.removeEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper dndHelper = DragAndDropHelper.getInstance();
getRobot().mouseRelease(null, null, dndHelper.getMouseButton());
pressOrReleaseModifiers(dndHelper.getModifier(), false);
dndHelper.setDragMode(false);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jubula.rc.common.tester.AbstractTableTester#
* rcDragCellByColValue(int, java.lang.String, java.lang.String,
* java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public void rcDragCellByColValue(int mouseButton, String modifier,
String row, String rowOperator, String value, String regex,
String searchType) {
super.rcDragCellByColValue(mouseButton, modifier, row, rowOperator,
value, regex, searchType);
// Add event filter to prevent scrolling
Node table = ((Node) getRealComponent());
table.addEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper.getInstance().setDragMode(true);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jubula.rc.common.tester.AbstractTableTester#
* rcDropCellByColValue(java.lang.String, java.lang.String,
* java.lang.String, java.lang.String, java.lang.String, int)
*/
@Override
public void rcDropCellByColValue(String row, String rowOperator,
String value, String regex, String searchType,
int delayBeforeDrop) {
try {
ITableComponent adapter = (ITableComponent) getComponent();
int implRow = adapter.getRowFromString(row, rowOperator);
int implCol = super.findColumn(value, regex, searchType, adapter,
implRow);
TableCell targetCell = getCellAt(implRow + 1, implCol + 1);
if (targetCell == null) {
throw new StepExecutionException("Drop target not visible", //$NON-NLS-1$
EventFactory
.createActionError(TestErrorEvent.NOT_VISIBLE));
}
super.rcDropCellByColValue(row, rowOperator, value, regex,
searchType, delayBeforeDrop);
} finally {
Node table = ((Node) getRealComponent());
table.removeEventFilter(ScrollToEvent.ANY, m_scrollConsumer);
DragAndDropHelper dndHelper = DragAndDropHelper.getInstance();
getRobot().mouseRelease(null, null, dndHelper.getMouseButton());
pressOrReleaseModifiers(dndHelper.getModifier(), false);
dndHelper.setDragMode(false);
}
}
@Override
protected Object setEditorToReplaceMode(Object editor, boolean replace) {
Object returnvalue = editor;
if (replace) {
getRobot().clickAtCurrentPosition(editor, 3, 1);
} else {
returnvalue = getComponent().getRealComponent();
}
return returnvalue;
}
@Override
protected Object activateEditor(Cell cell, Rectangle rectangle) {
Object table = getComponent().getRealComponent();
getRobot().click(table, rectangle);
TableCell<?, ?> realCell = getCellAt(cell.getRow(), cell.getCol());
// Check if setting the cell in its edit state was successful
if (realCell.isEditing()) {
ClickOptions co = ClickOptions.create().setClickCount(2);
getRobot().click(table, rectangle, co);
}
return realCell;
}
/**
* Returns the TableCell at the given position.
*
* @param row
* the row
* @param column
* the column
* @return the TableCell at the specified position.
*/
private TableCell<?, ?> getCellAt(final int row, final int column) {
TableCell<?, ?> result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"getCellText", new Callable<TableCell<?, ?>>() { //$NON-NLS-1$
@Override
public TableCell<?, ?> call() throws Exception {
TableView<?> table = (TableView<?>) getRealComponent();
table.scrollTo(row);
table.scrollToColumnIndex(column);
table.layout();
TableColumn<?, ?> col = table
.getVisibleLeafColumn(column);
List<? extends TableCell> tCells = NodeTraverseHelper
.getInstancesOf(table, TableCell.class);
for (TableCell<?, ?> cell : tCells) {
if (cell.getIndex() == row
&& cell.getTableColumn() == col
&& NodeTraverseHelper.isVisible(cell)) {
return cell;
}
}
return null;
}
});
return result;
}
@Override
protected int getExtendSelectionModifier() {
return KeyEvent.VK_CONTROL;
}
@Override
protected Cell getCellAtMousePosition() throws StepExecutionException {
final Point p = getRobot().getCurrentMousePosition();
Cell result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"getCellAtMousePosition", new Callable<Cell>() { //$NON-NLS-1$
@Override
public Cell call() throws Exception {
TableView<?> table = (TableView<?>) getRealComponent();
// Update the layout coordinates otherwise
// we would get old position values
table.requestLayout();
table.layout();
List<? extends TableCell> tCells = NodeTraverseHelper
.getInstancesOf(table, TableCell.class);
for (TableCell<?, ?> cell : tCells) {
if (NodeBounds.checkIfContains(
new Point2D(p.x, p.y), cell)
&& cell.getTableView().equals(table)
&& NodeTraverseHelper.isVisible(cell)) {
TableColumn cellColumn = cell
.getTableColumn();
int col = table.getVisibleLeafIndex(cellColumn);
return new Cell(cell.getIndex(), col);
}
}
return null;
}
});
return result;
}
/**
* Gets the index path for a given column
* @param column the column
* @param table the table of the column
* @return the index path
*/
private String getColumnPath(TableColumnBase column, TableView table) {
String colPath = ""; //$NON-NLS-1$
TableColumnBase nxtColumn = column;
while (nxtColumn.getParentColumn() != null) {
colPath = String.valueOf(TestDataConstants.
PATH_CHAR_DEFAULT).concat(String.
valueOf((nxtColumn.getParentColumn()
.getColumns()
.indexOf(nxtColumn) + 1) + colPath));
nxtColumn = nxtColumn.getParentColumn();
}
colPath = (table.getColumns()
.indexOf(nxtColumn) + 1) + colPath;
return colPath;
}
@Override
protected boolean isMouseOnHeader() {
Point p = getRobot().getCurrentMousePosition();
final Point2D pos = new Point2D(p.x, p.y);
boolean result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"getTableHeader", new Callable<Boolean>() { //$NON-NLS-1$
@Override
public Boolean call() throws Exception {
TableView<?> table = (TableView<?>) getRealComponent();
// Update the layout coordinates otherwise
// we would get old position values
table.layout();
Parent header = (Parent) table.lookup(
TableHeaderRow.class.getSimpleName());
return NodeBounds.checkIfContains(pos, header);
}
});
return result;
}
/**
* Toggles the checkbox in the selected row
*/
public void rcToggleCheckboxInSelectedRow() {
int row = EventThreadQueuerJavaFXImpl.invokeAndWait(
"rcToggleCheckboxInSelectedRow", new Callable<Integer>() { //$NON-NLS-1$
@Override
public Integer call() throws StepExecutionException {
TableView<?> table = (TableView<?>) getRealComponent();
return new Integer(table.getSelectionModel()
.getSelectedIndex());
}
});
int column = getIndexOfColumnWithCheckbox(row);
clickCheckBox(row, column);
}
/**
* @param row the row
* @return the index of the column containing a checkbox
*/
private int getIndexOfColumnWithCheckbox(int row) {
int columnCount = EventThreadQueuerJavaFXImpl.invokeAndWait(
"rcToggleCheckboxInSelectedRow", new Callable<Integer>() { //$NON-NLS-1$
@Override
public Integer call() throws StepExecutionException {
TableView<?> table = (TableView<?>) getRealComponent();
return new Integer(table.getColumns().size());
}
});
Map<Node, Integer> possibleCheckBoxes = new HashMap<Node, Integer>();
for (int column = 0; column < columnCount; column++) {
Node checkBox = getCheckBox(row, column);
if (checkBox != null) {
possibleCheckBoxes.put(checkBox, column);
}
}
switch (possibleCheckBoxes.size()) {
case 0:
throw new StepExecutionException(
"No checkbox found in selected row", //$NON-NLS-1$
EventFactory.createActionError(
TestErrorEvent.CHECKBOX_NOT_FOUND));
case 1:
// only one checkbox in row, return its column
return possibleCheckBoxes.values().iterator().next();
default:
throw new StepExecutionException(
"Multiple checkboxes found in selected row", //$NON-NLS-1$
EventFactory.createActionError(
TestErrorEvent.CHECKBOX_NOT_UNIQUE));
}
}
/**
* Toggles the checkbox under the Mouse Pointer
* (The "InRow"-part of the name is not precise anymore,
* as in JavaFX checkboxes can appear not just in the first column.)
*/
public void rcToggleCheckboxInRowAtMousePosition() {
Cell cell = getCellAtMousePosition();
clickCheckBox(cell.getRow(), cell.getCol());
}
/**
* Verifies whether the checkbox in the row of the selected cell is checked.
* Fails if there are no or more than one checkboxes in the selected row.
*
* @param checked
* true if checkbox in cell should be selected, false otherwise
* @param timeout the maximum amount of time to wait for the check whether
* the given column the checkbox is selected or not
* @throws StepExecutionException
* If no cell is selected or the verification fails.
*/
public void rcVerifyCheckboxInSelectedRow(final boolean checked,
int timeout) throws StepExecutionException {
invokeAndWait("rcVerifyCheckboxInSelectedRow", timeout, new Runnable() { //$NON-NLS-1$
public void run() {
Cell selectedCell = ((ITableComponent) getComponent())
.getSelectedCell();
int row = selectedCell.getRow();
int column = getIndexOfColumnWithCheckbox(row);
verifyCheckboxInRow(checked, row, column);
}
});
}
/**
* Verifies whether the checkbox in the row under the mouse pointer is
* checked
*
* @param checked
* true if checkbox in cell is selected, false otherwise
* @param timeout the maximum amount of time to wait to verify whether the
* checkbox in the row under the mouse pointer is checked
*/
public void rcVerifyCheckboxInRowAtMousePosition(boolean checked,
int timeout) {
invokeAndWait("rcVerifyCheckboxInRowAtMousePosition", timeout, //$NON-NLS-1$
new Runnable() {
@Override
public void run() {
Cell cell = getCellAtMousePosition();
if (cell != null) {
int row = cell.getRow();
int column = cell.getCol();
verifyCheckboxInRow(checked, row, column);
} else {
throw new StepExecutionException(
"No checkbox found", //$NON-NLS-1$
EventFactory.createActionError(
TestErrorEvent.CHECKBOX_NOT_FOUND));
}
}
});
}
/**
* Clicks on the CheckBox in given row and column
*
* @param row
* the Row
* @param column
* the Column
*/
private void clickCheckBox(final int row, final int column) {
Node box = getCheckBox(row, column);
if (box != null) {
getRobot().click(box, null,
ClickOptions.create().setClickCount(1).setMouseButton(1));
} else {
throw new StepExecutionException(
"No checkbox found", //$NON-NLS-1$
EventFactory.createActionError(
TestErrorEvent.CHECKBOX_NOT_FOUND));
}
}
/**
* Verifies whether the checkbox in the row with the given
* <code>index</code> is checked
*
* @param checked
* true if checkbox in cell is selected, false otherwise
* @param row
* the row-index of the cell in which the checkbox-state should
* be verified
* @param column
* the column-index of the cell in which the checkbox-state should
* be verified
*/
private void verifyCheckboxInRow(boolean checked, final int row,
final int column) {
final CheckBox box = (CheckBox) getCheckBox(row, column);
Boolean checkIndex = EventThreadQueuerJavaFXImpl.invokeAndWait(
"verifyCheckboxInRow", new Callable<Boolean>() { //$NON-NLS-1$
@Override
public Boolean call() throws StepExecutionException {
if (box == null) {
throw new StepExecutionException(
"No checkbox found", //$NON-NLS-1$
EventFactory.createActionError(
TestErrorEvent.CHECKBOX_NOT_FOUND));
}
return box.isSelected();
}
});
Verifier.equals(checked, checkIndex.booleanValue());
}
/**
* get the CheckBox in the first TableColumn of the given row
*
* @param row
* the Row
* @param column
* the Column
* @return the CheckBox or null
*/
private Node getCheckBox(final int row, final int column) {
return EventThreadQueuerJavaFXImpl.invokeAndWait(
"clickCheckBoxFirstColumn", new Callable<Node>() { //$NON-NLS-1$
@Override
public Node call() throws Exception {
TableView<?> table = (TableView<?>) getRealComponent();
table.layout();
TableColumn<?, ?> col = table.getVisibleLeafColumn(
column);
// Check if the CheckBox is realized via a CheckBoxCell
List<? extends CheckBoxTableCell> checkboxCells =
NodeTraverseHelper
.getInstancesOf(table, CheckBoxTableCell.class);
for (CheckBoxTableCell<?, ?> cell : checkboxCells) {
if (cell.getTableColumn().equals(col)
&& cell.getIndex() == row
&& NodeTraverseHelper.isVisible(cell)) {
return cell.lookup(CheckBox.class
.getSimpleName());
}
}
// No CheckBoxCell found. Now we have to check all
// Cells!
List<? extends TableCell> cells = NodeTraverseHelper
.getInstancesOf(table, TableCell.class);
for (TableCell<?, ?> cell : cells) {
if (cell.getTableColumn().equals(col)
&& cell.getIndex() == row
&& NodeTraverseHelper.isVisible(cell)) {
return cell.lookup(CheckBox.class
.getSimpleName());
}
}
return null;
}
});
}
@Override
public void rcVerifyValueInRow(final String row, final String rowOperator,
final String value, final String operator, final String searchType,
final boolean exists, int timeout) throws StepExecutionException {
invokeAndWait("rcVerifyValueInRow", timeout, new Runnable() { //$NON-NLS-1$
@Override
public void run() {
final ITableComponent adapter =
(ITableComponent) getComponent();
final int implRow = adapter.getRowFromString(row, rowOperator);
// if row is header
boolean result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"rcVerifyValueInRow", new Callable<Boolean>() { //$NON-NLS-1$
@Override
public Boolean call() throws Exception {
boolean valueIsExisting = false;
if (implRow == -1) {
valueIsExisting = (getColumnByName(value,
operator, searchType, adapter,
implRow) != null) ? true : false;
} else {
valueIsExisting = (getColumnByValue(value,
operator, searchType, adapter,
implRow) != null) ? true : false;
}
return valueIsExisting;
}
});
Verifier.equals(exists, result);
}
});
}
/**
* Returns the internal index of the first column which has the given name
* CALL IN JAVAFX-THREAD!
* @param name the name of the column
* @param operator the operator
* @param searchType the searchType
* @param adapter the adapter class
* @param implRow the row
* @return String with the column path or null
*/
private String getColumnByName(final String name, final String operator,
final String searchType, final ITableComponent adapter,
final int implRow) {
return EventThreadQueuerJavaFXImpl.invokeAndWait("getColumnByName", //$NON-NLS-1$
new Callable<String>() {
@Override
public String call() throws Exception {
final int columnCount = adapter.getColumnCount();
if (columnCount > 0) {
List<TableColumn> columns = getColumnsFromTable(
searchType, adapter);
for (TableColumn column : columns) {
if (MatchUtil.getInstance().match(
column.getText(), name, operator)) {
return getColumnPath(column,
(TableView)
getRealComponent());
}
}
}
return null;
}
});
}
/**
* Returns a list of columns. if the search type is "relative" all Columns
* relative to the current selection.
*
* CALL IN JAVAFX-THREAD!
*
* @param searchType the searchType
* @param adapter the adapter
* @return list of columns
*/
private List<TableColumn> getColumnsFromTable(final String searchType,
final ITableComponent adapter) {
ArrayList<TableColumn> columns = new ArrayList<>();
if (searchType
.equalsIgnoreCase(SearchType.relative.rcValue())) {
TableView table = (TableView) adapter.getRealComponent();
TableColumn selColumn = ((TablePosition) table.getSelectionModel()
.getSelectedCells().get(0)).getTableColumn();
TableColumnBase parCol = selColumn.getParentColumn();
while (parCol != null) {
selColumn = (TableColumn) parCol;
parCol = parCol.getParentColumn();
}
columns.addAll(new GenericTraverseHelper<TableColumn, TableColumn>()
.getInstancesOf(
new AbstractTraverser<TableColumn, TableColumn>(
selColumn) {
@Override
public Iterable<TableColumn>
getTraversableData() {
return this.getObject().getColumns();
}
}, TableColumn.class));
} else {
for (TableColumn column : ((TableView<?>) getRealComponent())
.getColumns()) {
columns.addAll(new GenericTraverseHelper
<TableColumn, TableColumn>()
.getInstancesOf(
new AbstractTraverser<TableColumn, TableColumn>(
column) {
@Override
public Iterable<TableColumn>
getTraversableData() {
return this.getObject().getColumns();
}
}, TableColumn.class));
}
columns.addAll(((TableView)adapter.getRealComponent()).
getColumns());
}
return columns;
}
/**
* Returns the internal index of the first column which contains the given value
* CALL IN JAVAFX-THREAD!
* @param value the value
* @param operator the operator
* @param searchType the searchType
* @param adapter the adapter class
* @param implRow the row
* @return String with the column path or null
*/
private String getColumnByValue(final String value, final String operator,
final String searchType, final ITableComponent adapter,
final int implRow) {
return EventThreadQueuerJavaFXImpl.invokeAndWait(
"getColumnByValue", new Callable<String>() { //$NON-NLS-1$
@Override
public String call() {
final int columnCount = adapter.getColumnCount();
if (columnCount > 0) {
int startIndex = getStartingColIndex(searchType)
- 1;
List<TableColumn> columns =
((TableView) getRealComponent())
.getVisibleLeafColumns();
for (int i = startIndex; i < columns.size(); i++) {
TableColumn column = columns.get(i);
int index = adapter.getColumnFromString(
getColumnPath(column,
(TableView) getRealComponent()),
"equals"); //$NON-NLS-1$
String cellValue = adapter.
getCellText(implRow, index);
if (MatchUtil.getInstance().match(
cellValue,
value,
operator)) {
return getColumnPath(column,
(TableView) getRealComponent());
}
}
}
return null;
}
});
}
@Override
public void rcSelectCellByColValue(final String row,
final String rowOperator, final String value,
final String operator, int clickCount,
final String extendSelection, final String searchType,
final int button) {
final ITableComponent adapter = (ITableComponent) getComponent();
final int implRow = adapter.getRowFromString(row, rowOperator);
// if row is header
String result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"rcSelectCellByColValue", new Callable<String>() { //$NON-NLS-1$
@Override
public String call() throws Exception {
if (implRow == -1) {
return getColumnByName(value, operator, searchType,
adapter, implRow);
}
return getColumnByValue(value, operator,
searchType, adapter, implRow);
}
});
if (result == null) {
throw new StepExecutionException("no such cell found", EventFactory //$NON-NLS-1$
.createActionError(TestErrorEvent.NOT_FOUND));
}
rcSelectCell(row, rowOperator, result, operator, clickCount, 50,
ValueSets.Unit.percent.rcValue(), 50,
ValueSets.Unit.percent.rcValue(), extendSelection, button);
}
/**
* @param searchType Determines column where the search begins ("relative" or "absolute")
* @return The index from which to begin a search, based on the search type
* and (if appropriate) the currently selected cell.
*/
private int getStartingColIndex(String searchType) {
int startingIndex = 0;
if (searchType.equalsIgnoreCase(SearchType.relative.rcValue())) {
Cell c = ((ITableComponent)getComponent())
.getSelectedCell();
if (c == null) {
throw new StepExecutionException("No selection found", //$NON-NLS-1$
EventFactory
.createActionError(TestErrorEvent.
NO_SELECTION));
}
startingIndex = c.getCol();
}
return startingIndex + 1;
}
/** {@inheritDoc} */
protected Object getNodeAtMousePosition() throws StepExecutionException {
Point awtPoint = getRobot().getCurrentMousePosition();
final Point2D point = new Point2D(awtPoint.x, awtPoint.y);
Object result = EventThreadQueuerJavaFXImpl.invokeAndWait(
"getNodeAtMousePosition", new Callable<Object>() { //$NON-NLS-1$
@Override
public Object call() throws Exception {
// Update the layout coordinates otherwise
// we would get old position values
((TableView<?>) getRealComponent()).layout();
List<TableCell> tCells = NodeTraverseHelper
.getInstancesOf((Parent) getRealComponent(),
TableCell.class);
for (TableCell cell : tCells) {
if (NodeBounds.checkIfContains(point, cell)) {
return cell;
}
}
throw new StepExecutionException(
"No table node found at mouse position: " //$NON-NLS-1$
+ "X: " + point.getX() //$NON-NLS-1$
+ "Y: " + point.getY(), //$NON-NLS-1$
EventFactory
.createActionError(
TestErrorEvent.NOT_FOUND));
}
});
return result;
}
}