describe("As the caret is moved is the UI properly updated?", function(){ var padName; var numberOfRows = 50; /* //create a new pad before each test run beforeEach(function(cb){ helper.newPad(cb); this.timeout(60000); }); xit("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 IN CHROME AS IT DOESNT MOVE THE CURSOR! it("down arrow", function(done){ var inner$ = helper.padInner$; var chrome$ = helper.padChrome$; var $newFirstTextElement = inner$("div").first(); $newFirstTextElement.focus(); keyEvent(inner$, 37, false, false); // arrow down keyEvent(inner$, 37, false, false); // arrow down done(); }); it("Creates N lines", function(done){ var inner$ = helper.padInner$; console.log(inner$); 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 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(inner$(window)[0].bowser.firefox || inner$(window)[0].bowser.modernIE){ // if it's a mozilla or IE var evtType = "keypress"; }else{ var evtType = "keydown"; } var e = target.Event(evtType); console.log(e); if(ctrl){ e.ctrlKey = true; // Control key } if(shift){ e.shiftKey = true; // Shift Key } e.which = charCode; e.keyCode = 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; }