Skip to content

Commit 3415f78

Browse files
Refactored and fixed bug where mutations were not being applied correctly on Dom additions. Also simplified dummy app.
1 parent 4682151 commit 3415f78

File tree

11 files changed

+58
-62
lines changed

11 files changed

+58
-62
lines changed

app/components/test-recorder.js

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@ export default Ember.Component.extend({
1212
// want this test recorder to sit outside the ember app and not be intrusive
1313
pendingGeneratedDomChangedScript: "",
1414

15-
initialObservedTarget: null,// cache this for performance
16-
1715
currentRouteName: "",
1816
routeHasChanged: false, //if true render a test condition for this
1917

2018
mutationObserversArr: [], // we disconnect these when the component is removed form the canvas (essential for testing)
2119

2220
willDestroyElement: function () {
23-
console.log("destroying");
21+
console.log("destroying " + this.get("mutationObserversArr").length + " mut observers ");
2422
this.get("mutationObserversArr").forEach(function (observer) {
2523
observer.disconnect();
2624
});
@@ -52,6 +50,7 @@ export default Ember.Component.extend({
5250
},
5351

5452
onCurrentRouteNameChange: Ember.observer('currentRouteName', function () {
53+
console.log(this.get("currentRouteName"));
5554
this.set("routeHasChanged", true);
5655
}),
5756

@@ -65,8 +64,6 @@ export default Ember.Component.extend({
6564
*/
6665
didInsertElement: function () {
6766

68-
this.set("initialObservedTarget", document.querySelector("body [id^=ember]")); // cache this for performance
69-
7067
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
7168

7269
//listen to clicks on ember items, apart from
@@ -76,6 +73,10 @@ export default Ember.Component.extend({
7673
var indentation = ' ';//2 spaces
7774
var currentNestedLevel = 0; //tracks the nesting level for mutations
7875

76+
/**
77+
* This is a helper function extension of jquery to give us a dynamic path incase the user hasn't given an
78+
* interactive element an ID. We then use this path to repeat the user action in a test case.
79+
*/
7980
Ember.$.fn.extend({
8081
path: function () {
8182

@@ -164,7 +165,6 @@ export default Ember.Component.extend({
164165
*/
165166
function addObserverForTarget(target) {
166167

167-
168168
var observer = new MutationObserver(function (mutations) {
169169
mutations.forEach(function (mutation) {
170170

@@ -175,27 +175,17 @@ export default Ember.Component.extend({
175175
var addedNodesArray = Array.prototype.slice.call(mutation.addedNodes);
176176
var removedNodesArray = Array.prototype.slice.call(mutation.removedNodes);
177177

178-
//ignore non tagged markup like carriage returns //todo investigate why ember does this, potential reflow issue
179-
//ignore things with no id
180-
//ignore ember-view wrapper divs
181-
182178
// This array is used to add new mutation Observers from the newly added DOM
183-
var newMutationsFromAddedNodesArray = addedNodesArray.filter(function (node) {
184-
var classListArray = node.classList && Array.prototype.slice.call(node.classList);
185-
//var isEmberView = classListArray ? (classListArray.indexOf("ember-view") === -1) : false;
186-
var hasDoNotRecordClass = classListArray ? (classListArray.indexOf("doNotRecord") !== -1) : false;
187-
return node.nodeType !== 3 && !hasDoNotRecordClass;
188-
});
179+
var newMutationsFromAddedNodesArray = addedNodesArray.filter(filterDoNotRecordAndWhiteSpace);
189180

190-
//loop through the above and add observers
181+
//loop through the above and add observers, we need to do this dynamically
191182
newMutationsFromAddedNodesArray.forEach(function (node) {
192-
addInnerObserversForTarget(node, 2); //just drill down 2 levels more
183+
addObserverForTarget(node); //just drill down 2 levels more
193184
})
194185

195-
//this array is used to generate the source code, we ignore anything with no ID
196-
197-
addedNodesArray = addedNodesArray.filter(unwantedNodesFilter);
198-
removedNodesArray = removedNodesArray.filter(unwantedNodesFilter);
186+
//this array is used to generate the source code, we filter
187+
addedNodesArray = addedNodesArray.filter(filter_DoNotRecord_WhiteSpace_emberID_noID);
188+
removedNodesArray = removedNodesArray.filter(filter_DoNotRecord_WhiteSpace_emberID_noID);
199189

200190
if (!addedNodesArray.length && !removedNodesArray.length) {
201191
//no point continuing in this iteration if nothing of interest
@@ -226,6 +216,8 @@ export default Ember.Component.extend({
226216
//this is the only place where observe is called so we can track them here too to disconnect
227217
observer.observe(target, config);
228218
self.get("mutationObserversArr").push(observer);
219+
addInnerObserversForTarget(target, 0);//forms new observers recursively
220+
229221

230222
}
231223

@@ -250,18 +242,14 @@ export default Ember.Component.extend({
250242
}
251243
}
252244

253-
//only observe inside the ember app, get 1st ember div todo possibly move this outside if users wish to look outside ember app
254-
//var initialObservedTarget = document.querySelector('body [id^=ember]');
255-
addObserverForTarget(this.get("initialObservedTarget"));
245+
//todo possibly move this outside if users wish to look outside ember app
246+
var target = document.querySelector('body [id^=ember]');
247+
addObserverForTarget(target);//as this does't do the recursive listeners straight away we have to call this:
256248

257-
//this is still WIP, as things are behaving a bit weird..
258-
if (this.get("initialObservedTarget").children) {
259-
addInnerObserversForTarget(this.get("initialObservedTarget"), 0);//forms new observers recursively
260-
}
261249
}
262250
});
263251

264-
function unwantedNodesFilter(node) {
252+
function filter_DoNotRecord_WhiteSpace_emberID_noID(node) {
265253
var classListArray = node.classList && Array.prototype.slice.call(node.classList);
266254
//var isEmberView = classListArray ? (classListArray.indexOf("ember-view") === -1) : false;
267255
var hasDoNotRecordClass = classListArray ? (classListArray.indexOf("doNotRecord") !== -1) : false;
@@ -275,3 +263,10 @@ function unwantedNodesFilter(node) {
275263

276264
return node.nodeType !== 3 && node.id && !hasDoNotRecordClass && !hasEmberIdRegex.test(node.id);
277265
}
266+
267+
function filterDoNotRecordAndWhiteSpace(node) {
268+
var classListArray = node.classList && Array.prototype.slice.call(node.classList);
269+
//var isEmberView = classListArray ? (classListArray.indexOf("ember-view") === -1) : false;
270+
var hasDoNotRecordClass = classListArray ? (classListArray.indexOf("doNotRecord") !== -1) : false;
271+
return node.nodeType !== 3 && !hasDoNotRecordClass;
272+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ember-cli-test-recorder",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"description": "The default blueprint for ember-cli addons.",
55
"directories": {
66
"doc": "doc",

tests/acceptance/test-playback-test.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ module('Acceptance: TestPlayback', {
2525
test('Playback code', function (assert) {
2626
//assume that the user starts on index
2727
visit('/');
28-
click("div:eq(0)>header>button:eq(0)");
28+
click("div:eq(0)>header>button:eq(1)");
2929
andThen(function () {
30-
assert.equal(currentRouteName(), "login", "The page navigates to login on button click");
30+
assert.equal(currentRouteName(), "foo", "The page navigates to foo on button click");
31+
assert.equal(find("#register-input-1").length, 0, "register-input-1 removed AFTER user [INSERT REASON]");
3132
assert.equal(find("#login-foo-component-with-nested-components").length, 1, "login-foo-component-with-nested-components shown AFTER user [INSERT REASON]");
3233

3334
});
3435

36+
click("div:eq(0)>header>button:eq(0)");
37+
andThen(function () {
38+
assert.equal(currentRouteName(), "index", "The page navigates to index on button click");
39+
assert.equal(find("#login-foo-component-with-nested-components").length, 0, "login-foo-component-with-nested-components removed AFTER user [INSERT REASON]");
40+
assert.equal(find("#register-input-1").length, 1, "register-input-1 shown AFTER user [INSERT REASON]");
41+
42+
});
43+
44+
3545
});

tests/dummy/app/controllers/application.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import Ember from 'ember';
22

33
export default Ember.Controller.extend({
44
actions: {
5-
goToLoginView: function () {
6-
this.transitionToRoute("login");
5+
goToIndexRoute: function () {
6+
this.transitionToRoute("index");
77
},
8-
goToInputsView: function () {
9-
this.transitionToRoute("inputs");
8+
goToFooRoute: function () {
9+
this.transitionToRoute("foo");
1010
}
1111
}
1212
});

tests/dummy/app/router.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ var Router = Ember.Router.extend({
66
});
77

88
Router.map(function () {
9-
this.route('login');
10-
this.route('inputs');
9+
this.route('index', {'path': ''});
10+
this.route('foo');//we just have a route here so we can test for it on transition
1111
});
1212

1313
export default Router;
14+
15+
Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
<header>
2-
<h1>Buttons</h1>
3-
<button type="button" {{action 'goToLoginView'}}
2+
<h1>Basic Inputs</h1>
3+
<p>The purpose of this page is to check that different inputs can be automated in acceptance tests</p>
4+
<!--this has no id to check if test recorder prints out html path for selector-->
5+
<button type="button" {{action 'goToIndexRoute'}}
46
class=""
5-
>
6-
<span class=""></span>&nbsp;Log in
7+
>
8+
<span class=""></span>&nbsp;Go to Index Route
79
</button>
8-
<!--this has no id to check if test recorder prints out html path for selector-->
9-
<button type="button" {{action 'goToInputsView'}}
10+
<button type="button" {{action 'goToFooRoute'}}
1011
class=""
1112
>
12-
<span class=""></span>&nbsp;Inputs
13+
<span class=""></span>&nbsp;Go to Foo Route
1314
</button>
1415
</header>
15-
{{#toggle-component}}
16-
<p id="toggle-component-1-p">Toggled content 1 in Application.hbs</p>
17-
<p>Toggled content 1 in Application.hbs</p>
18-
{{/toggle-component}}
16+
17+
1918

2019
{{outlet}}
2120
{{test-recorder currentRouteName=currentRouteName class="doNotRecord"}}

tests/dummy/app/templates/components/toggle-component.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
{{#if showContent}}
33
{{yield}}
44
{{/if}}
5-
<button {{action 'toggle'}}>Toggle</button>
5+
<button id="foobtn" {{action 'toggle'}}>Toggle</button>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
{{input type="text" name="type" placeholder="type in here"}}
1010
{{view "select" content=names}}
1111
</form>
12+

tests/dummy/app/templates/register.hbs

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)