Replaying sessions from mobile devices requires Tealeaf to convert JSON data to HTML. Tealeaf templates process JSON data that is generated by the mobile device and convert that data into HTML. The template expressions can reference JSON.
Templates accept two sources of input from JSON data. These inputs are:
- Environment input is the static (unchanging) information that is contained in the JSON header.
Examples of Environment input include:
osType osVersion msgVersion j2hVersion clientEnvironment
Environment input is accessed with the dollar sign ($), for example,
[$valueName]
. - Context input is the single type 10 JSON message being processed.
The context input is used by the templates to render data and contains layout and control information.
Context input is accessed without the dollar sign ($), for example,
[valueName]
.
How Tealeaf templates convert JSON data to HTML
In a process similar to ASP and JSP, Replay uses the templates to convert JSON to HTML. The conversion is not hardcoded. The templates are the customization point and the file type10.html
is the root of the conversion process.
The templates are located in ReplayServer/TLT and consist of fixed or static text and inline expressions, into which Replay can substitute other values.
The processing sequence for converting JSON data to HTML is as follows:
- The entire
type10
JSON message is passed to theType10.html
template.Type10.html
is the root of the conversion process. - The
Type10.html
template reads thetype10
JSON message to determine if it is coming from an Android or iOS device.- If
Type10.html
determines that the message is from an Android device, it passes the entiretype10
JSON message into the android\\root.tlt. - If
Type10.html
determines that the message is from an iOS device, it passes the entiretype10
JSON message into the iOS\\root.tlt.
The iOS\\root.tlt and android\\root.tlt are templates in-and-of-themselves that can emit some HTML and can also pass all or part of the JSON message into other templates.
- If
The following diagram illustrates how Replay uses templates to convert JSON to HTML.
Note: Template expressions are delimited with leading {{
and trailing }}
set of braces.
The HTML tags <label> </label>
are fixed text. {{
and }}
delimit the expression. The expression itself is ["currState"]["text"]
.
As an example, the result of rendering this template might be:
<label>Tealeaf</label>
A template might contain any amount of fixed text and any number of delimited expressions. JSON data from the logging framework post is rendered by the templates to produce HTML.
How Replay renders JSON data as HTML in BBR
Replay interprets the JSON data in a session that was posted to TealeafTarget by the mobile logging framework.
The JSON data posted by the logging framework includes a series of messages that describe events that occurred within the mobile application. Each message has a numeric type that indicates what type of information that message contains.
Replay relies on several parts of the JSON post.
- Header information that describes the mobile application and device.
- Type 10 messages that describe the platform native controls on the screen at a moment in time.
- Type 4 messages that describe changes in the state of controls on the screen.
In Browser Based Replay, web sessions are organized into Pages and UI events, with UI events nested under their pages. When you replay a mobile application session, Browser Based Replay reuses this same paradigm with Type 10 messages that are presented as pages and with Type 4 messages that are represented as UI events nested under those pages.
To make the JSON data in Type 10 and Type 4 messages easy to understand, Type 10 messages are converted into HTML, and Type 4 messages are drawn onto that HTML. To enable this, each control is given a unique identifier that remains the same across both Type 10 and Type 4 messages.
For example, a Type 10 message might indicate the presence of a Textbox control on the mobile application screen with a certain value, and a subsequent Type 4 message may indicate a change in the value of that Textbox.
In Browser Based Reply, the Type 10 message is represented as a page in the Navigation List, and the replay of that page is the result of the conversion from the Type 10 message into HTML. The Type 4 message is represented as a UI event under that page, and the replay of that UI event shows the Type 10 page but with the Textbox value updated and the Textbox appearing with the green highlighting that is characteristic of UI events.
Replay server templates
Tealeaf ships with ReplayServer
templates.
These templates are installed to the ReplayServer\TLT
directory when you install Tealeaf.
- \ReplayServer\TLT
- \android (folder)
- \ios (folder)
- \readme.txt (file)
- \type10.html (file)
The directory path (ReplayServer\TLT) and the type10.html
file are the only things in the template system that are hardcoded.
In Tealeaf, replaying Native Mobile sessions relies on the type10.html
template and other template files called from type10.html
to render mobile session data (in the form of JSON Type 10 messages) to HTML.
You can edit the template files in ReplayServer/TLT to control how the JSON data is converted to HTML. Type10.html
delegates to templates in the iOS or Android sub-directories and is root of all JSON-to-HTML conversions.
Note: Customizing the JSON-to-HTML conversion process by modifying the templates in ReplayServer/TLT has certain drawbacks. You will likely have to re-implement any changes you make to the templates when a new version of Tealeaf is installed.
The type10.html
file converts type10
messages (JSON message) to HTML. You can modify the contents of the type10.html
to control JSON data rendering in BBR.
The type10.html
file branches into either the iOS folder or the android folder.
{{
if(
eq([$"osType"],"Android"),
template([], "android\\root.tlt"),
template([], "ios\\root.tlt")
)
}}
In this example, the Type10.html template consists entirely of a single expression that is delimited by {{ }}
characters.
The environment value osType
is tested to see whether it is equal (eq
) to the string Android
.
If this test passes, the complete context value, represented as []
, is passed into the root.tlt
template in the android directory. Since the root of a single Type 10 message is passed as the context, this is what is sent to that sub template. Alternately, if the test fails, the Type 10 message is passed to a template under the ios directory.
Version checking the Tealeaf templates
When a mobile session is rendered, Tealeaf performs a version check on the type10
message only. If the version check reveals a breaking change from the API not being compliant with the version of Tealeaf templates installed, the rendering process throws the following exception error:
Caught Template Exception: A check against on json message format indicates
that the API and the installed template are incompatible.
Update your template as needed.
To address this exception error, update the version of the Tealeaf templates installed to be compatible with the API.
Version checking and Tealeaf templates
For mobile sessions rendered with SDK version 5.0.0.0 or later, Tealeaf performs version checking on the type 10 message.
The version checking process relies on a version string, which is embedded inside each type 10 message. The version string adheres to a convention where breaking changes increment the major version #
, while non-breaking changes increment the minor version
#
. If the version check reveals a breaking change from the API that may not be compatible with the version of the Tealeaf templates installed, the rendering process throws the following exception error:
Caught Template Exception: template update needed -
templates have not been validated
against type 10 message version #.#
If you encounter this exception error, you need to update the version of the Tealeaf templates installed to be compatible with the API.
Template language
Tealeaf mobile app session replay template language uses a functional programming model.
The mobile app session replay template language has the following characteristics.
- Each template language macro consists of a single expression that consists of nested function calls, which results in a JSON value that is rendered as the output.
- No existing values can be modified; only the creation of modified copies is allowed. Therefore, parameters of functions cannot be modified.
- Functions can have no side-effects.
- Every function or jpath navigation either returns a JSON value or throws an exception as its only result or effect.
- Parameters that are not used are guaranteed to never be evaluated. For example, in
default()
,if()
orforeach()
functions (or any place else). - The template language provides exception-based error handling where any errors that occur when processing an expression will generate an exception. If the exception is recoverable, (for example, a jpath navigation element that does not exist), it may be handled by a
default()
function. Other exceptions such as parsing errors or JSON parameters of the wrong type passed to a function will generate "non-defaultable" ( fatal) exceptions that cannot be caught by default() but which is caught by the Replay Server.
Template language constructs
The mobile app session replay template language is composed of three constructs; inline JSON literal values, Jpath style JSON navigation that is enclosed in square brackets, and composition of predefined function calls.
Inline JSON literal values
Inline JSON literal values are quoted strings; integers; doubles floats and real; the constants true
, false
, and null
; and arrays and objects that are all converted to JSON values.
JSON uses [ value, value, value ]
to specify arrays, but if that is used for inlining JSON arrays, it would create a parser ambiguity with jpath navigation, so inlined array value constants must be specified with parenthesis instead as ( value, value, value
)
. The output contains JSON square brackets []
if an array is output.
String constants are JSON strings and must not include any "
(quotation), \
(backslash), or control characters (for example, newline, form-feed, tab) in the strings. The JSON string escape sequences are provided except for \uxxxx
(hex unicode code point).
\" quote
\\ backslash
\/ forward slash (optional /
may be used without escapting) \b backspace \f form-feed \n newline \r carriage return \t horizontal tab
{{ "JSON text string \n" }}
{{ 5 }}
{{ 5.6 }}
{{ 5.6e10 }}
{{ true }}
{{ false }}
{{ null }}
{{ ( 6, 8.2, "value", true, false, null ) }} outputs as [6,8.2,"value",true,
false,null]
{{ {"a" : 3, "b" : true, "c" : (5, 2, 3), "d" : { "e" : 2, "f" : 3}} }}
outputs as: {"a":3,"b":true,"c":[5,2,3),"d":{"e":2,"f":3}}
Jpath style JSON navigation enclosed in square brackets
This construct has the following variants.
[]
(empty brackets) indicate the root of the JSON tree that is passed when starting the template. In most cases, the root context is the default and []
is optional.
["value-name"]
indicates a value with the specified name within a JSON object.
[3]
indicates the fourth value of a JSON array (0 based index).
[@"iter-name"]
indicates the name of a limited-scope iterator or variable. These are used with foreach()
, let()
, and filter()
function calls.
[$"env-var-name"] indicates an environment variable value. These values are made available through the template engine, but the values are determined and provided by the program that starts the template engine. Expected usage of these values is for version information of various aspects of the system or other data that is not contained within the root JSON value. Determination of which environment variables are present should be based on the value of the [$"j2hVersion"]
variable because J2H is responsible for setting these values.
Current environment values that are provided by the ReplayServer and J2H are:
[$"osType"]
is either Android or iOS.[$"osVersion"]
is version of the Android or iOS operating system.[$"msgVersion"]
is the version of the JSON message that is used for the type-10 message and[$"clientEnvironment]
.[$"j2hVersion"]
is the version of j2h.dll that started the template engine. This value is primarily used to determine what other environment variables should be present.[$"clientEnvironment"]
is the"clientEnvironment"
object from the header of the JSON message that also included the type-10 message that is passed as the primary value. Use the[$"msgVersion"]
value to determine what values should be present in this value.
{{ ["layout"]["controls"][0]["tltype"] }}
is equivalent to:
{{ []["layout"]["controls"][0]["tltype"] }}
Note: Frequently, the JSON navigation is the only thing inside {{...}}
. In that case, the contents of that JSON value are substituted for the expression.
Composition of predefined function calls
Note: User-defined functions are not supported.
Note: Values/sub-expressions that are never used are never executed. For example, the else portion of an if()
expression where the predicate condition evaluates to true.
All functions return a JSON value or throw an exception, and take only expressions that resolve to JSON values as arguments.
Some exceptions can be caught and handled by the default()
function. Examples of these exceptions are JSON-navigation array range or missing object values. Other exceptions cannot be intercepted by default()
and are fatal. Examples of these exceptions are parsing errors or JSON-navigation through invalid JSON value types. These exceptions always cause a failure for that template and any template parents/ancestors that instantiated it. These exceptions are caught by the Replay Server, which logs the appropriate information and generates HTML that indicates the error.
Predicate values are evaluated as true if a boolean value is true
; an int or uint value is not zero; or a string, object, or array value is not empty.