Skip to content

Commit a790459

Browse files
committed
Add wizard tests to cover navigation, and expected indicator and left-hand navigation behavior
1 parent cf3eec0 commit a790459

File tree

9 files changed

+367
-0
lines changed

9 files changed

+367
-0
lines changed

test/karma.conf.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = function(config) {
2626
'src/**/*.js',
2727
'src/**/*.html',
2828
'test/utils/*.js',
29+
'test/wizard/script.js',
2930
'test/**/*.spec.js',
3031
'test/**/*.html'
3132
],

test/wizard/deployment.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div ng-controller="DeploymentController">
2+
<div pf-wizard-substep step-title="Deploy" step-id="review-progress" step-priority="1" next-enabled="true" prev-enabled="false" ok-to-nav-away="true" wz-disabled="false" on-show="onShow">
3+
<div class="wizard-pf-contents" ng-controller="DeploymentController">
4+
<div class="wizard-pf-process blank-slate-pf" ng-if="!deploymentComplete">
5+
<div class="spinner spinner-lg blank-slate-pf-icon"></div>
6+
<h5 class="blank-slate-pf-main-action" id="example_source_deployment-in-progress">Deployment in progress</h5>
7+
<p class="blank-slate-pf-secondary-action">Lorem ipsum dolor sit amet, porta at suspendisse ac, ut wisi vivamus, lorem sociosqu eget nunc amet. </p>
8+
</div>
9+
<div class="wizard-pf-complete blank-slate-pf" ng-if="deploymentComplete">
10+
<div class="wizard-pf-success-icon"><span class="glyphicon glyphicon-ok-circle"></span></div>
11+
<h5 class="blank-slate-pf-main-action" id="example_source_deployment-was-successful">Deployment was successful</h5>
12+
<p class="blank-slate-pf-secondary-action">Lorem ipsum dolor sit amet, porta at suspendisse ac, ut wisi vivamus, lorem sociosqu eget nunc amet. </p>
13+
<button type="button" class="btn btn-lg btn-primary">View Deployment</button>
14+
</div>
15+
</div>
16+
</div>
17+
</div>

test/wizard/detail-page.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div ng-controller="DetailsGeneralController">
2+
<div pf-wizard-substep step-title="General" next-enabled="detailsGeneralComplete" step-id="details-general" step-priority="0" on-show="onShow" review-template="{{reviewTemplate}}" show-review-details="true">
3+
<form class="form-horizontal">
4+
<div pf-form-group pf-label="Name" required>
5+
<input id="new-name" name="name" ng-model="data.name" type="text" ng-change="updateName()" required/>
6+
</div>
7+
<div pf-form-group pf-label="Description">
8+
<input id="new-description" name="description" ng-model="data.description" type="text" />
9+
</div>
10+
</form>
11+
</div>
12+
</div>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div ng-controller="DetailsReviewController">
2+
<form class="form">
3+
<div class="wizard-pf-review-item">
4+
<span class="wizard-pf-review-item-label">Lorem:</span>
5+
<span class="wizard-pf-review-item-value">{{data.lorem}}</span>
6+
</div>
7+
<div class="wizard-pf-review-item">
8+
<span class="wizard-pf-review-item-label">Ipsum:</span>
9+
<span class="wizard-pf-review-item-value">{{data.ipsum}}</span>
10+
</div>
11+
</form>
12+
</div>

test/wizard/review-template.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<div ng-controller="DetailsReviewController">
2+
<form class="form">
3+
<div class="wizard-pf-review-item">
4+
<span class="wizard-pf-review-item-label">Name:</span>
5+
<span class="wizard-pf-review-item-value">{{data.name}}</span>
6+
</div>
7+
<div class="wizard-pf-review-item">
8+
<span class="wizard-pf-review-item-label">Description:</span>
9+
<span class="wizard-pf-review-item-value">{{data.description}}</span>
10+
</div>
11+
</form>
12+
</div>

test/wizard/script.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
angular.module('patternfly.wizard').controller('DetailsGeneralController', ['$rootScope', '$scope',
2+
function ($rootScope, $scope) {
3+
'use strict';
4+
5+
$scope.reviewTemplate = "test/wizard/review-template.html";
6+
7+
$scope.onShow = function() {
8+
$scope.detailsGeneralComplete = false;
9+
};
10+
11+
$scope.updateName = function() {
12+
$scope.detailsGeneralComplete = angular.isDefined($scope.data.name) && $scope.data.name.length > 0;
13+
};
14+
}
15+
]);
16+
17+
angular.module('patternfly.wizard').controller('DetailsReviewController', ['$rootScope', '$scope',
18+
function ($rootScope, $scope) {
19+
'use strict';
20+
21+
// Find the data!
22+
var next = $scope;
23+
while (angular.isUndefined($scope.data)) {
24+
next = next.$parent;
25+
if (angular.isUndefined(next)) {
26+
$scope.data = {};
27+
} else {
28+
$scope.data = next.wizardData;
29+
}
30+
}
31+
}
32+
]);
33+
34+
angular.module('patternfly.wizard').controller('SummaryController', ['$rootScope', '$scope', '$timeout',
35+
function ($rootScope, $scope, $timeout) {
36+
'use strict';
37+
$scope.pageShown = false;
38+
39+
$scope.onShow = function () {
40+
$scope.pageShown = true;
41+
$timeout(function () {
42+
$scope.pageShown = false; // done so the next time the page is shown it updates
43+
});
44+
}
45+
}
46+
]);
47+
48+
angular.module('patternfly.wizard').controller('DeploymentController', ['$rootScope', '$scope', '$timeout',
49+
function ($rootScope, $scope, $timeout) {
50+
'use strict';
51+
52+
$scope.onShow = function() {
53+
$scope.deploymentComplete = false;
54+
$timeout(function() {
55+
$scope.deploymentComplete = true;
56+
}, 2500);
57+
};
58+
}
59+
]);

test/wizard/summary.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div ng-controller="SummaryController">
2+
<div pf-wizard-substep step-title="Summary" step-id="review-summary" step-priority="0" next-enabled="true" prev-enabled="true" ok-to-nav-away="true" wz-disabled="false" on-show="onShow">
3+
<div pf-wizard-review-page shown="pageShown" wizard-data="data"></div>
4+
</div>
5+
</div>

test/wizard/wizard-container.html

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<div pf-wizard title="Wizard Title"
2+
wizard-ready="deployReady"
3+
on-finish="finishedWizard()"
4+
on-cancel="cancelDeploymentWizard()"
5+
next-title="nextButtonTitle"
6+
next-callback="nextCallback"
7+
back-callback="backCallback"
8+
current-step="currentStep"
9+
hide-indicators="hideIndicators"
10+
wizard-done="deployComplete || deployInProgress"
11+
loading-secondary-information="secondaryLoadInformation">
12+
<div pf-wizard-step step-title="First Step" substeps="true" step-id="details" step-priority="0" show-review="true" show-review-details="true">
13+
<div ng-include="'test/wizard/detail-page.html'">
14+
</div>
15+
<div pf-wizard-substep step-title="Details - Extra" next-enabled="true" step-id="details-extra" step-priority="1" show-review="true" show-review-details="true" review-template="test/wizard/review-second-template.html">
16+
<form class="form-horizontal">
17+
<div pf-form-group pf-label="Lorem" required>
18+
<input id="new-lorem" name="lorem" ng-model="data.lorem" type="text" required/>
19+
</div>
20+
<div pf-form-group pf-label="Ipsum">
21+
<input id="new-ipsum" name="ipsum" ng-model="data.ipsum" type="text" />
22+
</div>
23+
</form>
24+
</div>
25+
</div>
26+
<div pf-wizard-step step-title="Second Step" substeps="false" step-id="configuration" step-priority="1" show-review="true" review-template="test/wizard/review-second-template.html" >
27+
<form class="form-horizontal">
28+
<div pf-form-group pf-label="Lorem">
29+
<input id="new-lorem" name="lorem" ng-model="data.lorem" type="text"/>
30+
</div>
31+
<div pf-form-group pf-label="Ipsum">
32+
<input id="new-ipsum" name="ipsum" ng-model="data.ipsum" type="text" />
33+
</div>
34+
</form>
35+
</div>
36+
<div pf-wizard-step step-title="Review" substeps="true" step-id="review" step-priority="2">
37+
<div ng-include="'test/wizard/summary.html'"></div>
38+
<div ng-include="'test/wizard/deployment.html'"></div>
39+
</div>
40+
</div>

test/wizard/wizard.spec.js

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
describe('Directive: pfWizard', function () {
2+
var $scope,
3+
$rootScope,
4+
$compile,
5+
$httpBackend,
6+
$templateCache,
7+
$timeout,
8+
element;
9+
10+
// load the controller's module
11+
beforeEach(module(
12+
'patternfly.wizard',
13+
'wizard/wizard-substep.html',
14+
'wizard/wizard-step.html',
15+
'wizard/wizard-review-page.html',
16+
'wizard/wizard.html',
17+
'form/form-group/form-group.html',
18+
'test/wizard/deployment.html',
19+
'test/wizard/detail-page.html',
20+
'test/wizard/review-second-template.html',
21+
'test/wizard/review-template.html',
22+
'test/wizard/summary.html',
23+
'test/wizard/wizard-container.html'
24+
));
25+
26+
beforeEach(inject(function (_$compile_, _$rootScope_, _$httpBackend_, _$templateCache_, _$timeout_) {
27+
$compile = _$compile_;
28+
$scope = _$rootScope_;
29+
$rootScope = _$rootScope_;
30+
$httpBackend = _$httpBackend_;
31+
$templateCache = _$templateCache_;
32+
$timeout = _$timeout_;
33+
}));
34+
35+
var compileHtml = function (markup, scope) {
36+
var element = angular.element(markup);
37+
$compile(element)(scope);
38+
scope.$digest();
39+
return element;
40+
};
41+
42+
var setupWizardScope = function () {
43+
var initializeWizard = function () {
44+
$scope.data = {
45+
name: '',
46+
description: '',
47+
lorem: 'default setting',
48+
ipsum: ''
49+
};
50+
$scope.hideIndicators = false;
51+
52+
$scope.secondaryLoadInformation = 'ipsum dolor sit amet, porta at suspendisse ac, ut wisi vivamus, lorem sociosqu eget nunc amet.';
53+
$timeout(function () {
54+
$scope.deployReady = true;
55+
});
56+
$scope.nextButtonTitle = "Next >";
57+
};
58+
59+
var startDeploy = function () {
60+
$timeout(function() { }, 2000);
61+
$scope.deployInProgress = true;
62+
};
63+
64+
$scope.data = {};
65+
66+
$scope.nextCallback = function () {
67+
return true;
68+
};
69+
70+
$scope.backCallback = function () {
71+
return true;
72+
};
73+
74+
$scope.$on("wizard:stepChanged", function (e, parameters) {
75+
if (parameters.step.stepId === 'review-summary') {
76+
$scope.nextButtonTitle = "Deploy";
77+
} else if (parameters.step.stepId === 'review-progress') {
78+
$scope.nextButtonTitle = "Close";
79+
} else {
80+
$scope.nextButtonTitle = "Next >";
81+
}
82+
});
83+
84+
$scope.cancelDeploymentWizard = function () {
85+
$rootScope.$emit('wizard.done', 'cancel');
86+
};
87+
88+
$scope.finishedWizard = function () {
89+
$rootScope.$emit('wizard.done', 'done');
90+
return true;
91+
};
92+
initializeWizard();
93+
};
94+
95+
beforeEach(function () {
96+
setupWizardScope();
97+
var modalHtml = $templateCache.get('test/wizard/wizard-container.html');
98+
element = compileHtml(modalHtml, $scope);
99+
$scope.$digest();
100+
101+
// there are two dependent timeouts in the wizard that need to be flushed
102+
$timeout.flush();
103+
$timeout.flush();
104+
});
105+
106+
it('should dispatch the cancel event on the close button click', function () {
107+
var closeButton = element.find('.close');
108+
$rootScope.$on('wizard.done', function (event, data) {
109+
expect(data).toBe('cancel');
110+
});
111+
spyOn($rootScope, '$emit');
112+
eventFire(closeButton[0], 'click');
113+
$scope.$digest();
114+
115+
expect($rootScope.$emit).toHaveBeenCalled();
116+
});
117+
118+
it('should have three step indicators in the header', function () {
119+
var stepsIndicator = element.find('.wizard-pf-steps .wizard-pf-step');
120+
expect(stepsIndicator.length).toBe(3);
121+
});
122+
123+
it('should have two sections in the left-hand pane', function () {
124+
var stepsIndicator = element.find('.wizard-pf-sidebar .list-group-item');
125+
var hiddenStepsIndicator = element.find('section.ng-hide .wizard-pf-sidebar .list-group-item');
126+
127+
//find all hidden steps and remove them from total step count to make sure correct number are visible
128+
expect(stepsIndicator.length - hiddenStepsIndicator.length).toBe(2);
129+
});
130+
131+
it('should have disabled the next button', function () {
132+
var checkDisabled = element.find('.wizard-pf-next').attr('disabled');
133+
expect(checkDisabled).toBe('disabled');
134+
});
135+
136+
it('should have enabled the next button after input and allowed navigation', function () {
137+
var nextButton = element.find('.wizard-pf-next');
138+
var nameBox = element.find('#new-name');
139+
nameBox.val('test').triggerHandler('input');
140+
eventFire(nextButton[0], 'click');
141+
var stepIndicator = element.find('.wizard-pf-sidebar .list-group-item.active .wizard-pf-substep-number');
142+
expect(stepIndicator.text()).toBe('1B.');
143+
});
144+
145+
it('should have allowed moving back to first page after input and allowed navigation', function () {
146+
var nextButton = element.find('.wizard-pf-next');
147+
var nameBox = element.find('#new-name');
148+
nameBox.val('test').triggerHandler('input');
149+
eventFire(nextButton[0], 'click');
150+
var stepIndicator = element.find('.wizard-pf-sidebar .list-group-item.active .wizard-pf-substep-number');
151+
expect(stepIndicator.text()).toBe('1B.');
152+
153+
var backButton = element.find('#backButton');
154+
eventFire(backButton[0], 'click');
155+
var stepIndicator = element.find('.wizard-pf-sidebar .list-group-item.active .wizard-pf-substep-number');
156+
expect(stepIndicator.text()).toBe('1A.');
157+
});
158+
159+
it('should have allowed navigation to review page', function () {
160+
var nextButton = element.find('.wizard-pf-next');
161+
var nameBox = element.find('#new-name');
162+
nameBox.val('test').triggerHandler('input');
163+
$scope.$digest();
164+
165+
$scope.currentStep = 'Review';
166+
$scope.$digest();
167+
$timeout.flush();
168+
$timeout.flush();
169+
170+
var stepIndicator = element.find('section.current .wizard-pf-sidebar .list-group-item.active .wizard-pf-substep-number');
171+
expect(stepIndicator.text()).toBe('3A.');
172+
});
173+
174+
it('should hide indicators if the property is set', function () {
175+
var modalHtml = $templateCache.get('test/wizard/wizard-container.html');
176+
element = compileHtml(modalHtml, $scope);
177+
$scope.hideIndicators = true;
178+
$scope.$digest();
179+
var indicators = element.find('.wizard-pf-steps');
180+
expect(indicators.children().length).toBe(0);
181+
182+
// make sure indicators can be turned back on
183+
$scope.hideIndicators = false;
184+
$scope.$digest();
185+
var indicators = element.find('.wizard-pf-steps');
186+
expect(indicators.children().length).toBe(1);
187+
});
188+
189+
it('clicking indicators should navigate wizard', function () {
190+
var indicator = element.find('.wizard-pf-steps .wizard-pf-step a');
191+
var nameBox = element.find('#new-name');
192+
nameBox.val('test').triggerHandler('input');
193+
194+
eventFire(indicator[1], 'click');
195+
$scope.$digest();
196+
197+
var selectedSectionTitle = element.find('.wizard-pf-row section.current').attr("step-title");
198+
expect(selectedSectionTitle).toBe('Second Step');
199+
});
200+
201+
it('clicking indicators should not navigate wizard if prevented from doing so', function () {
202+
var indicator = element.find('.wizard-pf-steps .wizard-pf-step a');
203+
eventFire(indicator[1], 'click');
204+
$scope.$digest();
205+
206+
var selectedSectionTitle = element.find('.wizard-pf-row section.current').attr("step-title");
207+
expect(selectedSectionTitle).not.toBe('Second Step');
208+
});
209+
});

0 commit comments

Comments
 (0)