All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sitoolkit.wt.gui.pres.editor.TestScriptEditor Maven / Gradle / Ivy

package io.sitoolkit.wt.gui.pres.editor;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.commons.lang3.StringUtils;
import org.controlsfx.control.spreadsheet.Grid;
import org.controlsfx.control.spreadsheet.GridBase;
import org.controlsfx.control.spreadsheet.GridChange;
import org.controlsfx.control.spreadsheet.SpreadsheetCell;
import org.controlsfx.control.spreadsheet.SpreadsheetCellType;
import org.controlsfx.control.spreadsheet.SpreadsheetColumn;
import org.controlsfx.control.spreadsheet.SpreadsheetView;
import org.controlsfx.control.spreadsheet.SpreadsheetViewSelectionModel;

import io.sitoolkit.wt.domain.testscript.Locator;
import io.sitoolkit.wt.domain.testscript.TestScript;
import io.sitoolkit.wt.domain.testscript.TestStep;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TablePosition;

public class TestScriptEditor {

    private static final int COLUMN_INDEX_FIRST_CASE = 8;
    private static final int ROW_INDEX_FIRST_STEP = 1;

    public SpreadsheetView buildSpreadsheet(TestScript testScript) {

        Collection> rows = FXCollections.observableArrayList();

        ObservableList headerCells = FXCollections.observableArrayList();
        testScript.getHeaders().forEach(header -> {
            SpreadsheetCell headerCell = SpreadsheetCellType.STRING.createCell(rows.size(),
                    headerCells.size(), 1, 1, header);
            boolean editable = (headerCells.size() < 8) ? false : true;
            headerCell.setEditable(editable);
            headerCells.add(headerCell);
        });
        rows.add(headerCells);

        testScript.getTestStepList().stream().forEach(testStep -> {
            ObservableList cells = FXCollections.observableArrayList();

            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getNo()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getItemName()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getOperationName()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getLocator().getType()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getLocator().getValue()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getDataType()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getScreenshotTiming()));
            cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                    testStep.getBreakPoint()));

            testStep.getTestData().values().stream().forEach(testData -> {
                cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), cells.size(), 1, 1,
                        testData));
            });
            rows.add(cells);
        });

        Grid grid = new GridBase(10, 10);
        grid.setRows(rows);

        SpreadsheetView spreadSheet = new SpreadsheetView(grid);
        spreadSheet.setShowColumnHeader(true);
        spreadSheet.setShowRowHeader(true);
        spreadSheet.setId(testScript.getScriptFile().getAbsolutePath());
        spreadSheet.getStylesheets().add(
                getClass().getResource("/testScriptEditor.css").toExternalForm());

        new TestScriptEditorController(spreadSheet);

        return spreadSheet;
    }

    public TestScript buildTestscript(SpreadsheetView spreadSheet) {
        TestScript testScript = new TestScript();
        testScript.setScriptFile(new File(spreadSheet.getId()));

        ObservableList> rows = spreadSheet.getGrid().getRows();

        List headers = rows.iterator().next().stream().map(SpreadsheetCell::getText)
                .collect(Collectors.toList());
        headers.stream().forEach(header -> testScript.addHeader(header));

        List testStepList = new ArrayList();
        rows.stream().skip(1L).forEach(row -> {
            TestStep testStep = new TestStep();
            testStep.setNo(row.get(0).getText());
            testStep.setItemName(row.get(1).getText());
            testStep.setOperationName(row.get(2).getText());
            Locator locator = new Locator();
            locator.setType(row.get(3).getText());
            locator.setValue(row.get(4).getText());
            testStep.setLocator(locator);
            testStep.setDataType(row.get(5).getText());
            testStep.setScreenshotTiming(row.get(6).getText());
            testStep.setBreakPoint(row.get(7).getText());

            Map testData = new LinkedHashMap();
            for (int idx = 8; idx < row.size(); idx++) {
                String caseNo = (headers.get(idx).startsWith(testScript.getCaseNoPrefix())) ?
                        StringUtils.substringAfter(headers.get(idx), testScript.getCaseNoPrefix()) : headers.get(idx);
                testData.put(caseNo, row.get(idx).getText());
            }
            testStep.setTestData(testData);
            testStepList.add(testStep);
        });

        testScript.setTestStepList(testStepList);

        return testScript;
    }

    public void appendTestCase(SpreadsheetView spreadSheet) {
        appendTestCases(spreadSheet, 1);
    }

    public void appendTestCases(SpreadsheetView spreadSheet, int count) {
        insertTestCases(spreadSheet, spreadSheet.getGrid().getColumnCount(), count);
    }

    public void appendTestStep(SpreadsheetView spreadSheet) {
        appendTestSteps(spreadSheet, 1);
    }

    public void appendTestSteps(SpreadsheetView spreadSheet, int count) {
        insertTestSteps(spreadSheet, spreadSheet.getGrid().getRowCount(), count);
    }

    public boolean insertTestCase(SpreadsheetView spreadSheet) {
        return insertTestCases(spreadSheet, getSelectedColumnCount(spreadSheet));
    }

    public boolean insertTestCases(SpreadsheetView spreadSheet, int count) {
        Optional insertPosition = getInsertColumnPosition(spreadSheet);
        insertPosition.ifPresent(colPosition -> insertTestCases(spreadSheet, colPosition, count));
        return insertPosition.isPresent();
    }

    public boolean insertTestStep(SpreadsheetView spreadSheet) {
        return insertTestSteps(spreadSheet, getSelectedRowCount(spreadSheet));
    }

    public boolean insertTestSteps(SpreadsheetView spreadSheet, int count) {
        Optional insertPosition = getInsertRowPosition(spreadSheet);
        insertPosition.ifPresent(rowPosition -> insertTestSteps(spreadSheet, rowPosition, count));
        return insertPosition.isPresent();

    }

    public void deleteTestCase(SpreadsheetView spreadSheet) {
        Set deleteColumns = getSelectedCase(spreadSheet);

        ObservableList> rows = spreadSheet.getGrid().getRows();
        ObservableList columns = spreadSheet.getColumns();
        List widths = columns.stream()
                .map(SpreadsheetColumn::getWidth)
                .collect(Collectors.toCollection(LinkedList::new));

        rows.stream().forEach(row -> {
            deleteColumns.stream()
                    .sorted(Comparator.reverseOrder())
                    .mapToInt(Integer::intValue)
                    .forEachOrdered(row::remove);
        });
        deleteColumns.stream()
                .sorted(Comparator.reverseOrder())
                .mapToInt(Integer::intValue)
                .forEachOrdered(widths::remove);

        Grid newGrid = new GridBase(10, 10);
        newGrid.setRows(recreateRows(rows));
        spreadSheet.setGrid(newGrid);

        IntStream.range(0, widths.size()).forEach(i -> columns.get(i).setPrefWidth(widths.get(i)));
    }

    public void deleteTestStep(SpreadsheetView spreadSheet) {
        Set deleteRows = getSelectedStep(spreadSheet);

        ObservableList> rows = spreadSheet.getGrid().getRows();
        deleteRows.stream()
                .sorted(Comparator.reverseOrder())
                .mapToInt(Integer::intValue)
                .forEachOrdered(rows::remove);

        Grid newGrid = new GridBase(10, 10);
        newGrid.setRows(recreateRows(rows));
        spreadSheet.setGrid(newGrid);

    }

    public boolean isCaseInsertable(SpreadsheetView spreadSheet) {
        return getInsertColumnPosition(spreadSheet).isPresent();
    }

    public boolean isStepInsertable(SpreadsheetView spreadSheet) {
        return getInsertRowPosition(spreadSheet).isPresent();
    }

    public boolean isCaseSelected(SpreadsheetView spreadSheet) {
        return !getSelectedCase(spreadSheet).isEmpty();
    }

    public boolean isStepSelected(SpreadsheetView spreadSheet) {
        return !getSelectedStep(spreadSheet).isEmpty();
    }

    public int getCaseCount(SpreadsheetView spreadSheet, List changeList) {
        int columnCount = getColumnCount(changeList);
        int rowCount = getRowCount(changeList);
        return spreadSheet.getGrid().getRowCount() == rowCount ? columnCount : 0;
    }

    public int getStepCount(SpreadsheetView spreadSheet, List changeList) {
        int columnCount = getColumnCount(changeList);
        int rowCount = getRowCount(changeList);
        return spreadSheet.getGrid().getColumnCount() == columnCount ? rowCount : 0;
    }

    private int getColumnCount(List changeList) {
        Set colSet = changeList.stream().map(change -> change.getColumn()).collect(Collectors.toSet());
        return countMinToMax(colSet);
    }

    private int getRowCount(List changeList) {
        Set rowSet = changeList.stream().map(change -> change.getRow()).collect(Collectors.toSet());
        return countMinToMax(rowSet);
    }

    private int countMinToMax(Collection values) {
        return values.stream().max(Comparator.naturalOrder()).get()
                - values.stream().min(Comparator.naturalOrder()).get() + 1;

    }

    private Optional getInsertColumnPosition(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        Optional selectedMin = selectedCells.stream().map(TablePosition::getColumn).distinct()
                .min(Comparator.naturalOrder());

        return selectedMin.filter(this::isCaseColumn);
    }

    private Optional getInsertRowPosition(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        Optional selectedMin = selectedCells.stream().map(TablePosition::getRow).distinct()
                .min(Comparator.naturalOrder());

        return selectedMin.filter(this::isStepRow);
    }

    private int getSelectedRowCount(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        return (int) selectedCells.stream().map(TablePosition::getRow).distinct().count();
    }

    private int getSelectedColumnCount(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        return (int) selectedCells.stream().map(TablePosition::getColumn).distinct().count();
    }

    private Set getSelectedCase(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        Map map = new HashMap<>();
        selectedCells.stream().forEach(cell -> {
            int col = cell.getColumn();
            Optional count = Optional.ofNullable(map.get(col));
            map.put(col, count.orElse(0) + 1);
        });

        int gridRowCount = spreadSheet.getGrid().getRowCount();
        boolean onlyCaseSelected = map.entrySet().stream().allMatch(entity -> {
            return isCaseColumn(entity.getKey()) && entity.getValue() == gridRowCount;
        });

        return onlyCaseSelected ? map.keySet() : Collections.emptySet();

    }

    private Set getSelectedStep(SpreadsheetView spreadSheet) {

        @SuppressWarnings("rawtypes")
        ObservableList selectedCells = spreadSheet.getSelectionModel().getSelectedCells();

        Map map = new HashMap<>();
        selectedCells.stream().forEach(cell -> {
            int row = cell.getRow();
            Optional count = Optional.ofNullable(map.get(row));
            map.put(row, count.orElse(0) + 1);
        });

        int gridColumnCount = spreadSheet.getGrid().getColumnCount();
        boolean onlyStepSelected = map.entrySet().stream().allMatch(entity -> {
            return isStepRow(entity.getKey()) && entity.getValue() == gridColumnCount;
        });

        return onlyStepSelected ? map.keySet() : Collections.emptySet();

    }

    private boolean isCaseColumn(int columnPosition) {
        return columnPosition >= COLUMN_INDEX_FIRST_CASE;
    }

    private boolean isStepRow(int rowPosition) {
        return rowPosition >= ROW_INDEX_FIRST_STEP;
    }

    private Optional getColumnPosition(SpreadsheetView spreadSheet, int caseIndex) {
        int columnCount = spreadSheet.getGrid().getColumnCount();
        int position = COLUMN_INDEX_FIRST_CASE + caseIndex;
        return Optional.of(position)
                .filter(p -> p >= COLUMN_INDEX_FIRST_CASE && p < columnCount);
    }

    private Optional getRowPosition(SpreadsheetView spreadSheet, int stepIndex) {
        int rowCount = spreadSheet.getGrid().getRowCount();
        int position = ROW_INDEX_FIRST_STEP + stepIndex;
        return Optional.of(position)
                .filter(p -> p >= ROW_INDEX_FIRST_STEP && p < rowCount);
    }

    private void insertTestSteps(SpreadsheetView spreadSheet, int rowPosition, int rowCount) {

        Grid grid = spreadSheet.getGrid();
        int columnCount = grid.getColumnCount();

        ObservableList> rows = grid.getRows();
        ObservableList cells = FXCollections.observableArrayList();

        IntStream.range(0, rowCount).forEachOrdered(i -> {
            IntStream.range(0, columnCount).forEachOrdered(j -> {
                cells.add(SpreadsheetCellType.STRING.createCell(rows.size(), j, 1, 1, ""));
            });
            rows.add(rowPosition, cells);
        });
        grid.setRows(recreateRows(rows));

        SpreadsheetViewSelectionModel selection = spreadSheet.getSelectionModel();
        selection.clearSelection();
        selection.selectRange(rowPosition, spreadSheet.getColumns().get(0),
                rowPosition + rowCount - 1, spreadSheet.getColumns().get(spreadSheet.getColumns().size() - 1));
    }

    private void insertTestCases(SpreadsheetView spreadSheet, int columnPosition, int columnCount) {

        ObservableList> rows = spreadSheet.getGrid().getRows();
        IntStream.range(0, rows.size()).forEach(i -> {
            IntStream.range(columnPosition, columnPosition + columnCount).forEachOrdered(j -> {
                SpreadsheetCell cell = SpreadsheetCellType.STRING.createCell(i, j, 1, 1, "");
                rows.get(i).add(j, cell);
            });
        });
        ObservableList columns = spreadSheet.getColumns();
        List widths = columns.stream().map(col -> col.getWidth()).collect(Collectors.toList());
        IntStream.range(columnPosition, columnPosition + columnCount).forEachOrdered(j -> {
            widths.add(j, widths.get(j - 1));
        });

        Grid newGrid = new GridBase(10, 10);
        newGrid.setRows(recreateRows(rows));
        spreadSheet.setGrid(newGrid);
        IntStream.range(columnPosition, columns.size()).forEach(i -> columns.get(i).setPrefWidth(widths.get(i)));

        SpreadsheetViewSelectionModel selection = spreadSheet.getSelectionModel();
        selection.clearSelection();
        selection.selectRange(0, spreadSheet.getColumns().get(columnPosition),
                spreadSheet.getGrid().getRowCount() - 1,
                spreadSheet.getColumns().get(columnPosition + columnCount - 1));
    }

    private ObservableList> recreateRows(
            ObservableList> original) {
        ObservableList> rows = FXCollections.observableArrayList();
        rows.addAll(
                IntStream.range(0, original.size())
                        .mapToObj(row -> recreateRow(original.get(row), row))
                        .collect(Collectors.toList()));
        return rows;

    }

    private ObservableList recreateRow(ObservableList original, int row) {
        ObservableList cells = FXCollections.observableArrayList();
        cells.addAll(
                IntStream.range(0, original.size())
                        .mapToObj(column -> recreateCell(original.get(column), row, column))
                        .collect(Collectors.toList()));

        return cells;
    }

    private SpreadsheetCell recreateCell(SpreadsheetCell original, int row, int column) {
        SpreadsheetCell cell = SpreadsheetCellType.STRING.createCell(row, column, original.getRowSpan(),
                original.getColumnSpan(), original.getText());
        boolean editable = (row == 0 && column < 8) ? false : true;
        cell.setEditable(editable);
        return cell;
    }

    private void setStyle(SpreadsheetView spreadSheet, int stepIndex, int caseIndex, String stepStyle,
            String caseStyle) {

        ObservableList> rows = spreadSheet.getGrid().getRows();

        getRowPosition(spreadSheet, stepIndex).ifPresent(position -> {
            rows.get(position).stream().forEach(cell -> {
                cell.getStyleClass().add(stepStyle);
            });
        });

        getColumnPosition(spreadSheet, caseIndex).ifPresent(position -> {
            rows.stream().forEach(row -> {
                row.get(position).getStyleClass().add(caseStyle);
            });
        });
    }

    public void setDebugStyle(SpreadsheetView spreadSheet, int stepIndex, int caseIndex) {
        removeDebugStyle(spreadSheet);
        setStyle(spreadSheet, stepIndex, caseIndex, "debugStep","debugCase");
    }

    public void removeDebugStyle(SpreadsheetView spreadSheet) {
        spreadSheet.getGrid().getRows().stream()
                .flatMap(ObservableList::stream)
                .forEach(cell -> {
                    cell.getStyleClass().remove("debugStep");
                    cell.getStyleClass().remove("debugCase");
                });
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy