import impl.org.controlsfx.spreadsheet.CellView;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import org.controlsfx.control.spreadsheet.SpreadsheetCell;
import org.controlsfx.control.spreadsheet.SpreadsheetView;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.testfx.api.FxRobot;
import org.testfx.api.FxToolkit;
import org.testfx.service.query.NodeQuery;
public class SpreadsheetViewTest {
static SpreadsheetView view;
public FxRobot fx = new FxRobot();
@BeforeClass
public static void setup() throws Exception {
FxToolkit.registerPrimaryStage();
FxToolkit.setupStage((stage) -> {
view = new SpreadsheetView();
stage.setScene(new Scene(view, 500, 500));
});
FxToolkit.showStage();
}
@AfterClass
public static void cleanup() throws Exception {
FxToolkit.hideStage();
}
@Test
public void selectCellAfterEnterIsPressed() {
//Find first cell
NodeQuery query = fx.lookup((Node t) -> {
if ((t instanceof CellView) && ((CellView) t).getItem() != null) {
SpreadsheetCell cell = ((CellView) t).getItem();
if (cell.getRow() == 0 && cell.getColumn() == 0) {
return true;
}
}
return false;
});
Node cell = query.queryFirst();
Assert.assertNotNull(cell);
fx.doubleClickOn(cell);
TextField editor = fx.from(cell).lookup((Node t) -> t instanceof TextField).queryFirst();
Assert.assertNotNull(editor);
fx.clickOn(editor).write("test");
fx.type(KeyCode.ENTER);
fx.doubleClickOn(cell);
NodeQuery query2 = fx.lookup((Node t) -> {
if ((t instanceof CellView) && ((CellView) t).getItem() != null) {
SpreadsheetCell cell1 = ((CellView) t).getItem();
if (cell1.getRow() == 5 && cell1.getColumn() == 1) {
return true;
}
}
return false;
});
Node cell2 = query2.queryFirst();
Assert.assertNotNull(cell2);
fx.clickOn(cell2);
Assert.assertEquals(5, view.getSelectionModel().getSelectedIndex());
}
}
>Should I extend "ApplicationTest" instead? Should I extend FXRobot?--
You received this message because you are subscribed to the Google Groups "TestFX" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testfx-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Thank you for your very detailed response Benjamin!
So basically, I could extend from FxRobot and use FxToolkit for my tests right? For example I could initialize a Stage before all the tests and destroy it after. And before each test, initialize a SpreadsheetView that I will put in the Scene somehow? That could be a good workflow?
Because I started to extend from ApplicationTest and I saw a "start" method so I wasn't very sure of how to write the tests. Since ApplicationTest do only one test within the start method? Should I write more test with "@Test" annotation? I wasn't sure so I decided to go with the other solution.
I've seen everybody talk about the "getRootNode()" method, this have been removed? Now with FxToolkit, I can easily place my Node into the Scene?
Does the lookup method faster with CSS ID rather than Predicate? I saw that it is better to use the "from(Node)" method before using lookup in order to narrow the search right?
I don't think a SpreadsheetViewMatcher will make sense.. At least it will do for me but it should be private to my tests. But I can improve the TableViewMatcher since I will be using a lot from that.
Also, in order to use the Glass robot, are we compelled to use the JVM option? Can't we specify that somehow in the code?
I saw that you needed Javadoc and examples, I'll maybe submit some ideas in your Github if you're interested. Since I was new to TestFX I might be able to write the basic questions/answer in order to begin writting some simple tests.
Keep up the great work!
<dependency>
<groupId>org.jfxtras</groupId>
<artifactId>openjfx-monocle</artifactId>
<version>1.8.0_20</version>
<scope>test</scope>
</dependency>
//Find first cell
NodeQuery query = findCell(view, 0, 0);
CellView cell = query.queryFirst();
Assert.assertNotNull(cell);
doubleClickOn(cell);
TextField editor = (TextField) cell.getGraphic();
Assert.assertNotNull(editor);
gradlew clean jar
I've managed to run in headless mode but I needed to set the properties directly using "System.setProperty" in my "@BeforeClass".. Because if I set the arguments through the JVM via "-DXXX=XX" it was not working.. But maybe my Netbeans configurations is wrong I don't know..
So the headless mode was working I guess (I wasn't seeing anything on my screen so that should be a clue no? ^^)
In fact it's failing here, the editor is null. So apparently, the double click is not bringing the editor in the cell. Do you have any clue on that?
So I'll stick to the non headless mode right now but I hope to resolve that problem later. And by the way, I have a click and drag and drop test and it's apparently working with Monocle in Headless so good news huh?
FxToolkit.registerPrimaryStage();
FxToolkit.showStage();
FxToolkit.showStage(); ?
So now all tests are passing except for one, that is passing in non-headless but not in headless. If you have time, I would appreciate if you could take a look and tell me what is wrong. Basically, I set a Stage in the BeforeClass, and I want to keep it, and just instantiate a SpreadsheetView before each test. But I seem to be doing it wrong..
package com.nellarmonia.shuttlefx;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import com.sun.javafx.tk.Toolkit;
import impl.org.controlsfx.spreadsheet.CellView;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.input.KeyCode;
import org.controlsfx.control.spreadsheet.SpreadsheetCell;
import org.controlsfx.control.spreadsheet.SpreadsheetView;
import org.junit.Before;
import org.junit.Test;
import org.testfx.api.FxRobot;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.testfx.api.FxToolkit;
import static org.testfx.api.FxToolkit.registerPrimaryStage;
import static org.testfx.api.FxToolkit.setupStage;
import org.testfx.service.query.NodeQuery;
public class TestLol extends FxRobot {
static SpreadsheetView view;
static {
System.setProperty("testfx.robot", "glass");
System.setProperty("testfx.headless", "true");
System.setProperty("prism.order", "sw");
System.setProperty("prism.text", "t2k");
}
@BeforeClass
public static void beforeClass() throws Exception {
registerPrimaryStage();
setupStage(stage -> {
view = new SpreadsheetView();
StackPane sceneRoot = new StackPane(view);
stage.setScene(new Scene(sceneRoot, 400, 400));
stage.setX(0);
stage.setY(0);
stage.show();
});
}
@Before
public void before() throws Exception {
FxToolkit.setupSceneRoot(new Supplier<Parent>() {
@Override
public Parent get() {
view = new SpreadsheetView();
StackPane sceneRoot = new StackPane(view);
return sceneRoot;
}
});
}
@Test
public void testPressingTab() {
CellView cell = findCell(view, 0, 0).queryFirst();
Assert.assertNotNull(cell);
//Select first
clickOn(cell);
type(KeyCode.TAB);
verifySelectedCell(view, 0, 1);
TableView<ObservableList<SpreadsheetCell>> tableView = getTableView();
try {
//Select last on line
FxToolkit.setupFixture(() -> {
tableView.scrollToColumnIndex(view.getGrid().getColumnCount() - 1);
Toolkit.getToolkit().firePulse();
});
} catch (TimeoutException ex) {
Logger.getLogger(KeyTest.class.getName()).log(Level.SEVERE, null, ex);
}
cell = findCell(view, 0, view.getGrid().getColumnCount() - 1).queryFirst();
Assert.assertNotNull(cell);
clickOn(cell);
type(KeyCode.TAB);
verifySelectedCell(view, 1, 0);
try {
//Select last
FxToolkit.setupFixture(() -> {
tableView.scrollToColumnIndex(view.getGrid().getColumnCount() - 1);
tableView.scrollTo(view.getGrid().getRowCount() - 1);
Toolkit.getToolkit().firePulse();
});
} catch (TimeoutException ex) {
Logger.getLogger(KeyTest.class.getName()).log(Level.SEVERE, null, ex);
}
cell = findCell(view, view.getGrid().getRowCount() - 1, view.getGrid().getColumnCount() - 1).queryFirst();
Assert.assertNotNull(cell);
clickOn(cell);
type(KeyCode.TAB);
verifySelectedCell(view, view.getGrid().getRowCount() - 1, view.getGrid().getColumnCount() - 1);
}
protected TableView<ObservableList<SpreadsheetCell>> getTableView() {
return view.getSelectionModel().getTableView();
}
/**
* Verify that only the specified row and column intersection is selected.
*
* @param view
* @param row
* @param column
*/
protected void verifySelectedCell(SpreadsheetView view, int row, int column) {
for (TablePosition pos : view.getSelectionModel().getSelectedCells()) {
SpreadsheetCell cell = view.getGrid().getRows().get(pos.getRow()).get(pos.getColumn());
Assert.assertEquals(row, cell.getRow());
Assert.assertEquals(column, cell.getColumn());
}
}
protected NodeQuery findCell(SpreadsheetView view, int row, int column) {
return from(view).lookup((Node t) -> {
if ((t instanceof CellView) && ((CellView) t).getItem() != null) {
SpreadsheetCell cell1 = ((CellView) t).getItem();
if (cell1.getRow() == row && cell1.getColumn() == column) {
return true;
}
}
return false;
});
}
}
--
import java.util.concurrent.TimeoutException;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.testfx.api.FxToolkit;
import static org.testfx.api.FxToolkit.setupStage;
public class LolTest extends SpreadsheetUtils {
protected Label label;
@BeforeClass
public static void setupClass() throws TimeoutException {
FxToolkit.registerPrimaryStage();
}
@Before
public void setup() throws Exception {
setupStage(localStage -> {
label = new Label();
label.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Assert.assertTrue(event.isShortcutDown());
}
});
StackPane sceneRoot = new StackPane(label);
localStage.setScene(new Scene(sceneRoot, 1000, 800));
localStage.setX(0);
localStage.setY(0);
localStage.show();
});
}
@After
public void after() throws TimeoutException {
FxToolkit.cleanupStages();
FxToolkit.hideStage();
}
@Test
public void test_shortcut(){
press(KeyCode.SHORTCUT);
clickOn(label);
}
}
import java.util.concurrent.TimeoutException;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.testfx.api.FxRobot;
import org.testfx.api.FxToolkit;
import static org.testfx.api.FxToolkit.setupStage;
public class PressTest extends FxRobot{
static {
System.setProperty("testfx.robot", "glass");
// System.setProperty("testfx.headless", "true");
System.setProperty("prism.order", "sw");
System.setProperty("prism.text", "t2k");
}
protected Label label;
@BeforeClass
public static void setupClass() throws TimeoutException {
FxToolkit.registerPrimaryStage();
}
@Before
public void setup() throws Exception {
setupStage(localStage -> {
label = new Label();
label.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
Assert.assertTrue(event.isShiftDown());
}
});
StackPane sceneRoot = new StackPane(label);
localStage.setScene(new Scene(sceneRoot, 1000, 800));
localStage.setX(0);
localStage.setY(0);
localStage.show();
});
}
@After
public void after() throws TimeoutException {
FxToolkit.cleanupStages();
FxToolkit.hideStage();
}
@Test
public void test_shift(){
press(KeyCode.SHIFT);
clickOn(label);
release(KeyCode.SHIFT);
}
}
import java.util.concurrent.TimeoutException;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.testfx.api.FxRobot;
import org.testfx.api.FxToolkit;
import static org.testfx.api.FxToolkit.setupStage;
public class PressTest extends FxRobot{
static {
System.setProperty("testfx.robot", "glass");
// System.setProperty("testfx.headless", "true");
System.setProperty("prism.order", "sw");
System.setProperty("prism.text", "t2k");
}
protected Label label;
release(KeyCode.SHORTCUT);
}
}