Skip to content

Commit

Permalink
RTE-Extractor, hide password, sample naming, many fixed issues.
Browse files Browse the repository at this point in the history
• RTE-Extractor, is a component which adds the possibility to create variables with the current cursor position or to search from a position for next/previous field.

• Possibility to name samplers while recording.

• Hidde credentials

• Issue requesting to remove RTERecorder component while running script in blazemeter was solved.

• Bug which used to remove input by Label/Coords when no value specified was also solved.
  • Loading branch information
Baraujo25 committed Sep 19, 2019
1 parent 81f66d0 commit 6daea92
Show file tree
Hide file tree
Showing 51 changed files with 1,429 additions and 200 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ People who usually work with these IBM servers interact with them, basically, by
## Usage

### Using the plugin
The plugin adds three different elements to JMeter:
The plugin adds four different elements to JMeter:

#### A Recording Controller (RTE-Recorder)
![alt text](docs/RecorderPanel.png "RTE Recorder")
Expand All @@ -35,14 +35,14 @@ To start recording, the user should specify the _Server_, _Port_, _Protocol_, _T
Once everything is configured, the user proceeds to start the recording session, pressing START button. After the connection to the mainframe application is established (supposing configurations are right), the **[Terminal Emulator](/docs/terminal-emulator.md)** will show up.

![alt_text](docs/Emulator-Login.png)
![alt_text](docs/emulator-login.png)

>Click [here](/docs/terminal-emulator.md) to see all the information you must know about terminal emulator.
Now we are able to interact with our client through RTE-Emulator. Every interaction will be automatically saved in samplers (_[check out everything about samplers ](#sampler-rte-sampler)_).
Once we have ended the flow that we want to record, we can easily close the terminal emulator or press STOP button to stop our recording.

![alt_text](docs/Final-Testplan.png)
![alt_text](docs/final-testplan.png)


##### Child View Results Tree integration:
Expand Down Expand Up @@ -95,6 +95,13 @@ The RTE Sampler fields are:
All the "waiters" use a stable timeout value (in milliseconds) which specifies the time to wait for the emulator to remain at the desired state. The default value is 1000 milliseconds, but can be changed by adding the property `RTEConnectionConfig.stableTimeoutMillis=<time_in_millis>` in *jmeter.properties* file. The "Wait for silent" waiter is not affected by this setting since it has an explicit field for such purpose.
> Warning: both Stable Timeout and Silent Interval should be shorter than Timeout value, otherwise the sampler will always return a timeout error.
#### RTE-Extractor
![alt_text](docs/rte-extractor.png)

RTE-Extractor is a post-processor which its main purpose is to extract positions from response headers to be used later as a JMeter variable.
> Check [here](/docs/rte-extractor.md) for more information.

### Example

Suppose the user wants to automate the following workflow with an AS400 server (TN5250 system):
Expand Down
Binary file modified docs/Emulator-Login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/assertion-usage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/extractor-component.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/extractor-usage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/input-by-label-usage.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/response-headers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions docs/rte-extractor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# RTE-Extractor
![alt_text](rte-extractor.png)
**REMEMBER**: This Extractor will ease the development of future implementations. Therefore is not mandatory for script creation. However it can be used in particular cases.

The RTE Extractor is a component that must be embedded into a sampler.


<h5>How to add a RTE-Extractor:</h5>
![alt_text](extractor-component.gif)


The aim of the Extractor is to have the ability to look into response headers for a Field Position (from a given position) and to set a JMeter Variable with the corresponding field position.

Additionally, you are able to skip fields using the tab offset.

<h5>Tab offset cases:</h5>
- Case 1: Value equals to one, extractor will look for the closest field forward.
- Case 2: Value bigger than one, extractor will look for the closets field forward and skip field as many times as indicated. E.g: with an offset of two, it will search for the next field and then, skip that one to finally get the next one.
- Case 3: Value equals to minus one, extractor will look for the closest field backwards.
- Case 4: Value lower than minus one, same behaviour as **_case 2_** but backwards. E.g: offset equals to minus two, extractor will look for the nearest field backwards and then skip one.

Also there is an option to set the cursor position as a JMeter variable.

In order to search for a field in the screen we have added Field Positions in Response Headers.


![response_headers_fields_positions](response-headers.png)

Those positions are the real field positions. Place where we can insert values while recording.


Going back to the extractor, there is an obligatory field, which will contain the prefix name of your future variable:
![variable_prefix](variable-prefix.png)

In the previous image we can visualize that the variable prefix **_position_** will have the cursor position of the current sampler. Therefore the variable will split in two parts: (row, column). The row value will be saved in a variable called **_position_ROW_** and the column value will be **_position_COLUMN_**
> You can check how to use JMeter variables in your tests over [here](https://jmeter.apache.org/usermanual/functions.html#top).

<h3>Example of usage</h3>

Let's put the extractor to work. In order to do that, we are going to select the option _Extract next filed from position_ and we will give a position from where to search.

In this example we will look for the next field from position (1,2). As we have seen in the response headers picture, there is a field in position (1,27) which will be our target. In order to accomplish that, we must specify **tab offset** to 1.

Let's visualize all of this:

![alterText](extractor-usage.gif)
> In this example we gave the extractor the beginning of a field (1,2), and as you could see, it will search for the next field on the right, even when the given position is inside a field or outside of it.
Binary file added docs/rte-extractor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/rte-recorder-emulator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion docs/terminal-emulator.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
- You can press assertion button ![alt_text](../src/main/resources/dark-theme/assertion.png) when you want to make sure that a part of the screen has appeared in the screen. This assertion has the same behaviour as JMeter Assertions. To assert for a part of the screen you just have to select a part of the screen and press the button. An assertion will be added to corresponding sampler.
>[Here](#recorder-screen-assertion-usage) is an example of usage.
- Clicking on ![alter_text](../src/main/resources/dark-theme/not-visible-credentials.png) / ![alter_text](../src/main/resources/dark-theme/visible-credentials.png) you will be able to show/hide credentials.

- If you click on the ![alter_text](../src/main/resources/dark-theme/help.png) icon in the emulator, a pop up window will be displayed with general help information on the emulator: shortcuts, explanation about indicators on the screen, etc.


- **Sample name:** As the label says, you can specify the name of the sample in current screen.

### Input By Label Usage

![alt_text](input-by-label-usage.gif)
Expand Down
Binary file added docs/variable-prefix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>com.blazemeter.jmeter</groupId>
<artifactId>jmeter-bzm-rte</artifactId>
<packaging>jar</packaging>
<version>2.1.1</version>
<version>2.2</version>
<name>RTEPlugin Sampler as JMeter plugin</name>

<properties>
Expand Down
29 changes: 28 additions & 1 deletion src/main/java/com/blazemeter/jmeter/rte/core/Position.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.blazemeter.jmeter.rte.core;

import java.awt.Dimension;
import java.util.Comparator;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Position {

public static final int UNSPECIFIED_INDEX = 0;
private static final Pattern POSITION_PATTERN = Pattern.compile("^\\((\\d+),(\\d+)\\)$");

private int row;
private int column;
Expand All @@ -18,6 +23,16 @@ public Position(int row, int column) {
this.column = column;
}

public static Position fromString(String text) {
Matcher m = POSITION_PATTERN.matcher(text);
if (m.matches()) {
return new Position(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)));
} else {
throw new IllegalArgumentException("The text '" + text + "' does not match position format");
}

}

public int getRow() {
return row;
}
Expand Down Expand Up @@ -46,6 +61,18 @@ public int hashCode() {

@Override
public String toString() {
return "(" + row + ", " + column + ")";
return "(" + row + "," + column + ")";
}

public boolean isInside(Dimension screenDimension) {
return (row <= screenDimension.height && row >= 1) && (
column <= screenDimension.width
&& column >= 1);
}

public int compare(Object o) {
return Comparator.comparingInt(Position::getRow)
.thenComparing(Position::getColumn)
.compare(this, (Position) o);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.blazemeter.jmeter.rte.core;

import com.blazemeter.jmeter.rte.core.Screen.Segment;
import com.blazemeter.jmeter.rte.core.ssl.SSLType;
import com.blazemeter.jmeter.rte.sampler.Action;
import com.helger.commons.annotation.VisibleForTesting;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
Expand All @@ -18,6 +20,11 @@
*/
public class RteSampleResultBuilder {

public static final String FIELD_POSITION_SEPARATOR = ", ";
public static final String HEADERS_TERMINAL_TYPE = "Terminal-type: ";
public static final String CURSOR_POSITION_HEADER = "Cursor-position: ";
public static final String FIELDS_POSITION_HEADER = "Field-positions: ";
public static final String HEADERS_SEPARATOR = "\n";
private SampleResult result;
private String server;
private int port;
Expand All @@ -32,12 +39,24 @@ public class RteSampleResultBuilder {
private Position cursorPosition;
private boolean soundedAlarm;
private Screen screen;
private String responseHeaders;

public RteSampleResultBuilder() {
result = new SampleResult();
result.sampleStart();
}

@VisibleForTesting
public RteSampleResultBuilder(Position cursorPosition, Screen screen, String responseHeaders,
TerminalType terminalType) {
result = new SampleResult();
result.sampleStart();
this.screen = screen;
this.cursorPosition = cursorPosition;
this.responseHeaders = responseHeaders;
this.terminalType = terminalType;
}

public long getCurrentTimeInMillis() {
return result.currentTimeInMillis();
}
Expand Down Expand Up @@ -152,7 +171,8 @@ public RteSampleResultBuilder withAttentionKey(AttentionKey attentionKey) {
public SampleResult build() {
result.setRequestHeaders(buildRequestHeaders());
result.setSamplerData(buildSamplerData());
result.setResponseHeaders(buildResponseHeaders());
responseHeaders = responseHeaders == null ? buildResponseHeaders() : responseHeaders;
result.setResponseHeaders(responseHeaders);
result.setDataType(SampleResult.TEXT);
if (result.getResponseDataAsString().isEmpty()) {
result.setResponseData(screen != null ? screen.getText() : "", StandardCharsets.UTF_8.name());
Expand All @@ -164,7 +184,7 @@ private String buildRequestHeaders() {
return "Server: " + server + "\n" +
"Port: " + port + "\n" +
"Protocol: " + protocol + "\n" +
"Terminal-type: " + terminalType + "\n" +
HEADERS_TERMINAL_TYPE + terminalType + "\n" +
"Security: " + sslType + "\n" +
"Action: " + action + "\n" +
(inputInhibitedRequest != null ? "Input-inhibited: " + inputInhibitedRequest + "\n" : "");
Expand All @@ -186,10 +206,25 @@ private String buildResponseHeaders() {
if (action == Action.DISCONNECT) {
return "";
}
return "Input-inhibited: " + inputInhibitedResponse + "\n" +
"Cursor-position: " + (cursorPosition != null ? cursorPosition.getRow() + ","
+ cursorPosition.getColumn() : "") +
(soundedAlarm ? "\nSound-Alarm: true" : "");

String fieldsPositions = getFieldsPositions();
return "Input-inhibited: " + inputInhibitedResponse + HEADERS_SEPARATOR +
CURSOR_POSITION_HEADER + (cursorPosition != null ? cursorPosition.toString() : "")
+ HEADERS_SEPARATOR +
(soundedAlarm ? "Sound-Alarm: true" + HEADERS_SEPARATOR : "") +
(!fieldsPositions.isEmpty() ? FIELDS_POSITION_HEADER
+ fieldsPositions + HEADERS_SEPARATOR : "");

}

private String getFieldsPositions() {
if (screen == null) {
return "";
}
return screen.getSegments().stream()
.filter(Segment::isEditable)
.map(s -> s.getPositionRange().toString())
.collect(Collectors.joining(", "));

}
}
Loading

0 comments on commit 6daea92

Please sign in to comment.