Skip to content

Commit fea47db

Browse files
author
Davert
committed
substeps implemented
1 parent 7b0680b commit fea47db

34 files changed

Lines changed: 1117 additions & 191 deletions

‎src/Codeception/Lib/Friend.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public function does($closure)
4040
$module->_loadSession($this->data[$name]);
4141
};
4242

43-
$this->actor->comment(strtoupper("<info>{$this->name} does</info>:"));
43+
$this->actor->comment(strtoupper("<info>{$this->name} does --- </info>"));
4444
$ret = $closure($this->actor);
45-
$this->actor->comment(strtoupper("<info>{$this->name} finished</info>"));
45+
$this->actor->comment(strtoupper("<info>--- {$this->name} finished</info>"));
4646

4747
foreach ($this->multiSessionModules as $module) {
4848
$name = $module->_getName();

‎src/Codeception/PHPUnit/ResultPrinter/HTML.php‎

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace Codeception\PHPUnit\ResultPrinter;
33

4+
use Codeception\Step;
5+
46
class HTML extends \Codeception\PHPUnit\ResultPrinter
57
{
68
/**
@@ -66,38 +68,39 @@ protected function startClass($name)
6668
protected function onTest($name, $success = true, array $steps = [], $time = 0)
6769
{
6870
$this->timeTaken += $time;
69-
if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
70-
$scenarioStatus = 'scenarioFailed';
71-
} else {
72-
if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED) {
73-
$scenarioStatus = 'scenarioSkipped';
74-
} else {
75-
if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) {
76-
$scenarioStatus = 'scenarioIncomplete';
77-
} else {
78-
if ($this->testStatus == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR) {
79-
$scenarioStatus = 'scenarioFailed';
80-
} else {
81-
$scenarioStatus = 'scenarioSuccess';
82-
}
83-
}
84-
}
71+
72+
switch ($this->testStatus) {
73+
case \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE: $scenarioStatus = 'scenarioFailed'; break;
74+
case \PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED: $scenarioStatus = 'scenarioSkipped'; break;
75+
case \PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE: $scenarioStatus = 'scenarioIncomplete'; break;
76+
case \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR: $scenarioStatus = 'scenarioError'; break;
77+
default: $scenarioStatus = 'scenarioSuccess';
8578
}
8679

8780
$stepsBuffer = '';
81+
$metaStep = null;
8882

89-
foreach ($steps as $step) {
90-
$stepTemplate = new \Text_Template(
91-
$this->templatePath . 'step.html'
92-
);
83+
$subStepsBuffer = '';
9384

94-
$stepTemplate->setVar(
95-
[
96-
'action' => $step->getHtmlAction(),
97-
]
98-
);
85+
foreach ($steps as $step) {
86+
/** @var $step Step **/
87+
if ($step->getMetaStep()) {
88+
$subStepsBuffer .= $this->renderStep($step);
89+
$metaStep = $step->getMetaStep();
90+
continue;
91+
}
92+
if ($step->getMetaStep() != $metaStep) {
93+
$stepsBuffer .= $this->renderSubsteps($step, $subStepsBuffer);
94+
$subStepsBuffer = '';
95+
continue;
96+
}
97+
$metaStep = $step->getMetaStep();
98+
$stepsBuffer .= $this->renderStep($step);
99+
}
99100

100-
$stepsBuffer .= $stepTemplate->render();
101+
if ($subStepsBuffer) {
102+
$lastStep = end($steps);
103+
$stepsBuffer .= $this->renderSubsteps($lastStep, $subStepsBuffer);
101104
}
102105

103106
$scenarioTemplate = new \Text_Template(
@@ -107,7 +110,7 @@ protected function onTest($name, $success = true, array $steps = [], $time = 0)
107110
$scenarioTemplate->setVar(
108111
[
109112
'id' => ++$this->id,
110-
'name' => $name,
113+
'name' => ucfirst($name),
111114
'scenarioStatus' => $scenarioStatus,
112115
'steps' => $stepsBuffer,
113116
'time' => round($time, 2)
@@ -140,7 +143,7 @@ protected function endRun()
140143
$this->templatePath . 'scenario_header.html'
141144
);
142145

143-
$status = !$this->failed ? '<span style="color: green">OK</span>' : '<span style="color: red">FAILED</span>';
146+
$status = !$this->failed ? '<span style="color: green">OK</span>' : '<span style="color: #e74c3c">FAILED</span>';
144147

145148
$scenarioHeaderTemplate->setVar(
146149
[
@@ -170,5 +173,28 @@ protected function endRun()
170173
$this->write($scenariosTemplate->render());
171174
}
172175

176+
/**
177+
* @param $step
178+
* @return string
179+
*/
180+
protected function renderStep(Step $step)
181+
{
182+
$stepTemplate = new \Text_Template($this->templatePath . 'step.html');
183+
$stepTemplate->setVar(['action' => $step->getHtml()]);
184+
return $stepTemplate->render();
185+
}
186+
187+
/**
188+
* @param $step
189+
* @param $substepsBuffer
190+
* @return string
191+
*/
192+
protected function renderSubsteps(Step $step, $substepsBuffer)
193+
{
194+
$metaTemplate = new \Text_Template($this->templatePath . 'substeps.html');
195+
$metaTemplate->setVar(['metaStep' => $step->getMetaStep(), 'steps' => $substepsBuffer, 'id' => uniqid()]);
196+
return $metaTemplate->render();
197+
}
198+
173199

174200
}

‎src/Codeception/PHPUnit/ResultPrinter/template/scenario.html.dist‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<tr class="scenarioRow {scenarioStatus}">
22
<td>
3-
<p class="{scenarioStatus}" onclick="showHide('{id}', this)">[+] {name} ({time}s)</p>
3+
<p class="{scenarioStatus}" onclick="showHide('{id}', this)">[+] {name} <span style="color: #34495e; font-size: 70%;">{time}s</span></p>
44
</td>
55
</tr>
66
<tr class="scenarioRow {scenarioStatus}">

‎src/Codeception/PHPUnit/ResultPrinter/template/scenarios.html.dist‎

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
<title>Test results</title>
44
<meta charset='utf-8'>
55
<link href='http://fonts.googleapis.com/css?family=Varela+Round&v2' rel='stylesheet' type='text/css'>
6+
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
67

78
<style>
89
.layout {
910
margin: 0 auto;
10-
width: 960px;
11+
max-width: 1000px;
1112

1213
}
13-
body { font-family: arial, serif; margin: 0; padding: 0; background: #333; }
14-
h1,h2,h3 { font-family: arial, serif; color: white; }
14+
body { font-family: arial, serif; margin: 0; padding: 0; background: #ecf0f1; font-size: 20px; }
15+
h1,h2,h3 { font-family: arial, serif; color: #7f8c8d; }
1516
h1 { font-size: 2.5em; }
1617
h2 { font-size: 1.3em; }
1718
h3 { font-size: 1em; color: #84BBDD; margin: 0.5em 0; }
1819

19-
table { border: none; margin: 0; padding: 0; }
20+
table { border: none; margin: 0; padding: 0; font-size: 0.9em;}
2021
.scenarioStepsTable .stepName { padding: 5px; }
2122

2223
.scenarioStepsTable td {
23-
font-size: 80%;
2424
border: 1px solid #ccc;
2525
font-family: 'Varela Round', arial;
2626
-webkit-border-radius: 5px;
@@ -37,40 +37,32 @@
3737

3838
}
3939

40+
.scenarioStepsTable .nostyle {
41+
background: none;
42+
border: none;
43+
}
44+
4045
p {
4146
cursor: pointer;
42-
padding: 5px;
47+
}
4348

44-
-webkit-border-radius: 5px;
45-
-moz-border-radius: 5px;
46-
border-radius: 5px;
49+
.scenarioRow>td>p {
50+
padding: 5px;
51+
}
4752

48-
}
53+
.scenarioStepsTable.substeps td {
54+
background: #bdc3c7;
55+
}
4956

5057
.header { font-size: large; font-weight: bold; }
5158
p.scenarioSuccess {
52-
background: rgb(157,213,58); /* Old browsers */
53-
background: -moz-linear-gradient(top, rgba(157,213,58,1) 0%, rgba(161,213,79,1) 50%, rgba(124,188,10,1) 100%); /* FF3.6+ */
54-
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(157,213,58,1)), color-stop(50%,rgba(161,213,79,1)), color-stop(100%,rgba(124,188,10,1))); /* Chrome,Safari4+ */
55-
background: -webkit-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(124,188,10,1) 100%); /* Chrome10+,Safari5.1+ */
56-
background: -o-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(124,188,10,1) 100%); /* Opera11.10+ */
57-
background: -ms-linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(124,188,10,1) 100%); /* IE10+ */
58-
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a',GradientType=0 ); /* IE6-9 */
59-
background: linear-gradient(top, rgba(157,213,58,1) 0%,rgba(161,213,79,1) 50%,rgba(124,188,10,1) 100%); /* W3C */
60-
59+
background: rgb(157,213,58); /* Old browsers */
6160
}
6261

6362

6463
.scenario { color: black; }
65-
p.scenarioFailed { color: black;
66-
background: rgb(204,0,0); /* Old browsers */
67-
background: -moz-linear-gradient(top, rgba(204,0,0,1) 0%, rgba(119,0,0,1) 100%); /* FF3.6+ */
68-
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(204,0,0,1)), color-stop(100%,rgba(119,0,0,1))); /* Chrome,Safari4+ */
69-
background: -webkit-linear-gradient(top, rgba(204,0,0,1) 0%,rgba(119,0,0,1) 100%); /* Chrome10+,Safari5.1+ */
70-
background: -o-linear-gradient(top, rgba(204,0,0,1) 0%,rgba(119,0,0,1) 100%); /* Opera11.10+ */
71-
background: -ms-linear-gradient(top, rgba(204,0,0,1) 0%,rgba(119,0,0,1) 100%); /* IE10+ */
72-
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cc0000', endColorstr='#770000',GradientType=0 ); /* IE6-9 */
73-
background: linear-gradient(top, rgba(204,0,0,1) 0%,rgba(119,0,0,1) 100%); /* W3C */
64+
p.scenarioFailed, p.scenarioError { color: black;
65+
background: #e74c3c
7466
}
7567

7668

@@ -90,28 +82,29 @@
9082
padding: 20px;
9183
}
9284
ul#toolbar-filter {
93-
display: inline;
85+
display: block;
86+
position: fixed;
87+
top: 20px;
88+
left: 0px;
89+
padding: 0px;
9490
}
9591
ul#toolbar-filter li {
96-
display: inline;
97-
float: right;
92+
list-style: none;
93+
text-align: center;
9894
padding: 20px;
99-
width: 120px;
100-
color: black;
101-
background-color: #9DD53A;
102-
}
103-
ul#toolbar-filter li.disabled {
104-
background-color: gray;
95+
background-color: #3498db;
10596
}
106-
ul#toolbar-filter li:hover {
107-
background-color: white;
97+
ul#toolbar-filter li a, ul#toolbar-filter li a:hover, ul#toolbar-filter li a:visited {
98+
color: #34495e;
99+
text-decoration: none;
108100
}
109-
ul#toolbar-filter li.disabled:hover {
110-
background-color: #333;
101+
ul#toolbar-filter li.disabled {
102+
background-color: #bdc3c7;
111103
}
112104
</style>
113105

114106
<script type="text/javascript">
107+
var showAll = true;
115108
function showHide(nodeId, linkObj)
116109
{
117110
var subObj = document.getElementById('stepContainer' + nodeId);
@@ -136,49 +129,58 @@
136129
for(var z = 0; z < trs.length; z++) {
137130
trs[z].style.display = '';
138131
}
132+
showAll = true;
139133
}
140134

141-
function toogleScenarios(name, linkObj) {
142-
if (linkObj.className == '') {
143-
document.getElementById('toolbar-filter').children[0].className = 'disabled';
144-
linkObj.className = 'disabled';
145-
} else {
146-
var toolbar = document.getElementById('toolbar-filter');
147-
toolbar.children[0].className = '';
148-
linkObj.className = '';
149-
for (var i = 1; i < toolbar.children.length; i++) {
150-
if (toolbar.children[i].classList.contains('disabled')) {
151-
showAll = false;
152-
toolbar.children[0].className = 'disabled';
135+
function toggleScenarios(name, linkObj) {
136+
var links = document.getElementById('toolbar-filter').children;
137+
var rows = document.getElementsByClassName('scenarioRow');
138+
if (showAll) {
139+
for (var i = 0; i < links.length; i++) {
140+
links[i].className = 'disabled';
141+
}
142+
143+
for (var i = 0; i < rows.length; i++) {
144+
rows[i].style.display = 'none';
153145
}
154-
}
146+
155147
}
148+
showAll = false;
156149

157-
var rows = document.getElementsByClassName('scenarioRow');
158-
for (var i = 0; i < rows.length; i++) {
159-
var row = rows[i];
160-
if (row.classList.contains(name)) {
161-
if (row.style.display == '') {
162-
row.style.display = 'none';
163-
} else {
164-
row.style.display = '';
150+
if (linkObj.className == '') {
151+
linkObj.className = 'disabled';
152+
for (var i = 0; i < rows.length; i++) {
153+
if (rows[i].classList.contains(name)) {
154+
rows[i].style.display = 'none';
155+
}
156+
}
157+
return;
158+
}
159+
if (linkObj.className == 'disabled') {
160+
linkObj.className = '';
161+
for (var i = 0; i < rows.length; i++) {
162+
if (rows[i].classList.contains(name)) {
163+
rows[i].style.display = 'table-row';
164+
}
165165
}
166-
}
166+
return;
167167
}
168+
168169
}
169170
</script>
170171
</head>
171172

172173
<body>
174+
<ul id="toolbar-filter">
175+
<li> <a href="#" title="Show all" onClick="showAllScenarios()"><i class="fa fa-plus-square-o"></i></a></li>
176+
<li> <a href="#" title="Successful" onClick="toggleScenarios('scenarioSuccess', this.parentElement)"><i class="fa fa-check"></i> {successfulScenarios}</a></li>
177+
<li> <a href="#" title="Failed" onClick="toggleScenarios('scenarioFailed', this.parentElement)"><i class="fa fa-exclamation-triangle"></i> {failedScenarios}</a></li>
178+
<li> <a href="#" title="Skipped" onClick="toggleScenarios('scenarioSkipped', this.parentElement)"><i class="fa fa-square-o"></i> {skippedScenarios}</a></li>
179+
<li> <a href="#" title="Incomplete" onClick="toggleScenarios('scenarioIncomplete', this.parentElement)"><i class="fa fa-info"></i> {incompleteScenarios}</a></li>
180+
</ul>
173181
<div class="layout">
174182
{header}
175-
<ul id="toolbar-filter">
176-
<li onClick="showAllScenarios()">Show all</li>
177-
<li onClick="toogleScenarios('scenarioSuccess', this)">Success ({successfulScenarios})</li>
178-
<li onClick="toogleScenarios('scenarioFailed', this)">Failed ({failedScenarios})</li>
179-
<li onClick="toogleScenarios('scenarioSkipped', this)">Skipped ({skippedScenarios})</li>
180-
<li onClick="toogleScenarios('scenarioIncomplete', this)">Incomplete ({incompleteScenarios})</li>
181-
</ul>
183+
182184
<table border="0" style="width: 100%;">
183185
{scenarios}
184186
<tr>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<tr>
2-
<td class="stepName">I {action}</td>
2+
<td class="stepName">{action}</td>
33
</tr>
44

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<tr>
2+
<td class="stepName" ><p onclick="showHide('{id}', this)">[+] {metaStep}</p>
3+
4+
</td>
5+
</tr>
6+
<tr>
7+
<td class="nostyle">
8+
<table border="0" width="100%" class="substeps scenarioStepsTable" id="stepContainer{id}">
9+
{steps}
10+
</table>
11+
</td>
12+
</tr>

‎src/Codeception/Scenario.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public function getHtml()
129129
foreach ($this->getSteps() as $step) {
130130
/** @var Step $step */
131131
if ($step->getName() !== 'Comment') {
132-
$text .= 'I ' . $step->getHtmlAction() . '<br/>';
132+
$text .= 'I ' . $step->getHtml() . '<br/>';
133133
} else {
134134
$text .= trim($step->getHumanizedArguments(), '"') . '<br/>';
135135
}

0 commit comments

Comments
 (0)