summaryrefslogtreecommitdiff
path: root/tests/frontend/specs/caret.js
blob: 9d9da46092e6ac51e7ecefde1fbb4cf252113706 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
describe("As the caret is moved is the UI properly updated?", function(){
  var padName;
  var numberOfRows = 50;

  it("creates a pad", function(done) {
    padName = helper.newPad(done);
    this.timeout(60000);
  });

  /* Tests to do
  * Keystroke up (38), down (40), left (37), right (39) with and without special keys IE control / shift
  * Page up (33) / down (34) with and without special keys
  * Page up on the first line shouldn't move the viewport
  * Down down on the last line shouldn't move the viewport
  * Down arrow on any other line except the last lines shouldn't move the viewport
  * Do all of the above tests after a copy/paste event
  */

  /* Challenges
  * How do we keep the authors focus on a line if the lines above the author are modified?  We should only redraw the user to a location if they are typing and make sure shift and arrow keys aren't redrawing the UI else highlight - copy/paste would get broken
  * How can we simulate an edit event in the test framework?
  */

  // THIS DOESNT WORK AS IT DOESNT MOVE THE CURSOR!
  it("down arrow", function(done){
    var inner$ = helper.padInner$;
    keyEvent(inner$, 40, false, false); // arrow up
    done();
  });

  it("Creates N lines", function(done){
    var inner$ = helper.padInner$;
    var chrome$ = helper.padChrome$;
    var $newFirstTextElement = inner$("div").first();

    prepareDocument(numberOfRows, $newFirstTextElement); // N lines into the first div as a target
    helper.waitFor(function(){ // Wait for the DOM to register the new items
      return inner$("div").first().text().length == 6;
    }).done(function(){ // Once the DOM has registered the items
      done();
    });
  });

  it("Moves caret up a line", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.y;
    var newCaretPos;
    keyEvent(inner$, 38, false, false); // arrow up

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.y;
      return (newCaretPos < originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.lessThan(originalPos);
      done();
    });
  });

  it("Moves caret down a line", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.y;
    var newCaretPos;
    keyEvent(inner$, 40, false, false); // arrow down

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.y;
      return (newCaretPos > originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.moreThan(originalPos);
      done();
    });
  });

  it("Moves caret to top of doc", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.y;
    var newCaretPos;

    var i = 0;
    while(i < numberOfRows){ // press pageup key N times
      keyEvent(inner$, 33, false, false);
      i++;
    }

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.y;
      return (newCaretPos < originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.lessThan(originalPos);
      done();
    });
  });

  it("Moves caret right a position", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.x;
    var newCaretPos;
    keyEvent(inner$, 39, false, false); // arrow right

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.x;
      return (newCaretPos > originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.moreThan(originalPos);
      done();
    });
  });

  it("Moves caret left a position", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.x;
    var newCaretPos;
    keyEvent(inner$, 33, false, false); // arrow left

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.x;
      return (newCaretPos < originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.lessThan(originalPos);
      done();
    });
  });

  it("Moves caret to the next line using right arrow", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.y;
    var newCaretPos;
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right
    keyEvent(inner$, 39, false, false); // arrow right

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.y;
      return (newCaretPos > originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.moreThan(originalPos);
      done();
    });
  });

  it("Moves caret to the previous line using left arrow", function(done){
    var inner$ = helper.padInner$;
    var $newFirstTextElement = inner$("div").first();
    var originalCaretPosition = caretPosition(inner$);
    var originalPos = originalCaretPosition.y;
    var newCaretPos;
    keyEvent(inner$, 33, false, false); // arrow left

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      var newCaretPosition = caretPosition(inner$);
      newCaretPos = newCaretPosition.y;
      return (newCaretPos < originalPos);
    }).done(function(){
      expect(newCaretPos).to.be.lessThan(originalPos);
      done();
    });
  });



/*
  it("Creates N rows, changes height of rows, updates UI by caret key events", function(done){
    var inner$ = helper.padInner$;
    var chrome$ = helper.padChrome$; 
    var numberOfRows = 50;
    
    //ace creates a new dom element when you press a keystroke, so just get the first text element again
    var $newFirstTextElement = inner$("div").first();
    var originalDivHeight = inner$("div").first().css("height");
    prepareDocument(numberOfRows, $newFirstTextElement); // N lines into the first div as a target

    helper.waitFor(function(){ // Wait for the DOM to register the new items
      return inner$("div").first().text().length == 6;
    }).done(function(){ // Once the DOM has registered the items
      inner$("div").each(function(index){ // Randomize the item heights (replicates images / headings etc)
        var random = Math.floor(Math.random() * (50)) + 20;
        $(this).css("height", random+"px"); 
      });

      console.log(caretPosition(inner$));
      var newDivHeight = inner$("div").first().css("height");
      var heightHasChanged = originalDivHeight != newDivHeight; // has the new div height changed from the original div height
      expect(heightHasChanged).to.be(true); // expect the first line to be blank
    });

    // Is this Element now visible to the pad user?
    helper.waitFor(function(){ // Wait for the DOM to register the new items
      return isScrolledIntoView(inner$("div:nth-child("+numberOfRows+")"), inner$); // Wait for the DOM to scroll into place
    }).done(function(){ // Once the DOM has registered the items
      inner$("div").each(function(index){ // Randomize the item heights (replicates images / headings etc)
        var random = Math.floor(Math.random() * (80 - 20 + 1)) + 20;
        $(this).css("height", random+"px");
      });

      var newDivHeight = inner$("div").first().css("height");
      var heightHasChanged = originalDivHeight != newDivHeight; // has the new div height changed from the original div height
      expect(heightHasChanged).to.be(true); // expect the first line to be blank
    });
    var i = 0;
    while(i < numberOfRows){ // press down arrow
console.log("dwn");
      keyEvent(inner$, 40, false, false);
      i++;
    }

    // Does scrolling back up the pad with the up arrow show the correct contents?
    helper.waitFor(function(){ // Wait for the new position to be in place
      try{
        return isScrolledIntoView(inner$("div:nth-child("+numberOfRows+")"), inner$); // Wait for the DOM to scroll into place
      }catch(e){
        return false;
      }
    }).done(function(){ // Once the DOM has registered the items

      var i = 0;
      while(i < numberOfRows){ // press down arrow
        keyEvent(inner$, 33, false, false); // doesn't work
        i++;
      }
  
      // Does scrolling back up the pad with the up arrow show the correct contents?
      helper.waitFor(function(){ // Wait for the new position to be in place
        try{
          return isScrolledIntoView(inner$("div:nth-child(0)"), inner$); // Wait for the DOM to scroll into place
        }catch(e){
          return false;
        }
      }).done(function(){ // Once the DOM has registered the items



      });
   });


     var i = 0;
      while(i < numberOfRows){ // press down arrow
        keyEvent(inner$, 33, false, false); // doesn't work
        i++;
      }


    // Does scrolling back up the pad with the up arrow show the correct contents?
    helper.waitFor(function(){ // Wait for the new position to be in place
      return isScrolledIntoView(inner$("div:nth-child(1)"), inner$); // Wait for the DOM to scroll into place
    }).done(function(){ // Once the DOM has registered the items
      expect(true).to.be(true); 
      done();
    });
*/

});

function prepareDocument(n, target){ // generates a random document with random content on n lines
  var i = 0;
  while(i < n){ // for each line
    target.sendkeys(makeStr()); // generate a random string and send that to the editor
    target.sendkeys('{enter}'); // generator an enter keypress
    i++; // rinse n times
  }
}

function keyEvent(target, charCode, ctrl, shift){ // sends a charCode to the window
  if(target.browser.mozilla){ // if it's a mozilla browser
    var evtType = "keypress";
  }else{
    var evtType = "keydown";
  }
  var e = target.Event(evtType);
  if(ctrl){
    e.ctrlKey = true; // Control key
  }
  if(shift){
    e.shiftKey = true; // Shift Key
  }
  e.which = charCode; 
  target("#innerdocbody").trigger(e);
}


function makeStr(){ // from http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for( var i=0; i < 5; i++ )
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  return text;
}

function isScrolledIntoView(elem, $){ // from http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top; // how far the element is from the top of it's container
    var elemBottom = elemTop + $(elem).height(); // how far plus the height of the elem..  IE is it all in?
    elemBottom = elemBottom - 16; // don't ask, sorry but this is needed..
    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

function caretPosition($){
  var doc = $.window.document;
  var pos = doc.getSelection();
  pos.y = pos.anchorNode.parentElement.offsetTop;
  pos.x = pos.anchorNode.parentElement.offsetLeft;
  console.log(pos);
  return pos;
}