Overview

Xray's built-in Document Generator feature, and also the Xporter Jira app, allows you to export information from Jira issues and supported Jira plugins, including Xray, to Word, Excel, PDF, or other type of documents.

The layout of the output document can be customized using templates built in .DOCX (Microsoft Word), .XLSX (Microsoft Excel) or even .ODT (Open Office) files.

Templates are regular documents where certain placeholders (e.g., #{...}, ${...}, &{...}, %{...}) can be used to render some fields or to perform auxiliary operations.

The Xporter language syntax used within the document template allows you to:

  • core logic
    • define temporary variables
    • implement conditional blocks (i.e., "if" statements) using JavaScript
    • perform iterations/loops (i.e., "for" statements) over fields or entities that are list based (e.g., components, comments), with ability to filter
  • processing
    • obtain the input issue(s) used during the export document request
    • obtain issues on-demand using JQL queries
  • rendering
    • render issue's custom fields using "mappings" in Xporter's terminology
    • render entities and attributes connected to Jira issues from supported Jira apps using tailored "mappings" for this purpose
    • render text using a JavaScript expression

Please check Xporter's documentation to learn more about Working with Templates, and the page that has more information about the mappings available to obtain Xray related data.

Code snippets

Using ${...} resolves the inner expression that can either refer to:

  • a variable
  • a field, for the "current context" (i.e., for the current issue either received or that we are iterating over)
  • a function (e.g., set()...)

Whenever using %{...} the inner expression is assumed to be inline JavaScript that will be evaluated; the output text will be returned and rendered in the document, for example. 

Context

Xray's Document Generator (or Xporter app) engine will receive either a issue or a list of issues as input/incoming context, depending from where the document was exported from.

A given issue may have fields that are "simple" single-value attributes or that are "lists". These lists may be array of objects (e.g., labels, components) stored on the issue or may be virtual lists of related issues/entities (e.g., Preconditions on a Test, all the Test Runs in a Test Execution). It's possible to iterate on these lists and the inner context becomes the element being iterated.


Parent expressionIncoming contextInner context

Syntax for accessing fields on the inner context element

Example of accessing a field on the inner context element

none

(i.e., whenever exporting a single issue, that issue becomes the parent context)

the Jira issue

(i.e., the one it was exported from)

the incoming context

(i.e., the issue)

${...}

${Priority}

&{for issues}

(i.e., whenever exporting multiple issues, inside the  "&{for issues}" loop the issue becomes the current context)

the chosen Jira issues

(e.g., the ones selected for bulk export)

a issue from the list of the issues from the incoming context${...}${Priority}

#{for j=LinksCount}

(i.e., some fields have a corresponding "...Count" element that can serve to implement an iterator)

the Jira issue

(i.e., the one it was exported from)

each of the issue links, one by one, on the issue where it was export from${Links[j]}
#{for components}

the Jira issue

(i.e., the one it was exported from)

each of the components, one by one, from the issue where it was export from${Components[n]}${Components[n].Name)
#{for testruns}

the Jira issue

(i.e., the one it was exported from)

each of the Test Runs, one by one, from the Test or Test Execution issue where it was export from${TestRuns[n]}${TestRuns[n].Key)
#{for idx=JQLIssuesCount|clause=key in testRequirements('${Tests[n].Key}')}N/Aeach issue, one by one, returned by the JQL Expression${JQLIssues[idx]}${JQLIssues[idx].Summary}
#{for s=TestRuns[n].TestStepsCount}${TestRuns[n].TestSteps[s]}each Test Step, one by one, of a given Test Run, from the Test or Test Execution issue where it was export from${TestRuns[n].TestSteps[s]}${TestRuns[n].TestSteps[s].Action}


Variables

Fields, for example for the current issue in context, are case sensitive.

  • ${Priority}  works
  • ${priority} doesn't work

Create a temporary/auxiliary variable

It's possible to create temporary/auxiliary variables using the ${set(...)} function.

Variables may contain simple values (e.g., string, integer, float based); they cannot contain complex objects or list/array of objects.


/* as string */
${set(myVar, "A")}

/* as integer or float */
${set(myVar, 0)}
${set(myVar, 1.2)}

Print a temporary/auxiliary variable

%{${myVar}}

Increment an integer variable

${set(myVar, 0)}
${set(myVar, %{${myVar} + 1})}

Concatenation of a string variable

${set(myVar, 'A')}
${set(myVar,%{'${myVar}'.concat('${JQLIssues[a].Key},')})}

JavaScript

JavaScript can be used to render some text or can be used in some operations (e.g., for filtering iterations, to implement if conditionals).

Some notes follow:

  • inline script is supported; the output is returned (either to be printed or to be evaluated depending on the context) using the %{<inline_JS_code_snippet>} syntax. 
  • multiline JS is not supported
    • UNSUPPORTED
      %{var a='xpto';
      var b='dummy';}
  • %{...} always returns something, ultimately a boolean 

    • In the following example, the rendered document will have "true<newline>bla".

      %{var a='xpto';}
      bla
    • .To avoid the previous behaviour we could force returning an empty string, while at the same time make it inline. In this case the output would be just "bla".
      • %{var a='xpto';''}bla


Tip

JavaScript can be used to perform some pre or post-processing on variables using the power of JavaScript syntax.

Examples include:

  • removing starting & ending spaces (i.e., trimming) on text variables
  • replacing some text on a variable
  • increment/decrement a variable
  • etc

JavaScript and variables

In JavaScript expressions we can use local JavaScript variables or we can refer to an external variable defined by Xporter itself.

Local JavaScript variables can be printed from outside the JS expression where they were first defined in. This means that JS variables will be available in other JS expressions that may follow.


Using local variables in JavaScript
%{var a='xpto';a.toUpperCase()}
The "a" variable defined in a previous JS statement has the value %{a}.
OUTPUT
XPTO
The "a" variable defined in a previous JS statement has the value xpto.


In JS expression we can refer to external variables, defined by Xporter using the ${set(varname,value)} syntax.

${set(outsideVar, 1)
${set(myName, "  Sergio F.  ")}
%{${outsideVar}+2}
%{'${myName}'.trim()}
OUTPUT
3
Sergio F.

Loops

Regular, ad-hoc loops as you have in traditional languages (e.g., "do ... while", "while ... do") are not supported.

"For loops" are partially supported but are restricted for iterating well-known entities/fields that are list/array based.

It's not possible to make a regular, ad-hoc "for loop" like "for(n=3;n<10;n++)"; it's a current limitation.

In JavaScript expressions, we can use a standard JavaScript for loop but all loop must live within that statement; we cannot use one JS expression to start the JS "for" statement and then use another JS expression later to end that loop.

UNSUPPORTED
%{for (let i = 0; i < cars.length; i++) { }
...
%{ } }

Iterations

Iterations use "for"; however, the syntax changes slightly depending on the context.


Tip

Whenever using #{for ...}, &{for ...} please make sure that you don't have any spaces before and after or else it may not be processed.


Iterating over input issues

Whenever iterating over the issues received as the input for the template, the for syntax uses a &.

Within the loop, the issue is not  referred explicitly; we can simply use the ${field} notation to obtain that field for the current issue in the iteration.

&{for issues}
 ${Key}: ${Summary}
&{end}


Iterating over of array of objects (non issues!)

The index variable by default is called "n". In this case, we cannot define a custom name for the index variable.


#{for testruns}
 ${TestRuns[n].Execution Status}
#{end}

#{for components}
 ${Components[n].Name}
#{end}

#{for Images}
 ${Images[n].Image}
#{end}


Iterating over of array of objects, based on an existing counter attribute

Several entities have an attribute like "xxxCount", having a corresponding attribute "xxx" storing an array of objects.

The index variable is defined explicitly.

The for loop syntax is different from what we would expect at first sight.

/* this loop iterates over the JQLIssues attribute on the current scope, using index variable "m" (0<=m<JQLIssuesCount). It's like considering that JQLIssuesCount represents the size of the array named "JQLIssues". */
#{for m=JQLIssuesCount|clause=component = '${Components[n].Name}'}
${JQLIssues[m].Key}
#{end}

/* this loop iterates over the ExecutionEvidences attribute of TestRuns[n] object, using index variable "d" (0<=d<ExecutionEvidencesCount). It's like considering that TestRuns[n].ExecutionEvidencesCount represents the size of the array named TestRuns[n].ExecutionEvidences. */
#{for d=TestRuns[n].ExecutionEvidencesCount}
Id: ${TestRuns[n].ExecutionEvidences[d].Id}
#{end}


Filtering iterations

/* iterate only over "Test Execution" issues */
&{for issues|filter=%{'${IssueTypeName}'.equals('Test Execution')}}
 ${Key}
&{end}

/* show issue keys of the linked issues using the "duplicates" issue link
#{for j=LinksCount|filter=%{'${Links[j].LinkType}'.equals('duplicates')}}
 ${Links[j].Key}
#{end}

Conditionals

Conditionals use the "#{if ...}" syntax.

More info here.

Using ifs... 

/* compare temporary integer variable */
#{if (%{${total} <= 0})}
#{end}


/* compare integer variable/attribute */
#{if (%{'${IssueTypeName}'.equals('Test Execution') })}
#{end}

/* compare variable/attribute with a string */
#{if (%{'${Priority}'.equals('Medium')})}
#{end}

/* check based on boolean attribute */
#{if (%{${Comments[n].Internal}})}
#{end}

/* check if a field or a variable contain some substring */
#{if (%{'${desc}'.contains('some_word')})}
#{end}


Implementing "else" statement

Unfortunately, there is no support for "else" statement.

Thus, we need to implement by hand. We can either use another if statement that negates the first one or use a variable to achieve a similar purpose but in a more elegant way.


/* compare temporary integer variable */
#{if (%{(${total} <= 0)})}
#{end}
#{if (%{!(${total} <= 0)})}
#{end}

${set(myCondition, %{${total} <= 0})}
#{if (%{myCondition})}
#{end}
#{if (%{!myCondition})}
#{end} 

String manipulations

Remove all spaces

Some fields may be list based, such as the Labels or the Components fields on issues. If we print them, they will be formatted such as "value1, value". In thse cases, we may want to remove the spaces, for example right after the comma.

%{'${TestRuns[n].Labels}'.replace(/\s/g, '')}

Remove last comma

Whenever joining elements by hand, in an iteration for example, we may concatenate strings appending a final delimeter (e.g., comma), leading to a results such as "<value1>,<value2>,". In this case it may be useful to remove the last comma and any remaining spaces.

%{'${defects}'.replace(/,\s*$/, '')}

Test

The following examples assume the current context is a Test issue.

Requirements linked to/covered by a given Test


SERVERDC

${set(Req,'')}
#{for a=JQLIssuesCount|clause=key in testRequirements('${Key}')}
#{if (%{'${Req}'.indexOf('${Key},')==-1})}
${set(Req,%{'${Req}'.concat('${JQLIssues[a].Key},')})}
#{end}
#{end}
%{'${Req}'.replace(/,\s*$/, '')}


CLOUD

Thie example assumes that the coverage of a "requirement"/story by  the related Test issues is made using the issue link "tests".

${set(Req,'')}
#{for k=TestRuns[n].LinksCount|filter=%{'${TestRuns[n].Links[k].LinkType}'.equals('tests')}}
#{if (%{'${Req}'.indexOf('${TestRuns[n].Links[k].Key}')==-1})} 
${set(Req,%{'${Req}'.concat('${TestRuns[n].Links[k].Key},')})} 
#{end} 
#{end}
%{'${Req}'.replace(/,\s*$/, '')}"

Test Runs of a Test

SERVERDC CLOUD

#{for testruns}
 ${TestRuns[n].Execution Status}
#{end}

Preconditions associated with a Test

SERVERDC CLOUD

#{for preconditions}
    ${PreConditions[n].Key}
    ${PreConditions[n].Summary}
    ${PreConditions[n].Description}
#{end}

Preconditions "associated" with a TestRun

CLOUD

#{for l=TestRuns[n].PreConditionsCount}
#{if (%{'${TestRuns[n].PreConditions[l].PreCondition.Definition}'.equals('')})}
This Precondition ${TestRuns[n].PreConditions[l].Key} doesn’t have a definition.
#{end}
#{if (%{!'${TestRuns[n].PreConditions[l].PreCondition.Definition}'.equals('')})}
Definition of Precondition ${TestRuns[n].PreConditions[l].Key}: ${TestRuns[n].PreConditions[l].PreCondition.Definition}
#{end}


SERVERDC

#{for a=TestRuns[n].PreConditionsCount}
@{title=${TestRuns[n].PreConditions[a].Key}|href=${BaseURL}/browse/${TestRuns[n].PreConditions[a].Key}}
${wiki:TestRuns[n].PreConditions[a].Conditions}
#{end}

Test Sets associated with a Test

SERVERDC CLOUD

#{for testSets}
    ${TestSets[n].Key}
    ${TestSets[n].Summary}
    ${TestSets[n].Description}
#{end}

Test Executions associated with a Test

SERVERDC CLOUD

#{for testExecutions}
    ${TestExecutions[n].Key}
    ${TestExecutions[n].Summary}
    ${TestExecutions[n].Description}
#{end}

Test Plans associated with a Test

SERVERDC CLOUD

#{for testPlans}
    ${TestPlans[n].Key}
    ${TestPlans[n].Summary}
    ${TestPlans[n].Description}
#{end}

Test Plan

The following examples assume the current context is a Test Plan.

Requirements indirectly linked to/covered by a given Test Plan (without doubles)

SERVERDC

/* Define a variable that will hold the keys of the requirements already listed */
${set(Req, “A”)}

/* iterate over all the Tests */
#{for tests}
/* Fetch all Requirements for a given Test */
#{for a=JQLIssuesCount|clause=key in testRequirements('${Tests[n].Key}')}

/* Check if Requirement key is in the variable */
#{if (%{'${Req}'.indexOf('${JQLIssues[a].Key}')==-1})}
/* Add Requirement key to the variable */
${set(Req,%{'${Req}'.concat('${JQLIssues[a].Key},')})}

/* List URL, Summary, Status and Requirement Status */
@{title=${JQLIssues[a].Key}|href=${BaseURL}/browse/${JQLIssues[a].Key}}
${JQLIssues[a].Summary}
${JQLIssues[a].Status}
${JQLIssues[a].Requirement Status}

/* Close if */
#{end}
#{end}
#
/* Close for testRequirements */
#{end}


CLOUD

${set(Req, ‘A’)} 
#{for tests} 
#{for k=Tests[n].LinksCount|filter=%{'${Tests[n].Links[k].LinkType}'.equals('tests')}}
#{if (%{'${Req}'.indexOf('${Tests[n].Links[k].Key}')==-1})}
${set(Req,%{'${Req}'.concat('${Tests[n].Links[k].Key}')})} 
@{title=${Tests[n].Links[k].Key}|href=${BaseURL}/browse/${Tests[n].Links[k].Key}}	
${Tests[n].Links[k].Summary} 	
${Tests[n].Links[k].Status} 	
${Tests[n].Links[k].Requirement Status} 
#{end}
#{end}
#{end}

Total Defects linked to Test Runs of related Test Executions

SERVERDCCLOUD

${set(Def, ‘A’)} 
#{for testExecutions}
#{for a=TestExecutions[n].TestRunsCount}
#{for d=TestExecutions[n].TestRuns[a].ExecutionDefectsCount}
#{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Key}')==-1})}
${set(Def,%{'${Def}'.concat('${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Key}')})} 
@{title=${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Key}|href=${BaseURL}/browse/${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Key}}	${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Summary}
#{end}
#{end}
#{for m=TestExecutions[n].TestRuns[a].TestStepsCount}
#{for dc=TestExecutions[n].TestRuns[a].TestSteps[m].DefectsCount}
#{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dc].Key}')==-1})}
${set(Def,%{'${Def}'.concat('${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dc].Key}')})} 
${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dc].Key}	
${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dc].Summary}
#{end}
#{end}
#{end}
#{for it=TestExecutions[n].TestRuns[a].IterationsCount}
#{for r=TestExecutions[n].TestRuns[a].Iterations[it].TestStepsCount}
#{for dc=TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].DefectsCount}
#{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}')==-1})}
${set(Def,%{'${Def}'.concat('${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}')})}
@{title=${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}|href=${BaseURL}/browse/${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}}	${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Summary}
#{end}
#{end}
#{end}
#{end}
#{end}
#{end}


Notes:

  • includes global defects
    • includes step level defects
    • includes step level defects from data-driven tests
    • counts only unique defects

Test Executions associated with a Test Plan

#{for j=TestExecutionsCount}
 ${TestExecutions[j].Key}
#{end}

#{for testExecutions}
 ${TestExecutions[n].Key}
#{end}

#{for j=JQLIssuesCount|clause= key in testPlanTestExecutions('${Key}')}
 ${JQLIssues[j].Key}
#{end}

Test Run

Requirements indirectly linked to/covered by a given Test Run

SERVERDC

${set(Req, "")}
#{for a=JQLIssuesCount|clause=key in testRequirements('${TestRuns[n]}')}
#{if (%{"${Req}".indexOf("${TestRuns[n].Key},")==-1})}
${set(Req,%{"${Req}".concat(”${JQLIssues[a].Key},")})}
#{end}
#{end}
%{'${Req}'.replace(/,\s*$/, '')}"


CLOUD

${set(Req,'')}
#{for k=TestRuns[n].LinksCount|filter=%{'${TestRuns[n].Links[k].LinkType}'.equals('tests')}}
#{if (%{'${Req}'.indexOf('${TestRuns[n].Links[k].Key}')==-1})} 
${set(Req,%{'${Req}'.concat('${TestRuns[n].Links[k].Key},')})} 
#{end} 
#{end}
%{'${Req}'.replace(/,\s*$/, '')}"

Total Defects linked to a given Test Run

See the example below for "Total Defects Count linked to a given Test Run" and use the defects variable at the end instead.


Notes:

  • includes global defects
    • includes step level defects
    • includes step level defects from data-driven tests
    • considers only unique defects

Total Defects Count linked to a given Test Run

CLOUD

${set(defects, "")}
#{if (%{!${TestRuns[n].IsDataDriven}})}
${set(totalDefects,%{${TestRuns[n].ExecutionDefectsCount} + ${TestRuns[n].TestStepsDefectsCount} })}
#{for e=TestRuns[n].ExecutionDefectsCount}
${set(defects, %{'${defects}'.concat('${TestRuns[n].ExecutionDefects[e].Key},')})} 
#{end}
#{for s=TestRuns[n].TestStepsCount}
#{for d=TestRuns[n].TestSteps[s].DefectsCount}
#{if (%{'${defects}'.indexOf('${TestRuns[n].TestSteps[s].Defects[d].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${TestRuns[n].TestSteps[s].Defects[d].Key},')})} 
${set(totalDefects,%{${totalDefects}+1})}
#{end}
#{end}
#{end}
#{end}
#{if (%{${TestRuns[n].IsDataDriven}})}
${set(totalDefects,%{${TestRuns[n].ExecutionDefectsCount}})}
#{for m=TestRuns[n].IterationsCount}
#{for e=TestRuns[n].ExecutionDefectsCount}
#{if (%{'${defects}'.indexOf('${TestRuns[n].ExecutionDefects[e].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${TestRuns[n].ExecutionDefects[e].Key},')})} 
#{end}
#{end}
#{for s=TestRuns[n].Iterations[m].TestStepsCount}
#{for d=TestRuns[n].Iterations[m].TestSteps[s].DefectsCount}
#{if (%{'${defects}'.indexOf('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} 
${set(totalDefects,%{${totalDefects}+1})}
#{end}
#{end}
#{end}
#{end}
#{end}
${set(defects, %{'${defects}'.replace(/,\s*$/, '')})}
${totalDefects}


SERVERDC  

${set(defects, "")}
#{if (%{!${Tests[j].TestRuns[n].IsDataDriven}})}
${set(totalDefects,%{${Tests[j].TestRuns[n].ExecutionDefectsCount} + ${Tests[j].TestRuns[n].TestStepsDefectsCount} })}
#{for e=Tests[j].TestRuns[n].ExecutionDefectsCount}
${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},')})} 
#{end}
#{for s=Tests[j].TestRuns[n].TestStepsCount}
#{for d=Tests[j].TestRuns[n].TestSteps[s].DefectsCount}
#{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].TestSteps[s].Defects[d].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].TestSteps[s].Defects[d].Key},')})} 
${set(totalDefects,%{${totalDefects}+1})}
#{end}
#{end}
#{end}
#{end}
#{if (%{${Tests[j].TestRuns[n].IsDataDriven}})}
${set(totalDefects,%{${Tests[j].TestRuns[n].ExecutionDefectsCount}})}
#{for m=Tests[j].TestRuns[n].IterationsCount}
#{for e=Tests[j].TestRuns[n].ExecutionDefectsCount}
#{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},')})} 
#{end}
#{end}
#{for s=Tests[j].TestRuns[n].Iterations[m].TestStepsCount}
#{for d=Tests[j].TestRuns[n].Iterations[m].TestSteps[s].DefectsCount}
#{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})}
${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} 
${set(totalDefects,%{${totalDefects}+1})}
#{end}
#{end}
#{end}
#{end}
#{end}
${set(defects, %{'${defects}'.replace(/,\s*$/, '')})}
${totalDefects}

Notes:

  • includes global defects
    • includes step level defects
    • includes step level defects from data-driven tests
    • counts only unique defects


Total test runs elapsed time (calculate the time difference between 2 dates and convert milliseconds to hh:mm:ss format)

SERVERDCCLOUD

${set(dateDifTotal,0)}
#{for testruns}
${set(CreatedSpt,%{"${TestRuns[n].Started On}".split("[")[0]})}
${set(ResolvedSpt,%{"${TestRuns[n].Finished On}".split("[")[0]})}
${set(cr,%{new Date("${CreatedSpt}").getTime()})}
${set(res,%{new Date("${ResolvedSpt}").getTime()})}
${set(dateDif,%{${res} - ${cr}})}
${set(dateStr,%{new Date(${dateDif}).toISOString().substr(11, 8)})}
Begin: ${CreatedSpt}
End: ${ResolvedSpt}
Diference: ${dateStr}
${set(dateDifTotal,%{${dateDifTotal} + ${dateDif}})}
#{end}
${set(dateStrTotal,%{new Date(${dateDifTotal}).toISOString().substr(11, 8)})}
Total Elapsed Time: ${dateStrTotal}

Notes:

  • it will output "00:00:00" when there are no tests associated with the execution (or your executions are really fast) and " " when there are tests in progress (i.e. "Executing" or "To Do" status).