Skip to content

Commit 7bc95a5

Browse files
committed
Add GenerateReplayableSequence setting
1 parent 4277bd4 commit 7bc95a5

6 files changed

Lines changed: 73 additions & 22 deletions

File tree

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Ignore weak password chrome popup
1212
- Refactor usage of Tag ScreenshotImage
1313
- Add settings to configure webdriver constants
14+
- Add settings to enable/disable generating replayable files
1415

1516

1617
#TESTAR 2.7.7 (26-Aug-2025)

testar/src/org/testar/FileHandling.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,46 @@
4141
public class FileHandling {
4242

4343
public static String copyClassifiedSequence(String generatedSequence, File currentSeq, Verdict verdict) {
44-
// Generate target folder name based on severity title
44+
// Generate the target folder names based on the severity title
4545
String targetFolder = "sequences_" + verdict.verdictSeverityTitle().toLowerCase();
46+
String targetSequence = targetFolder + File.separator + generatedSequence;
4647

4748
LogSerialiser.log(
4849
String.format("Copying classified sequence (\"%s\") to %s folder...\n", generatedSequence, targetFolder),
4950
LogSerialiser.LogLevel.Info
5051
);
5152

53+
// The .testar sequence file might not exist (e.g., GenerateReplayableSequence is disabled)
54+
try {
55+
if (!currentSeq.getCanonicalFile().exists()) {
56+
LogSerialiser.log(
57+
String.format("No sequence file exists to classify for \"%s\".\n", generatedSequence),
58+
LogSerialiser.LogLevel.Info
59+
);
60+
61+
LogSerialiser.log(
62+
String.format("No sequence copied to output directory <%s>.\n", targetSequence),
63+
LogSerialiser.LogLevel.Info
64+
);
65+
66+
return targetSequence;
67+
}
68+
} catch (IOException ioe) {
69+
LogSerialiser.log(
70+
"Error checking whether the sequence file exists: " + ioe.getMessage() + "\n",
71+
LogSerialiser.LogLevel.Critical
72+
);
73+
}
74+
75+
// If it exists, copy to the specific classification folder
5276
try {
53-
// Copy to specific classification folder
5477
copyToOutputDir(currentSeq, targetFolder);
5578
} catch (NoSuchTagException | IOException e) {
56-
LogSerialiser.log("Error copying classified test sequence: " + e.getMessage() + "\n", LogSerialiser.LogLevel.Critical);
79+
LogSerialiser.log("Error copying classified test sequence: " + e.getMessage() + "\n",
80+
LogSerialiser.LogLevel.Critical
81+
);
5782
}
5883

59-
String targetSequence = targetFolder + File.separator + generatedSequence;
60-
6184
LogSerialiser.log(
6285
String.format("Copied classified sequence to output <%s> directory!\n", targetSequence),
6386
LogSerialiser.LogLevel.Info

testar/src/org/testar/monkey/ConfigTags.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,22 @@ private ConfigTags() {}
234234
public static final Tag<Boolean> JacocoCoverageAccumulate = Tag.from("JacocoCoverageAccumulate", Boolean.class,
235235
"Sets whether Jacoco coverage will be accumulated across the run sequences");
236236

237+
/**
238+
* Replay settings
239+
*/
240+
241+
public static final Tag<Boolean> GenerateReplayableSequence = Tag.from("GenerateReplayableSequence", Boolean.class,
242+
"Sets whether TESTAR must create a replayable testar file during Generate mode (this consumes more memory during execution)");
243+
244+
public static final Tag<Double> ReplayRetryTime = Tag.from("ReplayRetryTime", Double.class,
245+
"Inside the replay mode, establishes the time window in seconds for trying to replay a UI action of a replayed test sequence");
246+
247+
public static final Tag<Boolean> UseRecordedActionDurationAndWaitTimeDuringReplay = Tag.from("UseRecordedActionDurationAndWaitTimeDuringReplay", Boolean.class,
248+
"Inside the replay mode sets whether to use the action duration (ActionDuration and TimeToWaitAfterAction) as specified in the generated test sequence");
249+
250+
public static final Tag<String> PathToReplaySequence = Tag.from("PathToReplaySequence", String.class,
251+
"The sequence to REPLAY is the one indicated in this parameter");
252+
237253
/**
238254
* Additional settings with descriptions
239255
*/
@@ -268,18 +284,12 @@ private ConfigTags() {}
268284
public static final Tag<Boolean> OnlySaveFaultySequences = Tag.from("OnlySaveFaultySequences", Boolean.class,
269285
"Sets whether to save test sequences without failures");
270286

271-
public static final Tag<Double> ReplayRetryTime = Tag.from("ReplayRetryTime", Double.class,
272-
"Inside the replay mode, establishes the time window in seconds for trying to replay a UI action of a replayed test sequence");
273-
274287
public static final Tag<Boolean> StopGenerationOnFault = Tag.from("StopGenerationOnFault", Boolean.class,
275288
"Sets whether to finish a test in the presence of a fail (e.g. Suspicious Tag detected)");
276289

277290
public static final Tag<Double> TimeToFreeze = Tag.from("TimeToFreeze", Double.class,
278291
"Sets the time window, in seconds, for which to wait for a not responding SUT. After that, the test will finish with a fail");
279292

280-
public static final Tag<Boolean> UseRecordedActionDurationAndWaitTimeDuringReplay = Tag.from("UseRecordedActionDurationAndWaitTimeDuringReplay", Boolean.class,
281-
"Inside the replay mode sets whether to use the action duration (ActionDuration and TimeToWaitAfterAction) as specified in the generated test sequence");
282-
283293
public static final Tag<Boolean> VisualizeActions = Tag.from("VisualizeActions", Boolean.class,
284294
"Sets whether to display overlay information, inside the SPY mode, for all the UI actions derived from the test set up");
285295

@@ -289,9 +299,6 @@ private ConfigTags() {}
289299
public static final Tag<Boolean> UseSystemActions = Tag.from("UseSystemActions", Boolean.class,
290300
"ANDROID: Indicate if add system calls");
291301

292-
public static final Tag<String> PathToReplaySequence = Tag.from("PathToReplaySequence", String.class,
293-
"The sequence to REPLAY is the one indicated in this parameter");
294-
295302
public static final Tag<Double> RefreshSpyCanvas = Tag.from("RefreshSpyCanvas", Double.class,
296303
"Time in milliseconds that indicates the frequency of refreshing the screen in SPY mode");
297304

testar/src/org/testar/monkey/DefaultProtocol.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,15 @@ void getAndStoreSequenceFile() {
457457

458458
this.currentSeq = new File(sequenceObject);
459459

460-
try {
461-
TestSerialiser.start(new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.currentSeq, true))));
462-
LogSerialiser.log("Created new sequence file!\n", LogSerialiser.LogLevel.Debug);
463-
} catch (IOException e) {
464-
LogSerialiser.log("I/O exception creating new sequence file\n", LogSerialiser.LogLevel.Critical);
460+
if(settings.get(ConfigTags.GenerateReplayableSequence, false)) {
461+
try {
462+
TestSerialiser.start(new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(this.currentSeq, true))));
463+
LogSerialiser.log("Created new sequence file!\n", LogSerialiser.LogLevel.Info);
464+
} catch (IOException e) {
465+
LogSerialiser.log("I/O exception creating new sequence file\n", LogSerialiser.LogLevel.Critical);
466+
}
467+
} else {
468+
LogSerialiser.log("Replayable files are not created due to GenerateReplayableSequence setting\n", LogSerialiser.LogLevel.Info);
465469
}
466470
}
467471

@@ -572,6 +576,11 @@ void classifyAndCopySequenceIntoAppropriateDirectory(Verdict finalVerdict){
572576
* @param action
573577
*/
574578
void saveActionIntoFragmentForReplayableSequence(Action action, State state, Set<Action> actions) {
579+
// User decided not to generate replayable files
580+
if(!settings.get(ConfigTags.GenerateReplayableSequence)) {
581+
return;
582+
}
583+
575584
// create fragment
576585
TaggableBase fragment = new TaggableBase();
577586
fragment.set(ExecutedAction, action);

testar/src/org/testar/settings/SettingsDefaults.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ private SettingsDefaults() {}
5656
defaults.add(Pair.from(TempDir, Main.tempDir));
5757
defaults.add(Pair.from(OnlySaveFaultySequences, false));
5858
defaults.add(Pair.from(PathToReplaySequence, Main.tempDir));
59+
defaults.add(Pair.from(GenerateReplayableSequence, true));
5960
defaults.add(Pair.from(ActionDuration, 0.1));
6061
defaults.add(Pair.from(TimeToWaitAfterAction, 0.1));
6162
defaults.add(Pair.from(VisualizeActions, false));

testar/src/org/testar/settings/SettingsFileStructure.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,19 @@ public static String getTestSettingsStructure() {
359359
, ConfigTags.JacocoCoverageClasses.name() + " = "
360360
, ConfigTags.JacocoCoverageAccumulate.name() + " = "
361361
, ""
362+
, "#################################################################"
363+
, "# Replay mode features"
364+
, "# GenerateReplayableSequence: " + ConfigTags.GenerateReplayableSequence.getDescription()
365+
, "# PathToReplaySequence: " + ConfigTags.PathToReplaySequence.getDescription()
366+
, "# ReplayRetryTime: " + ConfigTags.ReplayRetryTime.getDescription()
367+
, "# UseRecordedActionDurationAndWaitTimeDuringReplay: " + ConfigTags.UseRecordedActionDurationAndWaitTimeDuringReplay.getDescription()
368+
, "#################################################################"
369+
, ""
370+
, ConfigTags.GenerateReplayableSequence.name() + " = "
371+
, ConfigTags.PathToReplaySequence.name() + " = "
372+
, ConfigTags.ReplayRetryTime.name() + " = "
373+
, ConfigTags.UseRecordedActionDurationAndWaitTimeDuringReplay.name() + " = "
374+
, ""
362375
);
363376

364377
// Second, create a list of secondary configuration tags settings
@@ -371,12 +384,9 @@ public static String getTestSettingsStructure() {
371384
secondarySettingsList.add(ConfigTags.FormFillingAction);
372385
secondarySettingsList.add(ConfigTags.LogLevel);
373386
secondarySettingsList.add(ConfigTags.OnlySaveFaultySequences);
374-
secondarySettingsList.add(ConfigTags.ReplayRetryTime);
375387
secondarySettingsList.add(ConfigTags.StopGenerationOnFault);
376388
secondarySettingsList.add(ConfigTags.TimeToFreeze);
377-
secondarySettingsList.add(ConfigTags.UseRecordedActionDurationAndWaitTimeDuringReplay);
378389
secondarySettingsList.add(ConfigTags.UseSystemActions);
379-
secondarySettingsList.add(ConfigTags.PathToReplaySequence);
380390
secondarySettingsList.add(ConfigTags.RefreshSpyCanvas);
381391
secondarySettingsList.add(ConfigTags.FlashFeedback);
382392
secondarySettingsList.add(ConfigTags.MaxReward);

0 commit comments

Comments
 (0)