From b389480cc83429010a7be7a2d02f9520cb9bb4e6 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 5 Feb 2026 19:30:42 +0100 Subject: [PATCH] wip: input data fixed --- .../lcc/e2e/pages/CalculationEditPage.java | 93 ++++++++++++------- .../de/avatic/lcc/e2e/testdata/TestCases.java | 28 +++--- 2 files changed, 73 insertions(+), 48 deletions(-) diff --git a/src/test/java/de/avatic/lcc/e2e/pages/CalculationEditPage.java b/src/test/java/de/avatic/lcc/e2e/pages/CalculationEditPage.java index 1e51b80..83ba065 100644 --- a/src/test/java/de/avatic/lcc/e2e/pages/CalculationEditPage.java +++ b/src/test/java/de/avatic/lcc/e2e/pages/CalculationEditPage.java @@ -411,27 +411,30 @@ public class CalculationEditPage extends BasePage { final Object vueResult = result; logger.info(() -> "Vue component route selection result: " + vueResult); - String resultStr = String.valueOf(result); + // Always try click simulation as the primary method - it's most reliable + logger.info("Using click simulation to select route"); + Locator routeToClick = allRoutes.nth(routeIndexToSelect); + simulateRobustClick(routeToClick); - // If Vue approach failed, try direct Pinia manipulation - if (resultStr.startsWith("error") || resultStr.equals("no_vue_component") || resultStr.equals("no_routes_cell")) { - logger.info("Vue component approach failed, trying Pinia direct access"); + // Wait for UI update + page.waitForTimeout(500); + + // Verify selection worked + boolean selected = verifyRouteSelectionVisual(allRoutes.nth(routeIndexToSelect)); + + // If click didn't work, try Pinia as fallback + if (!selected) { + logger.info("Click simulation didn't select route, trying Pinia direct access"); Object piniaResult = tryPiniaDirectAccess(routeIndexToSelect); final Object piniaResultFinal = piniaResult; logger.info(() -> "Pinia direct access result: " + piniaResultFinal); - resultStr = String.valueOf(piniaResult); + page.waitForTimeout(300); + selected = verifyRouteSelectionVisual(allRoutes.nth(routeIndexToSelect)); } - // If still failed, try clicking with proper event simulation - if (resultStr.startsWith("error") || resultStr.startsWith("no_")) { - logger.info("Trying robust click simulation"); - Locator routeToClick = allRoutes.nth(routeIndexToSelect); - simulateRobustClick(routeToClick); + if (!selected) { + logger.warning(() -> "Route selection may have failed for index " + routeIndexToSelect); } - - // Wait and verify - page.waitForTimeout(300); - verifyRouteSelectionVisual(allRoutes.nth(routeIndexToSelect)); } /** @@ -499,51 +502,73 @@ public class CalculationEditPage extends BasePage { /** * Verify route selection is visible in the DOM. + * @return true if the route appears selected, false otherwise */ - private void verifyRouteSelectionVisual(Locator routeElement) { + private boolean verifyRouteSelectionVisual(Locator routeElement) { try { Locator innerContainer = routeElement.locator(".destination-route-inner-container"); if (innerContainer.count() > 0) { String classes = innerContainer.getAttribute("class"); boolean selected = classes != null && classes.contains("selected"); logger.info(() -> "Route visual verification - classes: " + classes + ", selected: " + selected); + return selected; } } catch (Exception e) { logger.warning(() -> "Could not verify route selection: " + e.getMessage()); } + return false; } /** - * Find best matching route from DOM elements. + * Find exact matching route from DOM elements. + * The route must contain all spec segments in order, and the route text + * (when normalized) should match the concatenated spec segments. + * + * @throws IllegalStateException if no exact match is found */ private int findBestMatchingRouteIndexFromDom(Locator allRoutes, String routeSpec) { int routeCount = allRoutes.count(); - if (routeSpec == null || routeSpec.isEmpty() || routeCount == 0) { - return 0; + if (routeSpec == null || routeSpec.isEmpty()) { + return 0; // No route specified, use first available + } + if (routeCount == 0) { + throw new IllegalStateException("No routes available, but route spec was: " + routeSpec); } - String[] segments = routeSpec.split(","); - int bestMatchCount = 0; - int bestIndex = 0; + String[] specSegments = routeSpec.split(","); + // Build expected route text by concatenating segments (routes display without separators) + StringBuilder expectedBuilder = new StringBuilder(); + for (String segment : specSegments) { + expectedBuilder.append(segment.trim().toLowerCase().replace("_", " ")); + } + String expectedRouteText = expectedBuilder.toString(); + + // Find exact match for (int i = 0; i < routeCount; i++) { - String routeText = allRoutes.nth(i).textContent().toLowerCase(); - int matchCount = 0; + String routeText = allRoutes.nth(i).textContent().toLowerCase().trim(); + // Remove common whitespace/separator variations + String normalizedRouteText = routeText.replaceAll("\\s+", "").replace(">", ""); + String normalizedExpected = expectedRouteText.replaceAll("\\s+", ""); - for (String segment : segments) { - String normalized = segment.trim().toLowerCase().replace("_", " "); - if (routeText.contains(normalized)) { - matchCount++; - } - } - - if (matchCount > bestMatchCount) { - bestMatchCount = matchCount; - bestIndex = i; + if (normalizedRouteText.equals(normalizedExpected)) { + final int matchedIndex = i; + final String matchedRoute = routeText; + logger.info(() -> "Exact route match found at index " + matchedIndex + ": " + matchedRoute); + return i; } } - return bestIndex; + // No exact match found - log available routes and fail + StringBuilder availableRoutes = new StringBuilder("Available routes:\n"); + for (int i = 0; i < routeCount; i++) { + availableRoutes.append(" ").append(i).append(": ").append(allRoutes.nth(i).textContent().trim()).append("\n"); + } + + throw new IllegalStateException( + "No exact route match found for spec: '" + routeSpec + "' (expected: '" + expectedRouteText + "')\n" + + availableRoutes.toString() + ); } diff --git a/src/test/java/de/avatic/lcc/e2e/testdata/TestCases.java b/src/test/java/de/avatic/lcc/e2e/testdata/TestCases.java index d4424c3..2ee70b1 100644 --- a/src/test/java/de/avatic/lcc/e2e/testdata/TestCases.java +++ b/src/test/java/de/avatic/lcc/e2e/testdata/TestCases.java @@ -46,7 +46,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(5) .d2d(false) - .route("Ireland supplier,HH") + .route("IE SUP,HH") .customHandling(false) .build() )) @@ -108,7 +108,7 @@ public final class TestCases { .name("Geisa (KION plant)") .quantity(3500) .d2d(false) - .route("HH, WH STO,FGG") + .route("HH,WH STO,FGG") .handlingCost(3.5) .repackingCost(2.7) .disposalCost(6.5) @@ -118,7 +118,7 @@ public final class TestCases { .name("Aschaffenburg (KION plant)") .quantity(25000) .d2d(false) - .route("HH, WH ULHA, AB") + .route("HH,WH ULHA,AB") .handlingCost(3.0) .repackingCost(3.3) .disposalCost(8.0) @@ -190,14 +190,14 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(60000) .d2d(false) - .route("Turkey supplier,WH HH,HH") + .route("Turkey sup ...,WH HH,HH") .customHandling(false) .build(), DestinationInput.builder() .name("Aschaffenburg (KION plant)") .quantity(80000) .d2d(false) - .route("Turkey supplier,WH ULHA,AB") + .route("Turkey sup ...,WH ULHA,AB") .handlingCost(6.0) .repackingCost(6.0) .disposalCost(6.0) @@ -207,7 +207,7 @@ public final class TestCases { .name("Luzzara (KION plant)") .quantity(30000) .d2d(false) - .route("Turkey supplier,LZZ") + .route("Turkey sup ...,LZZ") .customHandling(false) .build() )) @@ -283,7 +283,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(60000) .d2d(false) - .route("Turkey supplier,WH HH,HH") + .route("Turkey sup ...,WH HH,HH") .customHandling(false) .build() )) @@ -345,7 +345,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(1200000) .d2d(true) - .route("Turkey supplier,WH HH, HH") + .route("Turkey sup ...,WH HH,HH") .d2dCost(6500.0) .d2dDuration(47) .customHandling(false) @@ -409,7 +409,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(500) .d2d(true) - .route("Ireland supplier,WH HH, HH") + .route("IE SUP,WH HH,HH") .d2dCost(2500.0) .d2dDuration(12) .handlingCost(120.0) @@ -421,7 +421,7 @@ public final class TestCases { .name("Aschaffenburg (KION plant)") .quantity(1000) .d2d(true) - .route("Ireland supplier,WH ULHA, AB") + .route("IE SUP,WH ULHA,AB") .d2dCost(1500.0) .d2dDuration(10) .handlingCost(2.5) @@ -594,7 +594,7 @@ public final class TestCases { .name("Stříbro (KION plant)") .quantity(50000) .d2d(true) - .route("Yantian supplier,CNSZX,DEHAM,WH ZBU,STR") + .route("Yantian s ...,CNSZX,DEHAM,WH ZBU,STR") .d2dCost(6500.0) .d2dDuration(47) .customHandling(false) @@ -722,7 +722,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(5) .d2d(false) - .route("Ireland supplier,HH") + .route("IE SUP,HH") .customHandling(false) .build() )) @@ -784,7 +784,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(40) .d2d(false) - .route("Ireland supplier,HH") + .route("IE SUP,HH") .handlingCost(6.0) .repackingCost(6.0) .disposalCost(6.0) @@ -849,7 +849,7 @@ public final class TestCases { .name("Hamburg (KION plant)") .quantity(900) .d2d(false) - .route("LX > CNXMN > DEHAM > WH_HH > HH") + .route("LX,CNXMN,DEHAM,WH HH,HH") .customHandling(false) .build() ))