Skip to content

Commit fc40e77

Browse files
authored
Merge pull request #110 from ing-bank/release/2.4
Release v2.4
2 parents 0fcf568 + 527014a commit fc40e77

File tree

86 files changed

+5926
-2367
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+5926
-2367
lines changed

Common/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>com.ing</groupId>
77
<artifactId>ingenious-playwright</artifactId>
8-
<version>2.3.1</version>
8+
<version>2.4</version>
99
</parent>
1010
<artifactId>Common</artifactId>
1111
<properties>

Datalib/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.ing</groupId>
66
<artifactId>ingenious-playwright</artifactId>
7-
<version>2.3.1</version>
7+
<version>2.4</version>
88
</parent>
99
<artifactId>ingenious-datalib</artifactId>
1010
<packaging>jar</packaging>

Datalib/src/main/java/com/ing/datalib/component/Project.java

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
import com.ing.datalib.util.data.FileScanner;
1212
import com.fasterxml.jackson.core.JsonProcessingException;
1313
import com.fasterxml.jackson.databind.ObjectMapper;
14+
import com.ing.datalib.or.web.WebOR.ORScope;
1415
import java.io.File;
1516
import java.util.ArrayList;
1617
import java.util.List;
18+
import java.util.LinkedHashSet;
19+
import java.util.Set;
1720
import java.util.Objects;
1821
import java.util.logging.Level;
1922
import java.util.logging.Logger;
@@ -23,8 +26,21 @@
2326
import javax.swing.table.TableModel;
2427

2528
/**
29+
* Represents an automation project and acts as the central entry point for loading, managing,
30+
* and persisting project data from disk.
31+
* <p>
32+
* A {@code Project} encapsulates the project’s filesystem location and name, and maintains the
33+
* in-memory model of core assets such as scenarios (TestPlan), releases/test sets (TestLab),
34+
* environment test data, project settings, and the {@link ObjectRepository}. It supports loading
35+
* and reloading from disk, saving all managed components, and producing table models for UI
36+
* components via {@code getTableModelFor(...)}.
37+
* </p>
2638
*
27-
*
39+
* <p>
40+
* The class also provides refactoring utilities that propagate renames across scenarios, releases,
41+
* and test data (e.g., scenario/test case renames, page/object reference updates, and test data
42+
* renames), including scope-aware refactoring for Object Repository references where applicable.
43+
* </p>
2844
*/
2945
public class Project {
3046

@@ -211,7 +227,9 @@ public Boolean rename(String newName) {
211227
}
212228
}
213229
getObjectRepository().getWebOR().setName(newName);
230+
getObjectRepository().getWebSharedOR().setName(newName);
214231
getObjectRepository().getMobileOR().setName(newName);
232+
getObjectRepository().getMobileSharedOR().setName(newName);
215233
return true;
216234
}
217235
return false;
@@ -395,7 +413,7 @@ public void refactorTestCaseScenario(String testCaseName, String oldScenarioName
395413
.ifPresent(scn -> scn.setName(newScenarioName));
396414
});
397415
}
398-
416+
399417
public void refactorObjectName(String pageName, String oldName, String newName) {
400418
for (Scenario scenario : scenarios) {
401419
scenario.refactorObjectName(pageName, oldName, newName);
@@ -408,12 +426,57 @@ public void refactorObjectName(String oldpageName, String oldObjName, String new
408426
}
409427
}
410428

429+
/**
430+
* Renames an object reference on the given page for the specified OR scope across the project,
431+
* by delegating to all scenarios.
432+
*
433+
* @param scope OR scope to match (e.g., shared vs project)
434+
* @param pageName page (screen) name containing the object reference
435+
* @param oldName existing object name to replace
436+
* @param newName new object name to apply
437+
*/
438+
public void refactorObjectName(ORScope scope, String pageName, String oldName, String newName) {
439+
for (Scenario scenario : scenarios) {
440+
scenario.refactorObjectName(scope, pageName, oldName, newName);
441+
}
442+
}
443+
411444
public void refactorPageName(String oldPageName, String newPageName) {
412445
for (Scenario scenario : scenarios) {
413446
scenario.refactorPageName(oldPageName, newPageName);
414447
}
415448
}
416449

450+
/**
451+
* Refactors (renames) a page reference across the project for a given Object Repository scope.
452+
* <p>
453+
* In addition to delegating the rename for the raw page names, this method also renames
454+
* scope-qualified page names using the convention:
455+
* <ul>
456+
* <li>{@code "[Shared] " + pageName} when scope is {@code ORScope.SHARED}</li>
457+
* <li>{@code "[Project] " + pageName} otherwise</li>
458+
* </ul>
459+
* For each {@link Scenario}, it applies both:
460+
* {@code scenario.refactorPageName(oldPageName, newPageName)} and
461+
* {@code scenario.refactorPageName(oldScoped, newScoped)}.
462+
* </p>
463+
*
464+
* @param scope the Object Repository scope used to derive the scoped page name prefix
465+
* @param oldPageName the original page name to be replaced
466+
* @param newPageName the new page name to apply
467+
*
468+
* @implNote This method performs two refactors per scenario: one for the plain page name and one
469+
* for the derived scoped form (e.g., {@code "[Shared] Login"}).
470+
*/
471+
public void refactorPageName(ORScope scope, String oldPageName, String newPageName) {
472+
String oldScoped = scope == ORScope.SHARED ? "[Shared] " + oldPageName : "[Project] " + oldPageName;
473+
String newScoped = scope == ORScope.SHARED ? "[Shared] " + newPageName : "[Project] " + newPageName;
474+
for (Scenario scenario : scenarios) {
475+
scenario.refactorPageName(oldPageName, newPageName);
476+
scenario.refactorPageName(oldScoped, newScoped);
477+
}
478+
}
479+
417480
public void refactorTestData(String oldTDName, String newTDName) {
418481
for (Scenario scenario : scenarios) {
419482
scenario.refactorTestData(oldTDName, newTDName);
@@ -434,6 +497,23 @@ public List<TestCase> getImpactedObjectTestCases(String pageName, String objectN
434497
return impactedTestCases;
435498
}
436499

500+
public List getImpactedObjectTestCases(ORScope scope, String pageName, String objectName) {
501+
Set impacted = new LinkedHashSet<>();
502+
String scopedPageName = null;
503+
if (scope != null) {
504+
scopedPageName = (scope == ORScope.SHARED)
505+
? "[Shared] " + pageName
506+
: "[Project] " + pageName;
507+
}
508+
for (Scenario scenario : scenarios) {
509+
impacted.addAll(scenario.getImpactedObjectTestCases(pageName, objectName));
510+
if (scopedPageName != null) {
511+
impacted.addAll(scenario.getImpactedObjectTestCases(scopedPageName, objectName));
512+
}
513+
}
514+
return new ArrayList<>(impacted);
515+
}
516+
437517
public List<TestCase> getImpactedTestCaseTestCases(String scenarioName, String testCaseName) {
438518
List<TestCase> impactedTestCases = new ArrayList<>();
439519
for (Scenario scenario : scenarios) {
@@ -520,5 +600,4 @@ private static DataItem fromTS(TestSet ts) {
520600
}
521601
}
522602
}
523-
524-
}
603+
}

Datalib/src/main/java/com/ing/datalib/component/Scenario.java

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,25 @@
22
package com.ing.datalib.component;
33

44
import com.ing.datalib.component.utils.FileUtils;
5+
import com.ing.datalib.or.web.WebOR.ORScope;
56
import java.io.File;
67
import java.util.ArrayList;
78
import java.util.List;
89

910
/**
11+
* Represents a scenario within a project’s TestPlan and serves as a container for related test cases.
12+
* <p>
13+
* A {@code Scenario} is backed by a filesystem folder under {@code <project>/TestPlan/<scenario>},
14+
* automatically loads its {@link TestCase} CSV files on construction, and exposes methods for adding,
15+
* removing, loading, and saving test cases.
16+
* </p>
1017
*
11-
*
18+
* <p>
19+
* The class also implements {@code DataModel} table-model behavior for UI consumption by presenting
20+
* a scenario-level view of non-reusable test cases, and provides refactoring and impact-analysis helpers
21+
* that delegate to contained test cases (e.g., object/page/test data reference updates and impacted test
22+
* case discovery).
23+
* </p>
1224
*/
1325
public class Scenario extends DataModel {
1426

@@ -279,6 +291,21 @@ public void refactorObjectName(String oldpageName, String oldObjName, String new
279291
}
280292
}
281293

294+
/**
295+
* Renames an object reference on the given page for the specified OR scope within this scenario,
296+
* by delegating to all test cases.
297+
*
298+
* @param scope OR scope to match (e.g., shared vs project)
299+
* @param pageName page (screen) name containing the object reference
300+
* @param oldName existing object name to replace
301+
* @param newName new object name to apply
302+
*/
303+
public void refactorObjectName(ORScope scope, String pageName, String oldName, String newName) {
304+
for (TestCase testCase : testCases) {
305+
testCase.refactorObjectName(scope, pageName, oldName, newName);
306+
}
307+
}
308+
282309
public void refactorPageName(String oldPageName, String newPageName) {
283310
for (TestCase testCase : testCases) {
284311
testCase.refactorPageName(oldPageName, newPageName);
@@ -350,5 +377,4 @@ public Boolean delete() {
350377
}
351378
return false;
352379
}
353-
354-
}
380+
}

Datalib/src/main/java/com/ing/datalib/component/TestCase.java

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.ing.datalib.component.TestStep.HEADERS;
55
import com.ing.datalib.component.utils.FileUtils;
66
import com.ing.datalib.component.utils.SaveListener;
7+
import com.ing.datalib.or.web.WebOR.ORScope;
78
import java.io.File;
89
import java.io.FileWriter;
910
import java.util.ArrayList;
@@ -18,8 +19,21 @@
1819
import org.apache.commons.csv.CSVRecord;
1920

2021
/**
22+
* Represents a test case composed of ordered {@link TestStep} entries and implements a table model
23+
* suitable for direct editing in UI components.
24+
* <p>
25+
* A {@code TestCase} belongs to a {@link Scenario}, loads and persists its steps from/to a CSV file,
26+
* and supports common editing operations such as inserting, removing, moving, replicating steps,
27+
* clearing values, toggling comments/breakpoints, and bulk removal. Save state is tracked and propagated
28+
* via a {@link SaveListener}.
29+
* </p>
2130
*
22-
*
31+
* <p>
32+
* The class also supports creating and managing reusable test cases (represented as “Execute” steps),
33+
* provides utilities for refactoring references (scenario/test case reuse links, object/page names,
34+
* test data and columns—including scope-aware OR references), and can report impact when a given object,
35+
* reusable, or test data reference is used.
36+
* </p>
2337
*/
2438
public class TestCase extends DataModel {
2539

@@ -557,7 +571,11 @@ public void refactorObjectName(String pageName, String oldName, String newName)
557571
Boolean clearOnExit = getTestSteps().isEmpty();
558572
loadTableModel();
559573
for (TestStep testStep : testSteps) {
560-
if (testStep.getReference().equals(pageName) && testStep.getObject().equals(oldName)) {
574+
String ref = Objects.toString(testStep.getReference(), "");
575+
String obj = Objects.toString(testStep.getObject(), "");
576+
String normalizedRef = normalizePageRef(ref);
577+
578+
if (normalizedRef.equals(pageName) && obj.equals(oldName)) {
561579
testStep.setObject(newName);
562580
}
563581
}
@@ -566,22 +584,85 @@ public void refactorObjectName(String pageName, String oldName, String newName)
566584
getTestSteps().clear();
567585
}
568586
}
569-
587+
570588
public void refactorObjectName(String oldpageName, String oldObjName, String newPageName, String newObjName) {
571589
Boolean clearOnExit = getTestSteps().isEmpty();
572590
loadTableModel();
591+
573592
for (TestStep testStep : testSteps) {
574-
if (testStep.getReference().equals(oldpageName) && testStep.getObject().equals(oldObjName)) {
593+
String ref = normalizePageRef(Objects.toString(testStep.getReference(), ""));
594+
String obj = Objects.toString(testStep.getObject(), "");
595+
if (ref.equals(oldpageName) && obj.equals(oldObjName)) {
575596
testStep.setObject(newObjName);
576597
testStep.setReference(newPageName);
577598
}
578599
}
600+
579601
if (clearOnExit) {
580602
save();
581603
getTestSteps().clear();
582604
}
583605
}
584606

607+
/**
608+
* Renames an object reference on the given page within this test case, restricted to the specified OR scope.
609+
* A step matches when its reference has the expected scope prefix and its normalized page name equals {@code pageName}.
610+
*
611+
* @param scope OR scope to match (e.g., {@code PROJECT} or {@code SHARED})
612+
* @param pageName page (screen) name (without scope prefix) to match
613+
* @param oldName existing object name to replace
614+
* @param newName new object name to apply
615+
*/
616+
public void refactorObjectName(ORScope scope, String pageName, String oldName, String newName) {
617+
Boolean clearOnExit = getTestSteps().isEmpty();
618+
loadTableModel();
619+
for (TestStep testStep : testSteps) {
620+
String refRaw = Objects.toString(testStep.getReference(), "");
621+
String obj = Objects.toString(testStep.getObject(), "");
622+
boolean scopedMatch = matchesScope(refRaw, scope) && normalizePageRef(refRaw).equals(pageName);
623+
if (scopedMatch && obj.equals(oldName)) {
624+
testStep.setObject(newName);
625+
}
626+
}
627+
if (clearOnExit) {
628+
save();
629+
getTestSteps().clear();
630+
}
631+
}
632+
633+
/**
634+
* Checks whether a reference string is explicitly scoped for the given OR scope.
635+
* Returns {@code true} only when {@code ref} starts with the expected scope prefix
636+
* (e.g., {@code "[Project] "} or {@code "[Shared] "}); otherwise returns {@code false}.
637+
*
638+
* @param ref raw reference value (may be {@code null})
639+
* @param scope scope to match against
640+
* @return {@code true} if {@code ref} begins with the prefix for {@code scope}; {@code false} otherwise
641+
*/
642+
private boolean matchesScope(String ref, ORScope scope) {
643+
if (ref == null) return false;
644+
ref = ref.trim();
645+
if (scope == ORScope.PROJECT) return ref.startsWith("[Project] ");
646+
if (scope == ORScope.SHARED) return ref.startsWith("[Shared] ");
647+
return false;
648+
}
649+
650+
/**
651+
* Normalizes a page reference by removing known scope prefixes.
652+
* Trims the input and strips {@code "[Project] "} or {@code "[Shared] "} when present;
653+
* otherwise returns the trimmed reference. Returns an empty string when {@code ref} is {@code null}.
654+
*
655+
* @param ref raw reference value (may be {@code null})
656+
* @return normalized page name without scope prefix (never {@code null})
657+
*/
658+
private String normalizePageRef(String ref) {
659+
if (ref == null) return "";
660+
ref = ref.trim();
661+
if (ref.startsWith("[Project] ")) return ref.substring("[Project] ".length()).trim();
662+
if (ref.startsWith("[Shared] ")) return ref.substring("[Shared] ".length()).trim();
663+
return ref;
664+
}
665+
585666
public void refactorPageName(String oldPageName, String newPageName) {
586667
Boolean clearOnExit = getTestSteps().isEmpty();
587668
loadTableModel();
@@ -662,5 +743,4 @@ public Boolean rename(String newName) {
662743
}
663744
return false;
664745
}
665-
666-
}
746+
}

0 commit comments

Comments
 (0)