Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static GridPane createSignatureTableRows(ResourceBundle resources,
var moreTextKey = showDocumentContext ? "signature.table.more.documents.txt" : "signature.table.more.txt";
var button = styled(new Button(translate(resources, "signature.table.more.btn")), "autogram-link");
button.setWrapText(true);
button.setOnMouseClicked(event -> callback.accept(null));
button.setOnAction(event -> callback.accept(null));
var flow = styled(new TextFlow(new Text(translate(resources, moreTextKey, totalSignatures - maxRows + 1)), button), "autogram-body", "autogram-font-weight-bold");
table.add(flow, 0, rowIndex, 2, 1);
}
Expand All @@ -85,7 +85,7 @@ public static GridPane createSignatureTableRows(ResourceBundle resources,
public static Button createSignatureTableLink(Consumer<String> callback, ResourceBundle resources) {
var button = styled(new Button(translate(resources, "signature.table.show.btn")), "autogram-link");
button.wrapTextProperty().setValue(true);
button.setOnMouseClicked(event -> callback.accept(null));
button.setOnAction(event -> callback.accept(null));
return button;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package digital.slovensko.autogram.ui.gui;

import digital.slovensko.autogram.ui.SupportedLanguage;
import javafx.application.Platform;
import javafx.event.Event;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.VBox;
import javafx.scene.robot.Robot;
import javafx.stage.Stage;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;

import java.util.Arrays;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.fail;

/** Run with -Dautogram.guiTests=true on a desktop or under xvfb-run. */
@EnabledIfSystemProperty(named = "autogram.guiTests", matches = "true")
class SignatureTableKeyboardTest {
@BeforeAll
static void startJavaFx() throws Exception {
var ready = new FutureTask<Void>(() -> {
Platform.setImplicitExit(false);
return null;
});
try {
Platform.startup(ready);
} catch (IllegalStateException alreadyStarted) {
Platform.runLater(ready);
}
ready.get(10, TimeUnit.SECONDS);
}

@Test
void signatureDetailsAndShowMoreRespondToEnterAndSpace() throws Exception {
onFxThread(() -> {
var count = new AtomicInteger();
var resources = SupportedLanguage.SLOVAK.loadResources();
var details = GUIValidationUtils.createSignatureTableLink(ignored -> count.incrementAndGet(), resources);
// maxRows=1 shows the "show more" button before rendering any signature rows.
var table = GUIValidationUtils.createSignatureTableRows(resources, Arrays.asList(null, null),
false, false, ignored -> count.incrementAndGet(), 1);
var stage = new Stage();
stage.setScene(new Scene(new VBox(details, table)));
stage.show();
try {
var more = table.lookupAll(".button").stream().map(Button.class::cast)
.filter(button -> button.getText().equals(resources.getString("signature.table.more.btn")))
.findFirst().orElseThrow();
for (var button : new Button[]{details, more}) {
button.requestFocus();
assertSame(button, stage.getScene().getFocusOwner());
press(button, KeyCode.ENTER);
assertEquals(1, count.getAndSet(0), button.getText() + " with Enter");
press(button, KeyCode.SPACE);
assertEquals(1, count.getAndSet(0), button.getText() + " with Space");
}
} finally {
stage.close();
}
return null;
});
}

@Test
void clickingSignatureDetailsRunsTheSameAction() throws Exception {
var count = new AtomicInteger();
var stage = onFxThread(() -> {
var button = GUIValidationUtils.createSignatureTableLink(ignored -> count.incrementAndGet(),
SupportedLanguage.SLOVAK.loadResources());
var window = new Stage();
window.setScene(new Scene(new VBox(button), 320, 100));
window.show();
return window;
});
try {
onFxThread(() -> {
var button = (Button) stage.getScene().getRoot().getChildrenUnmodifiable().getFirst();
var bounds = button.localToScreen(button.getBoundsInLocal());
var robot = new Robot();
robot.mouseMove(bounds.getCenterX(), bounds.getCenterY());
robot.mouseClick(MouseButton.PRIMARY);
return null;
});
var deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(5);
while (count.get() == 0 && System.nanoTime() < deadline)
Thread.sleep(20);
if (count.get() == 0)
fail("Mouse click did not activate signature details");
assertEquals(1, count.get());
} finally {
onFxThread(() -> { stage.close(); return null; });
}
}

private static void press(Button button, KeyCode code) {
Event.fireEvent(button, new KeyEvent(KeyEvent.KEY_PRESSED, "", "", code, false, false, false, false));
Event.fireEvent(button, new KeyEvent(KeyEvent.KEY_RELEASED, "", "", code, false, false, false, false));
}

private static <T> T onFxThread(java.util.concurrent.Callable<T> action) throws Exception {
var task = new FutureTask<>(action);
Platform.runLater(task);
return task.get(10, TimeUnit.SECONDS);
}
}
Loading