Extend the testcase widget to run tests
This commit is contained in:
parent
22ad43954e
commit
57e74a0ad5
|
@ -79,8 +79,52 @@ TestCaseWidget.prototype.render = function(parent,nextSibling) {
|
|||
this.setVariable("transclusion",$tw.utils.hashString(jsonPayload));
|
||||
// Generate a `payloadTiddlers` variable that contains the payload in JSON format
|
||||
this.setVariable("payloadTiddlers",jsonPayload);
|
||||
// Render the test rendering if required
|
||||
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) {
|
||||
var testcaseOutputContainer = $tw.fakeDocument.createElement("div");
|
||||
var testcaseOutputWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTestOutput,{
|
||||
document: $tw.fakeDocument,
|
||||
parseAsInline: false,
|
||||
parentWidget: this,
|
||||
variables: {
|
||||
currentTiddler: this.testcaseTestOutput
|
||||
}
|
||||
});
|
||||
testcaseOutputWidget.render(testcaseOutputContainer);
|
||||
}
|
||||
// Clear changes queue
|
||||
this.testcaseWiki.clearTiddlerEventQueue();
|
||||
// Run the actions if provided
|
||||
if(this.testcaseWiki.tiddlerExists(this.testcaseTestActions)) {
|
||||
testcaseOutputWidget.invokeActionString(this.testcaseWiki.getTiddlerText(this.testcaseTestActions));
|
||||
testcaseOutputWidget.refresh(this.testcaseWiki.changedTiddlers,testcaseOutputContainer);
|
||||
}
|
||||
// Set up the test result variables
|
||||
var testResult = "",
|
||||
outputHTML = "",
|
||||
expectedHTML = "";
|
||||
if(this.testcaseTestOutput && this.testcaseTestExpectedResult) {
|
||||
outputHTML = testcaseOutputContainer.children[0].innerHTML;
|
||||
expectedHTML = this.testcaseWiki.getTiddlerText(this.testcaseTestExpectedResult);
|
||||
if(outputHTML === expectedHTML) {
|
||||
testResult = "pass";
|
||||
} else {
|
||||
testResult = "fail";
|
||||
}
|
||||
this.setVariable("outputHTML",outputHTML);
|
||||
this.setVariable("expectedHTML",expectedHTML);
|
||||
this.setVariable("testResult",testResult);
|
||||
}
|
||||
// Don't display anything if testHideIfPass is "yes" and the tests have passed
|
||||
if(this.testcaseHideIfPass === "yes" && testResult === "pass") {
|
||||
return;
|
||||
}
|
||||
// Render the page root template of the subwiki
|
||||
var rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{document: this.document, parseAsInline: false, parentWidget: this});
|
||||
var rootWidget = this.testcaseWiki.makeTranscludeWidget(this.testcaseTemplate,{
|
||||
document: this.document,
|
||||
parseAsInline: false,
|
||||
parentWidget: this
|
||||
});
|
||||
rootWidget.render(domNode);
|
||||
// Trap changes in the wiki and refresh the rendering
|
||||
this.testcaseWiki.addEventListener("change",function(changes) {
|
||||
|
@ -93,6 +137,10 @@ Compute the internal state of the widget
|
|||
*/
|
||||
TestCaseWidget.prototype.execute = function() {
|
||||
this.testcaseTemplate = this.getAttribute("template","$:/core/ui/testcases/DefaultTemplate");
|
||||
this.testcaseTestOutput = this.getAttribute("testOutput");
|
||||
this.testcaseTestActions = this.getAttribute("testActions");
|
||||
this.testcaseTestExpectedResult = this.getAttribute("testExpectedResult");
|
||||
this.testcaseHideIfPass = this.getAttribute("testHideIfPass");
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -6,8 +6,27 @@ title: $:/core/ui/testcases/DefaultTemplate
|
|||
>
|
||||
<div class="tc-testcase-wrapper">
|
||||
<div class="tc-testcase-header">
|
||||
<h2><$transclude tiddler="Description" mode="inline"/></h2>
|
||||
<h2>
|
||||
<%if [<testResult>!match[]] %>
|
||||
<span class={{{ tc-testcase-result-icon [<testResult>!match[fail]then[tc-testcase-result-icon-pass]] [<testResult>match[fail]then[tc-testcase-result-icon-fail]] +[join[ ]] }}}>
|
||||
<%if [<testResult>!match[fail]] %>
|
||||
{{$:/core/images/done-button}}
|
||||
<%else%>
|
||||
{{$:/core/images/close-button}}
|
||||
<%endif%>
|
||||
</span>
|
||||
<%endif%>
|
||||
<$view tiddler="Description" mode="inline"/>
|
||||
</h2>
|
||||
</div>
|
||||
<%if [<testResult>match[fail]] %>
|
||||
<div class="tc-testcase-result-fail">
|
||||
<div>
|
||||
TEST FAILED
|
||||
</div>
|
||||
<$diff-text source=<<expectedHTML>> dest=<<outputHTML>>/>
|
||||
</div>
|
||||
<%endif%>
|
||||
<div class="tc-testcase-panes">
|
||||
<div class="tc-testcase-source">
|
||||
<$macrocall $name="tabs" tabsList="[all[tiddlers]sort[]] -[prefix<state>] -Description -ExpectedResult -Output Output +[putfirst[]] -[has[plugin-type]]" state=<<state>> default="Output" template="$:/core/ui/testcases/DefaultTemplate/Source"/>
|
||||
|
@ -15,7 +34,7 @@ title: $:/core/ui/testcases/DefaultTemplate
|
|||
<div class="tc-testcase-divider">
|
||||
</div>
|
||||
<div class="tc-testcase-output">
|
||||
<$transclude tiddler="Output"/>
|
||||
<$transclude $tiddler="Output" $mode="block"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
title: $:/core/ui/testcases/DefaultTemplate/Source
|
||||
|
||||
\whitespace trim
|
||||
\procedure body()
|
||||
<$list filter="[<currentTab>fields[]] -text +[limit[1]]" variable="ignore">
|
||||
<table class="tc-field-table">
|
||||
<tbody>
|
||||
|
@ -18,3 +19,6 @@ title: $:/core/ui/testcases/DefaultTemplate/Source
|
|||
</table>
|
||||
</$list>
|
||||
<$edit class="tc-edit-texteditor" tiddler=<<currentTab>>/>
|
||||
\end
|
||||
|
||||
<$transclude $variable="body" $mode="inline"/>
|
||||
|
|
|
@ -9,24 +9,46 @@ type: text/vnd.tiddlywiki
|
|||
|
||||
The testcase widget creates an independent subwiki loaded with the specified payload tiddlers and then renders a specified template from within the subwiki.The default template displays a split view with the source tiddlers on the left and the rendered tiddler titled `Output` on the right. It also displays the tiddler titled `Description` as the heading. This makes it possible to run independent tests that also serve as documentation examples.
|
||||
|
||||
The testcase widget can optionally also be used to run and verify test results within the subwiki.
|
||||
|
||||
The testcase widget creates a lightweight TiddlyWiki environment with the following important limitations:
|
||||
|
||||
* Output is rendered into a DIV, and so cannot be styled independently of the host wiki
|
||||
* Any changes to the wiki made interactively by the user are volatile, and are lost when the testcase widget is refreshed
|
||||
* Startup actions are not supported
|
||||
* Only plugins available in the host wiki can be included in the testcase
|
||||
|
||||
The [[Innerwiki Plugin]] offers the ability to embed a fully independent subwiki via an `<iframe>` element, but without the testing related features of the testcase widget.
|
||||
|
||||
! Content and Attributes
|
||||
|
||||
The content of the `<$testcase>` widget is not displayed but instead is scanned for <<.wlink DataWidget>> widgets that define the payload tiddlers to be included in the test case. The `$:/core` plugin is automatically included in the payload.
|
||||
The content of the `<$testcase>` widget is not displayed but instead is scanned for <<.wlink DataWidget>> widgets that define the payload tiddlers to be included in the testcase.
|
||||
|
||||
|!Attribute |!Description |
|
||||
|<<.attr template>> |Optional title of the template used to display the testcase (defaults to $:/core/ui/testcases/DefaultTemplate). Note that custom templates will need to be explicitly added to the payload |
|
||||
|<<.attr testOutput>> |Optional title of the tiddler whose output should be subject to testing (note that both <<.attr testOutput>> and <<.attr testExpectedResult>> must be provided in order for testing to occur) |
|
||||
|<<.attr testExpectedResult>> |Optional title of the tiddler whose content is the expected result of rendering the output tiddler (note that both <<.attr testOutput>> and <<.attr testExpectedResult>> must be provided in order for testing to occur) |
|
||||
|<<.attr testActions>> |Optional title of the tiddler containing actions that should be executed before the test occurs |
|
||||
|<<.attr testHideIfPass>> |If set to "yes", hides the testcase widget if the test passes |
|
||||
|
||||
! Payload Tiddlers
|
||||
|
||||
The payload tiddlers are the tiddler values that are loaded into the subwiki that is created to run the tests. They are created via <<.wlink DataWidget>> widgets within the body of the `<$testcase>` widget.
|
||||
The payload tiddlers are the tiddler values that are loaded into the subwiki that is created to run the tests. They are created via <<.wlink DataWidget>> widgets within the body of the `<$testcase>` widget. The `$:/core` plugin is automatically included in the payload.
|
||||
|
||||
! State Handling
|
||||
! Testcase Template Variables
|
||||
|
||||
The `<$testcase>` widget sets the variable `transclusion` to a hash that reflects the names and values of all the payload tiddlers. This makes it easier for test case templates to create unique state tiddler titles using the [[qualify Macro]] or QualifyWidget.
|
||||
The testcase widget makes the following variables available within the rendered template:
|
||||
|
||||
! Test Case Conventions
|
||||
|!Variable |!Description |
|
||||
|<<.var transclusion>> |A hash that reflects the names and values of all the payload tiddlers. This makes it easier for testcase templates to create unique state tiddler titles using the [[qualify Macro]] or QualifyWidget |
|
||||
|<<.var payloadTiddlers>> |JSON array of payload tiddler fields |
|
||||
|<<.var outputHTML>> |The actual output HTML if running tests |
|
||||
|<<.var expectedHTML>> |The expected output HTML if running tests |
|
||||
|<<.var testResult>> |The tests result if running tests (may be "pass" or "fail") |
|
||||
|
||||
The following conventions are used for test case tiddlers:
|
||||
! Testcase Conventions
|
||||
|
||||
The following conventions are used for testcase tiddlers:
|
||||
|
||||
* `Description` contains a brief description of the test (rendered in inline mode)
|
||||
* `Output` contains the tiddler text to be rendered. It can also reference other tiddlers
|
||||
|
@ -35,9 +57,7 @@ The following conventions are used for test case tiddlers:
|
|||
! Example
|
||||
|
||||
<$testcase>
|
||||
<$data $tiddler="$:/core/ui/testcases/DefaultTemplate"/>
|
||||
<$data $tiddler="$:/core/ui/testcases/DefaultTemplate/Source"/>
|
||||
<$data title="Description" text="Simple example of a test case"/>
|
||||
<$data title="Description" text="Simple example of a testcase"/>
|
||||
<$data title="Output" text="""<$testcase>
|
||||
<$data title="Description" text="How to calculate 2 plus 2"/>
|
||||
<$data title="Output" text="<$text text={{{ [[2]add[2]] }}}/>"/>
|
||||
|
|
|
@ -3250,6 +3250,40 @@ span.tc-translink > a:first-child {
|
|||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
.tc-testcase-divider {
|
||||
x-background-color: <<colour muted-foreground>>;
|
||||
}
|
||||
|
||||
.tc-testcase-result-icon {
|
||||
fill: #fff;
|
||||
padding: 0.25em;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
border-radius: 1em;
|
||||
vertical-align: bottom;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
.tc-testcase-result-icon-pass {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.tc-testcase-result-icon-fail {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.tc-testcase-result-icon svg {
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
}
|
||||
|
||||
.tc-testcase-result-fail {
|
||||
border: 1px solid <<colour foreground>>;
|
||||
background-color: <<colour background>>;
|
||||
margin: 1em;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.tc-testcase-header > h2,
|
||||
.tc-testcase-source > pre {
|
||||
margin: 0;
|
||||
|
@ -3260,7 +3294,6 @@ span.tc-translink > a:first-child {
|
|||
}
|
||||
|
||||
.tc-testcase-panes {
|
||||
background: <<colour background>>;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
|
@ -3274,10 +3307,23 @@ span.tc-translink > a:first-child {
|
|||
min-width: 250px;
|
||||
}
|
||||
|
||||
.tc-testcase-source .tc-tab-content {
|
||||
background: <<colour background>>;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tc-testcase-source .tc-field-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tc-testcase-source table.tc-field-table {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tc-tiddler-frame .tc-edit-texteditor {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tc-testcase-divider {
|
||||
flex: 0 0 2%;
|
||||
}
|
||||
|
@ -3287,6 +3333,7 @@ span.tc-translink > a:first-child {
|
|||
}
|
||||
|
||||
.tc-testcase-output {
|
||||
background: <<colour background>>;
|
||||
border-radius: 3px;
|
||||
border: 1px solid <<colour muted-foreground>>;
|
||||
flex: 1 0 49%;
|
||||
|
|
Loading…
Reference in New Issue