{
- private static final Logger LOG = LoggerFactory.getLogger(VisibleCursorListener.class);
-
public VisibleCursorListener(CursorWaitCondition condition, Tn5250Client client,
ScheduledExecutorService stableTimeoutExecutor, ExceptionHandler exceptionHandler) {
super(condition, client, stableTimeoutExecutor, exceptionHandler);
- if (condition.getPosition().equals(client.getCursorPosition().orElse(null))) {
- LOG.debug("Cursor is in expected position, now waiting for it to remain for stable period");
- startStablePeriod();
- }
}
@Override
public synchronized void stateChanged(XI5250EmulatorEvent event) {
- if (condition.getPosition().equals(client.getCursorPosition().orElse(null))) {
- LOG.debug("Cursor is in expected position, now waiting for it to remain for stable period");
- startStablePeriod();
- } else {
- LOG.debug("Cursor is not in expected position, canceling any stable period");
- endStablePeriod();
- }
+ updateConditionState(event.toString());
}
+ @Override
+ protected boolean getCurrentConditionState() {
+ return condition.getPosition().equals(client.getCursorPosition().orElse(null));
+ }
}
diff --git a/src/main/resources/recorder-help.html b/src/main/resources/recorder-help.html
index d5bc6f76..33569162 100644
--- a/src/main/resources/recorder-help.html
+++ b/src/main/resources/recorder-help.html
@@ -118,7 +118,11 @@ Status bar
|
- Allow using a selected part of the screen as wait condition |
+ Allow using a selected part of the screen as text wait condition |
+
+
+ |
+ Allow using a selected part of the screen in a Response Assertion |
Credits
diff --git a/src/test/java/com/blazemeter/jmeter/rte/core/listeners/ConditionWaiterIT.java b/src/test/java/com/blazemeter/jmeter/rte/core/listeners/ConditionWaiterIT.java
index bb17fa98..2f403779 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/core/listeners/ConditionWaiterIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/core/listeners/ConditionWaiterIT.java
@@ -18,14 +18,13 @@ public abstract class ConditionWaiterIT> {
protected static final long TIMEOUT_MILLIS = 3000;
protected static final long STABLE_MILLIS = 1000;
+ private static final int INITIAL_DELAY = 500;
protected ScheduledExecutorService stableTimeoutExecutor;
- private ScheduledExecutorService eventGeneratorExecutor;
-
@Mock
protected ExceptionHandler exceptionHandler;
-
protected T listener;
+ private ScheduledExecutorService eventGeneratorExecutor;
@Before
public void setup() throws Exception {
@@ -40,11 +39,10 @@ public void setup() throws Exception {
@Test
public void shouldUnblockAfterReceivingException() throws Exception {
when(exceptionHandler.hasPendingError()).thenReturn(true);
- long unlockDelayMillis = 500;
Stopwatch waitTime = Stopwatch.createStarted();
- startSingleEventGenerator(unlockDelayMillis, buildOnExceptionEventGenerator());
+ startSingleEventGenerator(INITIAL_DELAY, buildOnExceptionEventGenerator());
listener.await();
- assertThat(waitTime.elapsed(TimeUnit.MILLISECONDS)).isGreaterThanOrEqualTo(unlockDelayMillis);
+ assertThat(waitTime.elapsed(TimeUnit.MILLISECONDS)).isGreaterThanOrEqualTo(INITIAL_DELAY);
}
private Runnable buildOnExceptionEventGenerator() {
@@ -64,7 +62,9 @@ protected void startSingleEventGenerator(long delayMillis, Runnable eventGenerat
}
protected void startPeriodicEventGenerator(Runnable eventGenerator) {
- eventGeneratorExecutor.scheduleAtFixedRate(eventGenerator, 500, 500, TimeUnit.MILLISECONDS);
+ eventGeneratorExecutor
+ .scheduleAtFixedRate(eventGenerator, INITIAL_DELAY, Long.divideUnsigned(STABLE_MILLIS, 2),
+ TimeUnit.MILLISECONDS);
}
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/RteProtocolClientIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/RteProtocolClientIT.java
index 66bddfa3..9cd9240b 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/RteProtocolClientIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/RteProtocolClientIT.java
@@ -85,4 +85,6 @@ protected Screen buildScreenFromHtmlFile(String fileName) throws IOException {
}
protected abstract List buildExpectedFields();
+
+
}
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/Tn3270ClientIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/Tn3270ClientIT.java
index 638e275e..0ee5ea40 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/Tn3270ClientIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/Tn3270ClientIT.java
@@ -35,6 +35,7 @@
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.util.JMeterUtils;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.junit.Test;
@@ -360,4 +361,15 @@ public void shouldValidateSecretFieldsOnScreenWhenBuildScreen() throws Exception
assertThat(currentSegments).isEqualTo(buildExpectedFields());
}
+
+ @Test(expected = TimeoutException.class)
+ public void shouldThrowTimeoutExceptionWhenMatchedScreenChangedBeforeStablePeriod()
+ throws Exception {
+ loadFlow("login-with-multiple-flash-screen.yml");
+ client.connect(VIRTUAL_SERVER_HOST, server.getPort(), SSLType.NONE, getDefaultTerminalType(),
+ TIMEOUT_MILLIS);
+
+ client.await(Collections.singletonList(new TextWaitCondition(JMeterUtils.getPattern("AAAAA"),
+ JMeterUtils.getMatcher(), Area.fromTopLeftBottomRight(1, 1, Position.UNSPECIFIED_INDEX, Position.UNSPECIFIED_INDEX), TIMEOUT_MILLIS, STABLE_TIMEOUT_MILLIS)));
+ }
}
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/ScreenTextListenerIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/ScreenTextListenerIT.java
index 8ac9b950..fe57d57c 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/ScreenTextListenerIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/ScreenTextListenerIT.java
@@ -88,8 +88,8 @@ public void shouldThrowTimeoutExceptionWhenReceivedScreenNotMatchingRegexInArea(
listener.await();
}
- @Test(expected = TimeoutException.class)
- public void shouldThrowTimeoutExceptionWhenReceivedExpectedScreenButKeepGettingStateChanges()
+ @Test
+ public void shouldUnlockWhenReceivingMultipleStateChangesButScreenDoesNotChange()
throws Exception {
setupScreenWithText(EXPECTED_SCREEN);
buildScreenStateChangeGenerator().run();
@@ -97,8 +97,8 @@ public void shouldThrowTimeoutExceptionWhenReceivedExpectedScreenButKeepGettingS
listener.await();
}
- @Test(expected = TimeoutException.class)
- public void shouldThrowTimeoutExceptionWhenReceivedExpectedScreenButKeepGettingScreens()
+ @Test
+ public void shouldUnlockWhenReceivingMultipleExpectedScreen()
throws Exception {
setupScreenWithText(EXPECTED_SCREEN);
startPeriodicEventGenerator(buildScreenStateChangeGenerator());
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/UnlockListenerIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/UnlockListenerIT.java
index b0293749..549847da 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/UnlockListenerIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn3270/listeners/UnlockListenerIT.java
@@ -30,6 +30,7 @@ protected Tn3270ConditionWaiter> buildConditionWaiter() {
@Test
public void shouldUnblockAfterReceivingUnlockStateChange() throws Exception {
+ when(client.isInputInhibited()).thenReturn(false);
KeyboardStatusChangedEvent keyboardEvent = new KeyboardStatusChangedEvent(false, false, "");
long unlockDelayMillis = 500;
Stopwatch waitTime = Stopwatch.createStarted();
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/Tn5250ClientIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/Tn5250ClientIT.java
index 089837a7..8d7566cc 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/Tn5250ClientIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/Tn5250ClientIT.java
@@ -34,6 +34,7 @@
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.jmeter.util.JMeterUtils;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.junit.Test;
@@ -329,4 +330,13 @@ public void shouldValidateSecretFieldsOnScreenWhenBuildScreen() throws Exception
Collectors.toList());
assertThat(currentFields).isEqualTo(buildExpectedFields());
}
+
+ @Test(expected = TimeoutException.class)
+ public void shouldFailWhenMatchedScreenChangedBeforeStablePeriod() throws Exception {
+ loadFlow("login-with-multiple-flash-screen.yml");
+ client.connect(VIRTUAL_SERVER_HOST, server.getPort(), SSLType.NONE, getDefaultTerminalType(),
+ TIMEOUT_MILLIS);
+ client.await(Collections.singletonList(new TextWaitCondition(JMeterUtils.getPattern("Sign on"),
+ JMeterUtils.getMatcher(), Area.fromTopLeftBottomRight(1,1,24,80), 10000, 1000)));
+ }
}
diff --git a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/listeners/ScreenTextListenerIT.java b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/listeners/ScreenTextListenerIT.java
index ee591b72..0079c2f6 100644
--- a/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/listeners/ScreenTextListenerIT.java
+++ b/src/test/java/com/blazemeter/jmeter/rte/protocols/tn5250/listeners/ScreenTextListenerIT.java
@@ -85,17 +85,8 @@ public void shouldThrowTimeoutExceptionWhenReceivedScreenNotMatchingRegexInArea(
listener.await();
}
- @Test(expected = TimeoutException.class)
- public void shouldThrowTimeoutExceptionWhenReceivedExpectedScreenButKeepGettingStateChanges()
- throws Exception {
- setupScreenWithText(EXPECTED_SCREEN);
- buildNewPanelGenerator().run();
- startPeriodicEventGenerator(buildStateChangeGenerator());
- listener.await();
- }
-
- @Test(expected = TimeoutException.class)
- public void shouldThrowTimeoutExceptionWhenReceivedExpectedScreenButKeepGettingScreens()
+ @Test
+ public void shouldUnlockWhenReceivingMultipleExpectedScreen()
throws Exception {
setupScreenWithText(EXPECTED_SCREEN);
startPeriodicEventGenerator(buildNewPanelGenerator());
diff --git a/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-flash-screen.html b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-flash-screen.html
new file mode 100644
index 00000000..a41150a6
--- /dev/null
+++ b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-flash-screen.html
@@ -0,0 +1,27 @@
+
+
THIS IS A "TEST" LOGIN -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-with-multiple-flash-screen.yml b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-with-multiple-flash-screen.yml
new file mode 100644
index 00000000..1c6de866
--- /dev/null
+++ b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn3270/login-with-multiple-flash-screen.yml
@@ -0,0 +1,58 @@
+# Do TN3270E
+- !server {data: FFFD28, delayMillis: 342}
+# Won't TN3270E
+- !client {data: FFFC28}
+# Do Terminal Type
+- !server {data: FFFD18, delayMillis: 196}
+# Will Terminal Type
+- !client {data: FFFB18}
+# Send your Terminal Type
+- !server {data: 00FFFA1801FFF0, delayMillis: 196}
+# terminal-type: IBM-3278-2-E
+- !client {data: FFFA180049424D2D333237382D322D45FFF0}
+# Do End of Record
+- !server {data: FFFD19, delayMillis: 197}
+# Will End of Record
+- !server {data: FFFB19}
+# Will End of Record
+- !client {data: FFFB19}
+# Do Binary Transmission + Will Binary Transmission
+- !server {data: FFFD00FFFB00, delayMillis: 198}
+# Do End of Record
+- !client {data: FFFD19}
+# Will Binary Transmission + Do Binary Transmission
+- !client {data: FFFB00FFFD00}
+# restore keyboard + user input screen + cursor=2,1
+- !server {data: 05C1115D7F1D401140401DC8C1C1C1C1C1C1C1C1C140C5D5E3C5D940E4E2C5D9C9C440601D4011C15013FFEF}
+- !server {data: 01C2FFEF, delayMillis: 150}
+- !server {data: 05C1115D7F1D401140401DC8E3C8C9E240C9E240C1407FE3C5E2E37F40D3D6C7C9D5401D4011C15013FFEF}
+- !server {data: 01C2FFEF}
+# user: testusr + enter
+- !client {data: 7D406111405AA385A2A3A4A299FFEF}
+# reset + cursor=1,1
+- !server {data: 05C1115D7F1D4011404013FFEF, delayMillis: 289}
+# restore keyboard
+- !server {data: 05D7FFEF}
+# restore keyboard + password input screen + cursor=8,20
+- !server {data: 05C31140403C4040401140401DE86060606060606060606060606060606060606060606060606060606060606040E3E2D661C540D3D6C7D6D54060606060606060606060606060606060606060606060606060606060606060606060606011C1501DE8404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404011C2601DE84040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040115B601DE8D7C6F161D7C6F1F3407E7E6E40C885939740404040D7C6F361D7C6F1F5407E7E6E40D3968796868640404040D7C1F1407E7E6E40C1A3A38595A389969540404040D7C1F2407E7E6E40D985A28896A6115CF01DE8E896A4409481A840998598A485A2A340A29785838986898340888593974089958696999481A38996954082A8408595A385998995874081407D6F7D408995408195A8408595A399A840868985938411C3F31DE8C595A3859940D3D6C7D6D540978199819485A38599A24082859396A67A11C4E31DE8D9C1C3C640D3D6C7D6D540978199819485A38599A27A11C6D21D6040E4A285998984404040407E7E7E6E11C6E21DE8E3C5E2E3E4E2D9401DF011C8F21D6040D781A2A2A696998440407E7E7E6E11C9C21D4C00000000000000001DF0114DF21D6040C18383A340D5948299407E7E7E6E114EC21DC8F1F0F0F0F0F0F00000000000000000000000000000000000000000000000000000000000000000001DF0114BD21D6040D79996838584A49985407E7E7E6E114BE21DC8D7D9D6C3F0F0F01DF01150D21D6040E289A9854040404040407E7E7E6E1150E21DC8F4F0F9F60000001DF011D2F21D6040D78599869699944040407E7E7E6E11D3C21DC80000001DF0114CC21D6040C79996A49740C9848595A340407E7E7E6E114CD51DC800000000000000001DF011C9E21D6040D585A640D781A2A2A6969984407E7E7E6E11C9F51D4C00000000000000001DF011D7F31DE8C595A38599408195407DE27D408285869699854085818388409697A3899695408485A2899985844082859396A67A1D6011D9C71DE80011D9C91DC8401DF060D596948189931D6011D9D71DE80011D9D91DC8401DF060D5969596A38983851D6011D9E81DE80011D96A1DC8001DF060D985839695958583A31D6011D97A1DE80011D97C1DC8401DF060D6C9C483819984401D6011D5D21D6040C39694948195844040407E7E7E6E11D5E21DC840404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040401DF011C7C21D7C40E28583938182859340404040407E7E7E6E11C7D51D7C40404040404040401DF011C9C313FFEF,
+ delayMillis: 197}
+# password: testpsw + enter
+- !client {data: 7DC94A11C9C3A385A2A397A2A640FFEF}
+# Server shows stream of data
+- !server {data: 05C1115D7F1D4011404013FFEF, delayMillis: 198}
+- !server {data: 05C111404013FFEF}
+- !server {data: 01C11140403C404000FFEF01401140401DC8E3E2E2F7F0F0F0C940E3C5E2E3E4E2D940D381A2A360E4A2858440F0F540C1979940F1F840F1F67AF1F240E2A8A2A385947EE7C5F4F940C68183899389A3A87EE3E2D61D4011C1501DC8E3E2E2F7F0F0F1C940C396A495A37EF0F0F0F0F340D49684857EC681899340D3968392A38994857ED596958540D58194857EE3C5E2E3C9D5C740E4E2C5D9F11D4011C26013FFEF014011C2601DC8C9D2D1F5F6F4F5F5C940E3C5E2E3E4E2D940D3D6C7D6D540C9D540D7D9D6C7D9C5E2E240C1E340F1F67AF1F77AF4F540D6D540C1D7D9C9D340F56B40F2F0F1F81D4011C3F013FFEF,
+ delayMillis: 196}
+- !server {data: 014011C3F01DC8405C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C1D4011C5401DC8405C4040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040405C1D4011C6501DC8405C4040404040404040E685938396948540A39640E3E2D661C540969540D4E5E240D489958940E2A8A2A3859440404040404040404040404040404040405C1D4011C7601DC8405C40E2D4C6C9C44DE7C5F4F95D4040D1C5E2F2D5D6C4C54DE4E2C9F2F4F9D4C55D4040E3E2D6C1D7D7D34DC1F4F9C9D6E3E2D65D4040404040404040405C1D4011C8F01DC8405C4040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040405C1D40114A4013FFEF,
+ delayMillis: 2439}
+- !server {data: 0140114A401DC8405C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C1D40114B5013FFEF0140114B501DC8401D40114C601DC85CD3D6C7D6D5F3F9F47A40E3E2D661C9E2D7C640E2C5E2E2C9D6D540E3C1C9D3D6D9C9D5C740E2C5D3C5C3E3C9D6D540C9D540D7D9D6C7D9C5E2E25C1D40114DF013FFEF0140114DF01DC85CD5D6E3C57A407DE3C5E2E3E4E2D94BC9E2D7C6D7C1D9D44BC3D3C9E2E37D40D5D6E340C6D6E4D5C46B40C4C5C6C1E4D3E3E240E3C1D2C5D55C1D40114F401DC85CD5D6E3C57A407DE2E8E2F24BC3D3C9E2E34DC9E2D7C6D7C1D9D45D7D40D4C1E840C2C540E4E2C5C440C1E240C140D4D6C4C5D35C1D4011505013FFEF}
+- !server {data: 01401150501DC85C40C1D3D3D6C3C1E3C9D6D5E240C6D6D940C9E2D7C640E7E7E7E7E7E740C9D540D7D9D6C7D9C5E2E25C1D4011D16013FFEF,
+ delayMillis: 299}
+- !server {data: 014011D1601DC85CD5D6E3C57A40C4C5C6C1E4D3E340D3C9C2D9C1D9E840E2E3D9E4C3E3E4D9C540E2C5D3C5C3E3C5C47A40404DE2D4D7C540D9C1C3C640C9D7C3E240E2C4E2C65D5C1D4011D2F013FFEF014011D2F01DC85CD5D6E3C57A40E2E8E2D7D9D6C340C8C1E240C2C5C5D540D9C560C1D3D3D6C3C1E3C5C45C1D4011D44013FFEF014011D4401DC85CD5D6E3C57A40E2E8E2C8C5D3D740C8C1E240C2C5C5D540D9C560C1D3D3D6C3C1E3C5C45C1D4011D55013FFEF,
+ delayMillis: 275}
+- !server {data: 014011D5501DC8401D4011D6601DC840C5D5E3C5D9407DC9E2D7E2E3C1D9E37D40C6D6D940C3D6D4D7E4E3C5D940C1E2E2D6C3C9C1E3C5E240D4C1E2E3C5D940D7C1D5C5D31D4011D7F01DC840404040D6D9407DD7C4C67D404040404040C6D6D940D4E5E240D7D9D6C7D9C1D440C4C5E5C5D3D6D7D4C5D5E340C6C1C3C9D3C9E3E8404DD7C4C65D1D4011D9401DC8401D40115A5013FFEF,
+ delayMillis: 568}
+- !server {data: 0140115A501DC8115AD1D9C5C1C4E8401D4013115B6013FFEF, delayMillis: 255}
+- !server {data: 01C2FFEF}
+- !server {data: FFFF}
+- !client {data: FFFF}
\ No newline at end of file
diff --git a/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn5250/login-with-multiple-flash-screen.yml b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn5250/login-with-multiple-flash-screen.yml
new file mode 100644
index 00000000..f8bee4ca
--- /dev/null
+++ b/src/test/resources/com/blazemeter/jmeter/rte/protocols/tn5250/login-with-multiple-flash-screen.yml
@@ -0,0 +1,27 @@
+- !server {data: FFFD27FFFD18, delayMillis: 2195}
+- !client {data: FFFC27}
+- !client {data: FFFB18}
+- !server {data: FFFA1801FFF0}
+- !client {data: FFFA1800}
+- !client {data: 49424D2D333137392D32FFF0}
+- !server {data: FFFD19FFFB19FFFD00FFFB00}
+- !client {data: FFFB19}
+- !client {data: FFFD19FFFB00FFFD00}
+# Server welcome screen
+- !server {data: 01F512A00000040000030440041100180107000000190000001101162240404040404040404040404040E289879540D695020137402011022F20E2A8A2A3859440404B404B404B404B404B407A2011024520E3C5E2E3E2E8E2402011032F20E2A482A2A8A2A38594404B404B404B404B407A2011034520E3C5E2E3E240404040402011042F20C489A2979381A8404B404B404B404B404B407A2011044520E3C5E2E3C4C9E2D7D3E82011061020E4A2859940404B404B404B404B404B404B404B404B404B404B404B404B404B404B201106341D402024000A000000000000000000001107341D402027000A11081020D799968799819461979996838584A49985404B404B404B404B404B404B404B404B201108341D400024000A0000000000000000000011091020D48595A440404B404B404B404B404B404B404B404B404B404B404B404B404B404B201109341D400024000A00000000000000000000110A1020C3A499998595A340938982998199A8404B404B404B404B404B404B404B404B404B20110A341D400024000A0000000000000000000011071020D781A2A2A696998440404B404B404B404B404B404B404B404B404B404B404B404B201107342702073E0011182722404DC35D40C3D6D7E8D9C9C7C8E340C9C2D440C3D6D9D74B40F1F9F8F06B40F2F0F1F34B404040402004520000FFEF,
+ delayMillis: 500}
+- !server {data: 01F512A00000040000030440041100180107000000190000001101162240404040404040404040404040E6859383969485020137402011022F20E2A8A2A3859440404B404B404B404B404B407A2011024520E3C5E2E3E2E8E2402011032F20E2A482A2A8A2A38594404B404B404B404B407A2011034520E3C5E2E3E240404040402011042F20C489A2979381A8404B404B404B404B404B407A2011044520E3C5E2E3C4C9E2D7D3E82011061020E4A2859940404B404B404B404B404B404B404B404B404B404B404B404B404B404B201106341D402024000A000000000000000000001107341D402027000A11081020D799968799819461979996838584A49985404B404B404B404B404B404B404B404B201108341D400024000A0000000000000000000011091020D48595A440404B404B404B404B404B404B404B404B404B404B404B404B404B404B201109341D400024000A00000000000000000000110A1020C3A499998595A340938982998199A8404B404B404B404B404B404B404B404B404B20110A341D400024000A0000000000000000000011071020D781A2A2A696998440404B404B404B404B404B404B404B404B404B404B404B404B201107342702073E0011182722404DC35D40C3D6D7E8D9C9C7C8E340C9C2D440C3D6D9D74B40F1F9F8F06B40F2F0F1F34B404040402004520000FFEF,
+ delayMillis: 5}
+# User sends user and password
+- !client {data: 002112A0000004000000073CF1110635E3C5E2E3E4E2D9110735E3C5E2E3D7E2E6FFEF}
+- !server {data: 001112A000000400000304F30005D97000FFEF, delayMillis: 1522}
+- !client {data: 004712A0000004000000000088003AD9708006000101000000000000000000000000000000000001F5F2F5F1F0F1F1020000000000000100000000014300000000000000000000FFEF}
+- !server {data: 000A12A000000400000CFFEF}
+# Server menu screen
+- !server {data: 028C12A00000040000030440041100001114061D50002000991101013AD4C1C9D5000000000000200000000000000000000000000000000000000022C9C2D4408940D481899540D48595A420110202274020400000400000274020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020E2A8A2A385947A200020E3C5E2E3E2E8E200201103013AE285938583A34096958540968640A38885408696939396A68995877A2011050620F14B00E4A2859940A381A292A22011060620F24B00D6868689838540A381A292A22011080620F44B00C6899385A26B409389829981998985A26B4081958440869693848599A220110A0620F64B00C3969494A495898381A3899695A220110C0620F84B00D799968293859440888195849389958720110D0620F94B00C489A2979381A8408140948595A420110E0520F1F04B00C9958696999481A389969540C1A2A289A2A38195A3409697A3899695A220110F0520F1F14B00C9C2D4408940C1838385A2A240A381A292A22011110520F9F04B00E2898795409686862011130120E285938583A3899695409699408396949481958420111401207E7E7E6E24111550201116013AC6F37EC5A789A320003AC6F47ED799969497A320003AC6F97ED985A3998985A58520003AC6F1F27EC3819583859320003AC6F1F37EC9958696999481A389969540C1A2A289A2A38195A3201117013AC6F2F37EE285A340899589A389819340948595A420111801224DC35D40C3D6D7E8D9C9C7C8E340C9C2D440C3D6D9D74B40F1F9F8F06B40F2F0F1F34B00000000000000000000000000000000000000000000000000000000000000000000000000000000002200201314070411001C04520000FFEF,
+ delayMillis: 89}
+# User selects tasks menu item
+- !client {data: 001112A00000040000001408F1111407F1FFEF}
+# Server tasks menu screen
+- !server {data: 02F012A00000040000030440041100001114061D50002000991101013AE4E2C5D9000000000000200000000000000000000000000000000000000000000022E4A2859940E381A292A220110202274020400000400000274020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020E2A8A2A385947A200020E3C5E2E3E2E8E200201103013AE285938583A34096958540968640A38885408696939396A68995877A2011050620F14B00C489A2979381A84096994083888195878540A896A499409196822011060620F24B00C489A2979381A8409485A2A2818785A22011070620F34B00E28595844081409485A2A28187852011080620F44B00E2A4829489A34081409196822011090620F54B00E696999240A689A38840A896A49940A29796969385844096A4A397A4A34086899385A220110A0620F64B00E696999240A689A38840A896A499408281A3838840919682A220110B0620F74B00C489A2979381A84096994083888195878540A896A49940938982998199A8409389A2A320110C0620F84B00C3888195878540A896A499409781A2A2A696998420110D0620F94B00C3888195878540A896A49940A4A28599409799968689938520110F0520F6F04B00D496998540A4A2859940A381A292409697A3899695A22011110520F9F04B00E2898795409686862011130120E285938583A3899695409699408396949481958420111401207E7E7E6E24111550201116013AC6F37EC5A789A320003AC6F47ED799969497A320003AC6F97ED985A3998985A58520003AC6F1F27EC3819583859320003AC6F1F37EC9958696999481A389969540C1A2A289A2A38195A3201117013AC6F1F67EE2A8A2A3859440D481899540948595A420111801224DC35D40C3D6D7E8D9C9C7C8E340C9C2D440C3D6D9D74B40F1F9F8F06B40F2F0F1F34B00000000000000000000000000000000000000000000000000000000000000000000000000000000002200201314070411001804520000FFEF,
+ delayMillis: 2}