disable most tests

native-events
webzwo0i 2020-11-14 17:17:17 +01:00
parent f1c3415de9
commit 536a6dce70
35 changed files with 0 additions and 4338 deletions

View File

@ -1,109 +0,0 @@
describe('author of pad edition', function() {
var REGULAR_LINE = 0;
var LINE_WITH_ORDERED_LIST = 1;
var LINE_WITH_UNORDERED_LIST = 2;
// author 1 creates a new pad with some content (regular lines and lists)
before(function(done) {
var padId = helper.newPad(function() {
// make sure pad has at least 3 lines
var $firstLine = helper.padInner$('div').first();
var threeLines = ['regular line', 'line with ordered list', 'line with unordered list'].join('<br>');
$firstLine.html(threeLines);
// wait for lines to be processed by Etherpad
helper.waitFor(function() {
var $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
return $lineWithUnorderedList.text() === 'line with unordered list';
}).done(function() {
// create the unordered list
var $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
$lineWithUnorderedList.sendkeys('{selectall}');
var $insertUnorderedListButton = helper.padChrome$('.buttonicon-insertunorderedlist');
$insertUnorderedListButton.click();
helper.waitFor(function() {
var $lineWithUnorderedList = getLine(LINE_WITH_UNORDERED_LIST);
return $lineWithUnorderedList.find('ul li').length === 1;
}).done(function() {
// create the ordered list
var $lineWithOrderedList = getLine(LINE_WITH_ORDERED_LIST);
$lineWithOrderedList.sendkeys('{selectall}');
var $insertOrderedListButton = helper.padChrome$('.buttonicon-insertorderedlist');
$insertOrderedListButton.click();
helper.waitFor(function() {
var $lineWithOrderedList = getLine(LINE_WITH_ORDERED_LIST);
return $lineWithOrderedList.find('ol li').length === 1;
}).done(function() {
// Reload pad, to make changes as a second user. Need a timeout here to make sure
// all changes were saved before reloading
setTimeout(function() {
// Expire cookie, so author is changed after reloading the pad.
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_4_Reset_the_previous_cookie
helper.padChrome$.document.cookie = 'token=foo;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
helper.newPad(done, padId);
}, 1000);
});
});
});
});
this.timeout(60000);
});
// author 2 makes some changes on the pad
it('marks only the new content as changes of the second user on a regular line', function(done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(REGULAR_LINE, 'x', done);
});
it('marks only the new content as changes of the second user on a line with ordered list', function(done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(LINE_WITH_ORDERED_LIST, 'y', done);
});
it('marks only the new content as changes of the second user on a line with unordered list', function(done) {
changeLineAndCheckOnlyThatChangeIsFromThisAuthor(LINE_WITH_UNORDERED_LIST, 'z', done);
});
/* ********************** Helper functions ************************ */
var getLine = function(lineNumber) {
return helper.padInner$('div').eq(lineNumber);
}
var getAuthorFromClassList = function(classes) {
return classes.find(function(cls) {
return cls.startsWith('author');
});
}
var changeLineAndCheckOnlyThatChangeIsFromThisAuthor = function(lineNumber, textChange, done) {
// get original author class
var classes = getLine(lineNumber).find('span').first().attr('class').split(' ');
var originalAuthor = getAuthorFromClassList(classes);
// make change on target line
var $regularLine = getLine(lineNumber);
helper.selectLines($regularLine, $regularLine, 2, 2); // place caret after 2nd char of line
$regularLine.sendkeys(textChange);
// wait for change to be processed by Etherpad
var otherAuthorsOfLine;
helper.waitFor(function() {
var authorsOfLine = getLine(lineNumber).find('span').map(function() {
return getAuthorFromClassList($(this).attr('class').split(' '));
}).get();
otherAuthorsOfLine = authorsOfLine.filter(function(author) {
return author !== originalAuthor;
});
var lineHasChangeOfThisAuthor = otherAuthorsOfLine.length > 0;
return lineHasChangeOfThisAuthor;
}).done(function() {
var thisAuthor = otherAuthorsOfLine[0];
var $changeOfThisAuthor = getLine(lineNumber).find('span.' + thisAuthor);
expect($changeOfThisAuthor.text()).to.be(textChange);
done();
});
}
});

View File

@ -1,66 +0,0 @@
describe("bold button", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text bold on click", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
//get the bold button and click it
var $boldButton = chrome$(".buttonicon-bold");
$boldButton.click();
//ace creates a new dom element when you press a button, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// is there a <b> element now?
var isBold = $newFirstTextElement.find("b").length === 1;
//expect it to be bold
expect(isBold).to.be(true);
//make sure the text hasn't changed
expect($newFirstTextElement.text()).to.eql($firstTextElement.text());
done();
});
it("makes text bold on keypress", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 66; // b
inner$("#innerdocbody").trigger(e);
//ace creates a new dom element when you press a button, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// is there a <b> element now?
var isBold = $newFirstTextElement.find("b").length === 1;
//expect it to be bold
expect(isBold).to.be(true);
//make sure the text hasn't changed
expect($newFirstTextElement.text()).to.eql($firstTextElement.text());
done();
});
});

View File

@ -1,338 +0,0 @@
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
var e = target.Event(helper.evtType);
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;
return pos;
}

View File

@ -1,104 +0,0 @@
describe("change user color", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("Color picker matches original color and remembers the user color after a refresh", function(done) {
this.timeout(60000);
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $userSwatch = chrome$("#myswatch");
$userSwatch.click();
var fb = chrome$.farbtastic('#colorpicker')
var $colorPickerSave = chrome$("#mycolorpickersave");
var $colorPickerPreview = chrome$("#mycolorpickerpreview");
// Same color represented in two different ways
const testColorHash = '#abcdef'
const testColorRGB = 'rgb(171, 205, 239)'
// Check that the color picker matches the automatically assigned random color on the swatch.
// NOTE: This has a tiny chance of creating a false positive for passing in the
// off-chance the randomly assigned color is the same as the test color.
expect($colorPickerPreview.css('background-color')).to.be($userSwatch.css('background-color'))
// The swatch updates as the test color is picked.
fb.setColor(testColorHash)
expect($colorPickerPreview.css('background-color')).to.be(testColorRGB)
$colorPickerSave.click();
expect($userSwatch.css('background-color')).to.be(testColorRGB)
setTimeout(function(){ //give it a second to save the color on the server side
helper.newPad({ // get a new pad, but don't clear the cookies
clearCookies: false
, cb: function(){
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $userSwatch = chrome$("#myswatch");
$userSwatch.click();
var $colorPickerPreview = chrome$("#mycolorpickerpreview");
expect($colorPickerPreview.css('background-color')).to.be(testColorRGB)
expect($userSwatch.css('background-color')).to.be(testColorRGB)
done();
}
});
}, 1000);
});
it("Own user color is shown when you enter a chat", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $colorOption = helper.padChrome$('#options-colorscheck');
if (!$colorOption.is(':checked')) {
$colorOption.click();
}
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $userSwatch = chrome$("#myswatch");
$userSwatch.click();
var fb = chrome$.farbtastic('#colorpicker')
var $colorPickerSave = chrome$("#mycolorpickersave");
// Same color represented in two different ways
const testColorHash = '#abcdef'
const testColorRGB = 'rgb(171, 205, 239)'
fb.setColor(testColorHash)
$colorPickerSave.click();
//click on the chat button to make chat visible
var $chatButton = chrome$("#chaticon");
$chatButton.click();
var $chatInput = chrome$("#chatinput");
$chatInput.sendkeys('O hi'); // simulate a keypress of typing user
$chatInput.sendkeys('{enter}'); // simulate a keypress of enter actually does evt.which = 10 not 13
//check if chat shows up
helper.waitFor(function(){
return chrome$("#chattext").children("p").length !== 0; // wait until the chat message shows up
}).done(function(){
var $firstChatMessage = chrome$("#chattext").children("p");
expect($firstChatMessage.css('background-color')).to.be(testColorRGB); // expect the first chat message to be of the user's color
done();
});
});
});

View File

@ -1,72 +0,0 @@
describe("change username value", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("Remembers the user name after a refresh", function(done) {
this.timeout(60000);
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $usernameInput = chrome$("#myusernameedit");
$usernameInput.click();
$usernameInput.val('John McLear');
$usernameInput.blur();
setTimeout(function(){ //give it a second to save the username on the server side
helper.newPad({ // get a new pad, but don't clear the cookies
clearCookies: false
, cb: function(){
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $usernameInput = chrome$("#myusernameedit");
expect($usernameInput.val()).to.be('John McLear')
done();
}
});
}, 1000);
});
it("Own user name is shown when you enter a chat", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $usernameInput = chrome$("#myusernameedit");
$usernameInput.click();
$usernameInput.val('John McLear');
$usernameInput.blur();
//click on the chat button to make chat visible
var $chatButton = chrome$("#chaticon");
$chatButton.click();
var $chatInput = chrome$("#chatinput");
$chatInput.sendkeys('O hi'); // simulate a keypress of typing JohnMcLear
$chatInput.sendkeys('{enter}'); // simulate a keypress of enter actually does evt.which = 10 not 13
//check if chat shows up
helper.waitFor(function(){
return chrome$("#chattext").children("p").length !== 0; // wait until the chat message shows up
}).done(function(){
var $firstChatMessage = chrome$("#chattext").children("p");
var containsJohnMcLear = $firstChatMessage.text().indexOf("John McLear") !== -1; // does the string contain John McLear
expect(containsJohnMcLear).to.be(true); // expect the first chat message to contain JohnMcLear
done();
});
});
});

View File

@ -1,114 +0,0 @@
describe("Chat messages and UI", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
});
it("opens chat, sends a message, makes sure it exists on the page and hides chat", async function() {
var chatValue = "JohnMcLear";
await helper.showChat();
await helper.sendChatMessage(`${chatValue}{enter}`);
expect(helper.chatTextParagraphs().length).to.be(1);
// <p data-authorid="a.qjkwNs4z0pPROphS"
// class="author-a-qjkwz78zs4z122z0pz80zz82zz79zphz83z">
// <b>unnamed:</b>
// <span class="time author-a-qjkwz78zs4z122z0pz80zz82zz79zphz83z">12:38
// </span> JohnMcLear
// </p>
let username = helper.chatTextParagraphs().children("b").text();
let time = helper.chatTextParagraphs().children(".time").text();
expect(helper.chatTextParagraphs().text()).to.be(`${username}${time} ${chatValue}`);
await helper.hideChat();
});
it("makes sure that an empty message can't be sent", async function() {
var chatValue = "mluto";
await helper.showChat();
await helper.sendChatMessage(`{enter}${chatValue}{enter}`); // simulate a keypress of typing enter, mluto and enter (to send 'mluto')
let chat = helper.chatTextParagraphs();
expect(chat.length).to.be(1);
// check that the received message is not the empty one
let username = chat.children("b").text();
let time = chat.children(".time").text();
expect(chat.text()).to.be(`${username}${time} ${chatValue}`);
});
it("makes chat stick to right side of the screen via settings, remove sticky via settings, close it", async function() {
await helper.showSettings();
await helper.enableStickyChatviaSettings();
expect(helper.isChatboxShown()).to.be(true);
expect(helper.isChatboxSticky()).to.be(true);
await helper.disableStickyChatviaSettings();
expect(helper.isChatboxSticky()).to.be(false);
expect(helper.isChatboxShown()).to.be(true);
await helper.hideChat();
expect(helper.isChatboxSticky()).to.be(false);
expect(helper.isChatboxShown()).to.be(false);
});
it("makes chat stick to right side of the screen via icon on the top right, remove sticky via icon, close it", async function() {
await helper.showChat();
await helper.enableStickyChatviaIcon();
expect(helper.isChatboxShown()).to.be(true);
expect(helper.isChatboxSticky()).to.be(true);
await helper.disableStickyChatviaIcon();
expect(helper.isChatboxShown()).to.be(true);
expect(helper.isChatboxSticky()).to.be(false);
await helper.hideChat();
expect(helper.isChatboxSticky()).to.be(false);
expect(helper.isChatboxShown()).to.be(false);
});
xit("Checks showChat=false URL Parameter hides chat then when removed it shows chat", function(done) {
this.timeout(60000);
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
setTimeout(function(){ //give it a second to save the username on the server side
helper.newPad({ // get a new pad, but don't clear the cookies
clearCookies: false,
params:{
showChat: "false"
}, cb: function(){
var chrome$ = helper.padChrome$;
var chaticon = chrome$("#chaticon");
// chat should be hidden.
expect(chaticon.is(":visible")).to.be(false);
setTimeout(function(){ //give it a second to save the username on the server side
helper.newPad({ // get a new pad, but don't clear the cookies
clearCookies: false
, cb: function(){
var chrome$ = helper.padChrome$;
var chaticon = chrome$("#chaticon");
// chat should be visible.
expect(chaticon.is(":visible")).to.be(true);
done();
}
});
}, 1000);
}
});
}, 1000);
});
});

View File

@ -1,88 +0,0 @@
describe("chat-load-messages", function(){
var padName;
it("creates a pad", function(done) {
padName = helper.newPad(done);
this.timeout(60000);
});
it("adds a lot of messages", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var chatButton = chrome$("#chaticon");
chatButton.click();
var chatInput = chrome$("#chatinput");
var chatText = chrome$("#chattext");
this.timeout(60000);
var messages = 140;
for(var i=1; i <= messages; i++) {
var num = ''+i;
if(num.length == 1)
num = '00'+num;
if(num.length == 2)
num = '0'+num;
chatInput.sendkeys('msg' + num);
chatInput.sendkeys('{enter}');
}
helper.waitFor(function(){
return chatText.children("p").length == messages;
}, 60000).always(function(){
expect(chatText.children("p").length).to.be(messages);
helper.newPad(done, padName);
});
});
it("checks initial message count", function(done) {
var chatText;
var expectedCount = 101;
var chrome$ = helper.padChrome$;
helper.waitFor(function(){
var chatButton = chrome$("#chaticon");
chatButton.click();
chatText = chrome$("#chattext");
return chatText.children("p").length == expectedCount;
}).always(function(){
expect(chatText.children("p").length).to.be(expectedCount);
done();
});
});
it("loads more messages", function(done) {
var expectedCount = 122;
var chrome$ = helper.padChrome$;
var chatButton = chrome$("#chaticon");
chatButton.click();
var chatText = chrome$("#chattext");
var loadMsgBtn = chrome$("#chatloadmessagesbutton");
loadMsgBtn.click();
helper.waitFor(function(){
return chatText.children("p").length == expectedCount;
}).always(function(){
expect(chatText.children("p").length).to.be(expectedCount);
done();
});
});
it("checks for button vanishing", function(done) {
var expectedDisplay = 'none';
var chrome$ = helper.padChrome$;
var chatButton = chrome$("#chaticon");
chatButton.click();
var chatText = chrome$("#chattext");
var loadMsgBtn = chrome$("#chatloadmessagesbutton");
var loadMsgBall = chrome$("#chatloadmessagesball");
loadMsgBtn.click();
helper.waitFor(function(){
return loadMsgBtn.css('display') == expectedDisplay &&
loadMsgBall.css('display') == expectedDisplay;
}).always(function(){
expect(loadMsgBtn.css('display')).to.be(expectedDisplay);
expect(loadMsgBall.css('display')).to.be(expectedDisplay);
done();
});
});
});

View File

@ -1,133 +0,0 @@
describe("clear authorship colors button", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text clear authorship colors", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// override the confirm dialogue functioon
helper.padChrome$.window.confirm = function(){
return true;
}
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
// Get the original text
var originalText = inner$("div").first().text();
// Set some new text
var sentText = "Hello";
//select this text element
$firstTextElement.sendkeys('{selectall}');
$firstTextElement.sendkeys(sentText);
$firstTextElement.sendkeys('{rightarrow}');
helper.waitFor(function(){
return inner$("div span").first().attr("class").indexOf("author") !== -1; // wait until we have the full value available
}).done(function(){
//IE hates you if you don't give focus to the inner frame bevore you do a clearAuthorship
inner$("div").first().focus();
//get the clear authorship colors button and click it
var $clearauthorshipcolorsButton = chrome$(".buttonicon-clearauthorship");
$clearauthorshipcolorsButton.click();
// does the first divs span include an author class?
var hasAuthorClass = inner$("div span").first().attr("class").indexOf("author") !== -1;
//expect(hasAuthorClass).to.be(false);
// does the first div include an author class?
var hasAuthorClass = inner$("div").first().attr("class").indexOf("author") !== -1;
expect(hasAuthorClass).to.be(false);
helper.waitFor(function(){
var disconnectVisible = chrome$("div.disconnected").attr("class").indexOf("visible") === -1
return (disconnectVisible === true)
});
var disconnectVisible = chrome$("div.disconnected").attr("class").indexOf("visible") === -1
expect(disconnectVisible).to.be(true);
done();
});
});
it("makes text clear authorship colors and checks it can't be undone", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// override the confirm dialogue functioon
helper.padChrome$.window.confirm = function(){
return true;
}
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
// Get the original text
var originalText = inner$("div").first().text();
// Set some new text
var sentText = "Hello";
//select this text element
$firstTextElement.sendkeys('{selectall}');
$firstTextElement.sendkeys(sentText);
$firstTextElement.sendkeys('{rightarrow}');
helper.waitFor(function(){
return inner$("div span").first().attr("class").indexOf("author") !== -1; // wait until we have the full value available
}).done(function(){
//IE hates you if you don't give focus to the inner frame bevore you do a clearAuthorship
inner$("div").first().focus();
//get the clear authorship colors button and click it
var $clearauthorshipcolorsButton = chrome$(".buttonicon-clearauthorship");
$clearauthorshipcolorsButton.click();
// does the first divs span include an author class?
var hasAuthorClass = inner$("div span").first().attr("class").indexOf("author") !== -1;
//expect(hasAuthorClass).to.be(false);
// does the first div include an author class?
var hasAuthorClass = inner$("div").first().attr("class").indexOf("author") !== -1;
expect(hasAuthorClass).to.be(false);
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 90; // z
inner$("#innerdocbody").trigger(e); // shouldn't od anything
// does the first div include an author class?
hasAuthorClass = inner$("div").first().attr("class").indexOf("author") !== -1;
expect(hasAuthorClass).to.be(false);
// get undo and redo buttons
var $undoButton = chrome$(".buttonicon-undo");
// click the button
$undoButton.click(); // shouldn't do anything
hasAuthorClass = inner$("div").first().attr("class").indexOf("author") !== -1;
expect(hasAuthorClass).to.be(false);
helper.waitFor(function(){
var disconnectVisible = chrome$("div.disconnected").attr("class").indexOf("visible") === -1
return (disconnectVisible === true)
});
var disconnectVisible = chrome$("div.disconnected").attr("class").indexOf("visible") === -1
expect(disconnectVisible).to.be(true);
done();
});
});
});

View File

@ -1,37 +0,0 @@
describe("delete keystroke", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text delete", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
// get the original length of this element
var elementLength = $firstTextElement.text().length;
// get the original string value minus the last char
var originalTextValue = $firstTextElement.text();
var originalTextValueMinusFirstChar = originalTextValue.substring(1, originalTextValue.length );
// simulate key presses to delete content
$firstTextElement.sendkeys('{leftarrow}'); // simulate a keypress of the left arrow key
$firstTextElement.sendkeys('{del}'); // simulate a keypress of delete
//ace creates a new dom element when you press a keystroke, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// get the new length of this element
var newElementLength = $newFirstTextElement.text().length;
//expect it to be one char less in length
expect(newElementLength).to.be((elementLength-1));
done();
});
});

View File

@ -1,168 +0,0 @@
// WARNING: drag and drop is only simulated on these tests, so manual testing might also be necessary
describe('drag and drop', function() {
before(function(done) {
helper.newPad(function() {
createScriptWithSeveralLines(done);
});
this.timeout(60000);
});
context('when user drags part of one line and drops it far form its original place', function() {
before(function(done) {
selectPartOfSourceLine();
dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
// make sure DnD was correctly simulated
helper.waitFor(function() {
var $targetLine = getLine(TARGET_LINE);
var sourceWasMovedToTarget = $targetLine.text() === 'Target line [line 1]';
return sourceWasMovedToTarget;
}).done(done);
});
context('and user triggers UNDO', function() {
before(function() {
var $undoButton = helper.padChrome$(".buttonicon-undo");
$undoButton.click();
});
it('moves text back to its original place', function(done) {
// test text was removed from drop target
var $targetLine = getLine(TARGET_LINE);
expect($targetLine.text()).to.be('Target line []');
// test text was added back to original place
var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
expect($firstSourceLine.text()).to.be('Source line 1.');
expect($lastSourceLine.text()).to.be('Source line 2.');
done();
});
});
});
context('when user drags some lines far form its original place', function() {
before(function(done) {
selectMultipleSourceLines();
dragSelectedTextAndDropItIntoMiddleOfLine(TARGET_LINE);
// make sure DnD was correctly simulated
helper.waitFor(function() {
var $lineAfterTarget = getLine(TARGET_LINE + 1);
var sourceWasMovedToTarget = $lineAfterTarget.text() !== '...';
return sourceWasMovedToTarget;
}).done(done);
});
context('and user triggers UNDO', function() {
before(function() {
var $undoButton = helper.padChrome$(".buttonicon-undo");
$undoButton.click();
});
it('moves text back to its original place', function(done) {
// test text was removed from drop target
var $targetLine = getLine(TARGET_LINE);
expect($targetLine.text()).to.be('Target line []');
// test text was added back to original place
var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
expect($firstSourceLine.text()).to.be('Source line 1.');
expect($lastSourceLine.text()).to.be('Source line 2.');
done();
});
});
});
/* ********************* Helper functions/constants ********************* */
var TARGET_LINE = 2;
var FIRST_SOURCE_LINE = 5;
var getLine = function(lineNumber) {
var $lines = helper.padInner$('div');
return $lines.slice(lineNumber, lineNumber + 1);
}
var createScriptWithSeveralLines = function(done) {
// create some lines to be used on the tests
var $firstLine = helper.padInner$('div').first();
$firstLine.html('...<br>...<br>Target line []<br>...<br>...<br>Source line 1.<br>Source line 2.<br>');
// wait for lines to be split
helper.waitFor(function(){
var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
return $lastSourceLine.text() === 'Source line 2.';
}).done(done);
}
var selectPartOfSourceLine = function() {
var $sourceLine = getLine(FIRST_SOURCE_LINE);
// select 'line 1' from 'Source line 1.'
var start = 'Source '.length;
var end = start + 'line 1'.length;
helper.selectLines($sourceLine, $sourceLine, start, end);
}
var selectMultipleSourceLines = function() {
var $firstSourceLine = getLine(FIRST_SOURCE_LINE);
var $lastSourceLine = getLine(FIRST_SOURCE_LINE + 1);
helper.selectLines($firstSourceLine, $lastSourceLine);
}
var dragSelectedTextAndDropItIntoMiddleOfLine = function(targetLineNumber) {
// dragstart: start dragging content
triggerEvent('dragstart');
// drop: get HTML data from selected text
var draggedHtml = getHtmlFromSelectedText();
triggerEvent('drop');
// dragend: remove original content + insert HTML data into target
moveSelectionIntoTarget(draggedHtml, targetLineNumber);
triggerEvent('dragend');
}
var getHtmlFromSelectedText = function() {
var innerDocument = helper.padInner$.document;
var range = innerDocument.getSelection().getRangeAt(0);
var clonedSelection = range.cloneContents();
var span = innerDocument.createElement('span');
span.id = 'buffer';
span.appendChild(clonedSelection);
var draggedHtml = span.outerHTML;
return draggedHtml;
}
var triggerEvent = function(eventName) {
var event = helper.padInner$.Event(eventName);
helper.padInner$('#innerdocbody').trigger(event);
}
var moveSelectionIntoTarget = function(draggedHtml, targetLineNumber) {
var innerDocument = helper.padInner$.document;
// delete original content
innerDocument.execCommand('delete');
// set position to insert content on target line
var $target = getLine(targetLineNumber);
$target.sendkeys('{selectall}{rightarrow}{leftarrow}');
// Insert content.
// Based on http://stackoverflow.com/a/6691294, to be IE-compatible
var range = innerDocument.getSelection().getRangeAt(0);
var frag = innerDocument.createDocumentFragment();
var el = innerDocument.createElement('div');
el.innerHTML = draggedHtml;
while (el.firstChild) {
frag.appendChild(el.firstChild);
}
range.insertNode(frag);
}
});

View File

@ -1,136 +0,0 @@
describe("embed links", function(){
var objectify = function (str)
{
var hash = {};
var parts = str.split('&');
for(var i = 0; i < parts.length; i++)
{
var keyValue = parts[i].split('=');
hash[keyValue[0]] = keyValue[1];
}
return hash;
}
var checkiFrameCode = function(embedCode, readonly){
//turn the code into an html element
var $embediFrame = $(embedCode);
//read and check the frame attributes
var width = $embediFrame.attr("width");
var height = $embediFrame.attr("height");
var name = $embediFrame.attr("name");
expect(width).to.be('100%');
expect(height).to.be('600');
expect(name).to.be(readonly ? "embed_readonly" : "embed_readwrite");
//parse the url
var src = $embediFrame.attr("src");
var questionMark = src.indexOf("?");
var url = src.substr(0,questionMark);
var paramsStr = src.substr(questionMark+1);
var params = objectify(paramsStr);
var expectedParams = {
showControls: 'true'
, showChat: 'true'
, showLineNumbers: 'true'
, useMonospaceFont: 'false'
}
//check the url
if(readonly){
expect(url.indexOf("r.") > 0).to.be(true);
} else {
expect(url).to.be(helper.padChrome$.window.location.href);
}
//check if all parts of the url are like expected
expect(params).to.eql(expectedParams);
}
describe("read and write", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
describe("the share link", function(){
it("is the actual pad url", function(done){
var chrome$ = helper.padChrome$;
//open share dropdown
chrome$(".buttonicon-embed").click();
//get the link of the share field + the actual pad url and compare them
var shareLink = chrome$("#linkinput").val();
var padURL = chrome$.window.location.href;
expect(shareLink).to.be(padURL);
done();
});
});
describe("the embed as iframe code", function(){
it("is an iframe with the the correct url parameters and correct size", function(done){
var chrome$ = helper.padChrome$;
//open share dropdown
chrome$(".buttonicon-embed").click();
//get the link of the share field + the actual pad url and compare them
var embedCode = chrome$("#embedinput").val();
checkiFrameCode(embedCode, false)
done();
});
});
});
describe("when read only option is set", function(){
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
describe("the share link", function(){
it("shows a read only url", function(done){
var chrome$ = helper.padChrome$;
//open share dropdown
chrome$(".buttonicon-embed").click();
chrome$('#readonlyinput').click();
chrome$('#readonlyinput:checkbox:not(:checked)').attr('checked', 'checked');
//get the link of the share field + the actual pad url and compare them
var shareLink = chrome$("#linkinput").val();
var containsReadOnlyLink = shareLink.indexOf("r.") > 0
expect(containsReadOnlyLink).to.be(true);
done();
});
});
describe("the embed as iframe code", function(){
it("is an iframe with the the correct url parameters and correct size", function(done){
var chrome$ = helper.padChrome$;
//open share dropdown
chrome$(".buttonicon-embed").click();
//check read only checkbox, a bit hacky
chrome$('#readonlyinput').click();
chrome$('#readonlyinput:checkbox:not(:checked)').attr('checked', 'checked');
//get the link of the share field + the actual pad url and compare them
var embedCode = chrome$("#embedinput").val();
checkiFrameCode(embedCode, true);
done();
});
});
});
});

View File

@ -1,34 +0,0 @@
describe("enter keystroke", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("creates a new line & puts cursor onto a new line", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
// get the original string value minus the last char
var originalTextValue = $firstTextElement.text();
// simulate key presses to enter content
$firstTextElement.sendkeys('{enter}');
//ace creates a new dom element when you press a keystroke, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
helper.waitFor(function(){
return inner$("div").first().text() === "";
}).done(function(){
var $newSecondLine = inner$("div").first().next();
var newFirstTextElementValue = inner$("div").first().text();
expect(newFirstTextElementValue).to.be(""); // expect the first line to be blank
expect($newSecondLine.text()).to.be(originalTextValue); // expect the second line to be the same as the original first line.
done();
});
});
});

View File

@ -1,33 +0,0 @@
describe("font select", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text RobotoMono", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $settingsButton = chrome$(".buttonicon-settings");
$settingsButton.click();
//get the font menu and RobotoMono option
var $viewfontmenu = chrome$("#viewfontmenu");
var $RobotoMonooption = $viewfontmenu.find("[value=RobotoMono]");
//select RobotoMono and fire change event
// $RobotoMonooption.attr('selected','selected');
// commenting out above will break safari test
$viewfontmenu.val("RobotoMono");
$viewfontmenu.change();
//check if font changed to RobotoMono
var fontFamily = inner$("body").css("font-family").toLowerCase();
var containsStr = fontFamily.indexOf("robotomono");
expect(containsStr).to.not.be(-1);
done();
});
});

View File

@ -1,468 +0,0 @@
describe("the test helper", function(){
describe("the newPad method", function(){
xit("doesn't leak memory if you creates iframes over and over again", function(done){
this.timeout(100000);
var times = 10;
var loadPad = function(){
helper.newPad(function(){
times--;
if(times > 0){
loadPad();
} else {
done();
}
})
}
loadPad();
});
it("gives me 3 jquery instances of chrome, outer and inner", function(done){
this.timeout(10000);
helper.newPad(function(){
//check if the jquery selectors have the desired elements
expect(helper.padChrome$("#editbar").length).to.be(1);
expect(helper.padOuter$("#outerdocbody").length).to.be(1);
expect(helper.padInner$("#innerdocbody").length).to.be(1);
//check if the document object was set correctly
expect(helper.padChrome$.window.document).to.be(helper.padChrome$.document);
expect(helper.padOuter$.window.document).to.be(helper.padOuter$.document);
expect(helper.padInner$.window.document).to.be(helper.padInner$.document);
done();
});
});
// Make sure the cookies are cleared, and make sure that the cookie
// clearing has taken effect at this point in the code. It has been
// observed that the former can happen without the latter if there
// isn't a timeout (within `newPad`) after clearing the cookies.
// However this doesn't seem to always be easily replicated, so this
// timeout may or may end up in the code. None the less, we test here
// to catch it if the bug comes up again.
it("clears cookies", function(done) {
this.timeout(60000);
// set cookies far into the future to make sure they're not expired yet
window.document.cookie = 'token=foo;expires=Thu, 01 Jan 3030 00:00:00 GMT; path=/';
window.document.cookie = 'language=bar;expires=Thu, 01 Jan 3030 00:00:00 GMT; path=/';
expect(window.document.cookie).to.contain('token=foo');
expect(window.document.cookie).to.contain('language=bar');
helper.newPad(function(){
// helper function seems to have cleared cookies
// NOTE: this doesn't yet mean it's proven to have taken effect by this point in execution
var firstCookie = window.document.cookie
expect(firstCookie).to.not.contain('token=foo');
expect(firstCookie).to.not.contain('language=bar');
var chrome$ = helper.padChrome$;
// click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
var $usernameInput = chrome$("#myusernameedit");
$usernameInput.click();
$usernameInput.val('John McLear');
$usernameInput.blur();
// Before refreshing, make sure the name is there
expect($usernameInput.val()).to.be('John McLear');
// Now that we have a chrome, we can set a pad cookie, so we can confirm it gets wiped as well
chrome$.document.cookie = 'prefsHtml=baz;expires=Thu, 01 Jan 3030 00:00:00 GMT';
expect(chrome$.document.cookie).to.contain('prefsHtml=baz');
// Cookies are weird. Because it's attached to chrome$ (as helper.setPadCookies does), AND we
// didn't put path=/, we shouldn't expect it to be visible on window.document.cookie. Let's just
// be sure.
expect(window.document.cookie).to.not.contain('prefsHtml=baz');
setTimeout(function(){ //give it a second to save the username on the server side
helper.newPad(function(){ // get a new pad, let it clear the cookies
var chrome$ = helper.padChrome$;
// helper function seems to have cleared cookies
// NOTE: this doesn't yet mean cookies were cleared effectively.
// We still need to test below that we're in a new session
expect(window.document.cookie).to.not.contain('token=foo');
expect(window.document.cookie).to.not.contain('language=bar');
expect(chrome$.document.cookie).to.contain('prefsHtml=baz');
expect(window.document.cookie).to.not.contain('prefsHtml=baz');
expect(window.document.cookie).to.not.be(firstCookie);
// click on the settings button to make settings visible
var $userButton = chrome$(".buttonicon-showusers");
$userButton.click();
// confirm that the session was actually cleared
var $usernameInput = chrome$("#myusernameedit");
expect($usernameInput.val()).to.be('');
done();
});
}, 1000);
});
});
it("sets pad prefs cookie", function(done) {
this.timeout(60000);
helper.newPad({
padPrefs: {foo:"bar"},
cb: function(){
var chrome$ = helper.padChrome$;
expect(chrome$.document.cookie).to.contain('prefsHttp=%7B%22');
expect(chrome$.document.cookie).to.contain('foo%22%3A%22bar');
done();
}
});
});
});
describe("the waitFor method", function(){
it("takes a timeout and waits long enough", function(done){
this.timeout(2000);
var startTime = Date.now();
helper.waitFor(function(){
return false;
}, 1500).fail(function(){
var duration = Date.now() - startTime;
expect(duration).to.be.greaterThan(1490);
done();
});
});
it("takes an interval and checks on every interval", function(done){
this.timeout(4000);
var checks = 0;
helper.waitFor(function(){
checks++;
return false;
}, 2000, 100).fail(function(){
// One at the beginning, and 19-20 more depending on whether it's the timeout or the final
// poll that wins at 2000ms.
expect(checks).to.be.greaterThan(18);
expect(checks).to.be.lessThan(22);
done();
});
});
it('rejects if the predicate throws', async function() {
let err;
await helper.waitFor(() => { throw new Error('test exception'); })
.fail(() => {}) // Suppress the redundant uncatchable exception.
.catch((e) => { err = e; });
expect(err).to.be.an(Error);
expect(err.message).to.be('test exception');
});
describe("returns a deferred object", function(){
it("it calls done after success", function(done){
helper.waitFor(function(){
return true;
}).done(function(){
done();
});
});
it("calls fail after failure", function(done){
helper.waitFor(function(){
return false;
},0).fail(function(){
done();
});
});
xit("throws if you don't listen for fails", function(done){
var onerror = window.onerror;
window.onerror = function(){
window.onerror = onerror;
done();
}
helper.waitFor(function(){
return false;
},100);
});
});
describe('checks first then sleeps', function() {
it('resolves quickly if the predicate is immediately true', async function() {
const before = Date.now();
await helper.waitFor(() => true, 1000, 900);
expect(Date.now() - before).to.be.lessThan(800);
});
it('polls exactly once if timeout < interval', async function() {
let calls = 0;
await helper.waitFor(() => { calls++; }, 1, 1000)
.fail(() => {}) // Suppress the redundant uncatchable exception.
.catch(() => {}); // Don't throw an exception -- we know it rejects.
expect(calls).to.be(1);
});
it('resolves if condition is immediately true even if timeout is 0', async function() {
await helper.waitFor(() => true, 0);
});
});
});
describe('the waitForPromise method', function() {
it('returns a Promise', async function() {
expect(helper.waitForPromise(() => true)).to.be.a(Promise);
});
it('takes a timeout and waits long enough', async function() {
this.timeout(2000);
const startTime = Date.now();
let rejected;
await helper.waitForPromise(() => false, 1500)
.catch(() => { rejected = true; });
expect(rejected).to.be(true);
const duration = Date.now() - startTime;
expect(duration).to.be.greaterThan(1490);
});
it('takes an interval and checks on every interval', async function() {
this.timeout(4000);
let checks = 0;
let rejected;
await helper.waitForPromise(() => { checks++; return false; }, 2000, 100)
.catch(() => { rejected = true; });
expect(rejected).to.be(true);
// `checks` is expected to be 20 or 21: one at the beginning, plus 19 or 20 more depending on
// whether it's the timeout or the final poll that wins at 2000ms. Margin is added to reduce
// flakiness on slow test machines.
expect(checks).to.be.greaterThan(17);
expect(checks).to.be.lessThan(24);
});
});
describe("the selectLines method", function(){
// function to support tests, use a single way to represent whitespaces
var cleanText = function(text){
return text
// IE replaces line breaks with a whitespace, so we need to unify its behavior
// for other browsers, to have all tests running for all browsers
.replace(/\n/gi, "")
.replace(/\s/gi, " ");
}
before(function(done){
helper.newPad(function() {
// create some lines to be used on the tests
var $firstLine = helper.padInner$("div").first();
$firstLine.sendkeys("{selectall}some{enter}short{enter}lines{enter}to test{enter}{enter}");
// wait for lines to be split
helper.waitFor(function(){
var $fourthLine = helper.padInner$("div").eq(3);
return $fourthLine.text() === "to test";
}).done(done);
});
this.timeout(60000);
});
it("changes editor selection to be between startOffset of $startLine and endOffset of $endLine", function(done){
var inner$ = helper.padInner$;
var startOffset = 2;
var endOffset = 4;
var $lines = inner$("div");
var $startLine = $lines.eq(1);
var $endLine = $lines.eq(3);
helper.selectLines($startLine, $endLine, startOffset, endOffset);
var selection = inner$.document.getSelection();
/*
* replace() is required here because Firefox keeps the line breaks.
*
* I'm not sure this is ideal behavior of getSelection() where the text
* is not consistent between browsers but that's the situation so that's
* how I'm covering it in this test.
*/
expect(cleanText(selection.toString().replace(/(\r\n|\n|\r)/gm,""))).to.be("ort lines to t");
done();
});
it("ends selection at beginning of $endLine when it is an empty line", function(done){
var inner$ = helper.padInner$;
var startOffset = 2;
var endOffset = 1;
var $lines = inner$("div");
var $startLine = $lines.eq(1);
var $endLine = $lines.eq(4);
helper.selectLines($startLine, $endLine, startOffset, endOffset);
var selection = inner$.document.getSelection();
/*
* replace() is required here because Firefox keeps the line breaks.
*
* I'm not sure this is ideal behavior of getSelection() where the text
* is not consistent between browsers but that's the situation so that's
* how I'm covering it in this test.
*/
expect(cleanText(selection.toString().replace(/(\r\n|\n|\r)/gm,""))).to.be("ort lines to test");
done();
});
it("ends selection at beginning of $endLine when its offset is zero", function(done){
var inner$ = helper.padInner$;
var startOffset = 2;
var endOffset = 0;
var $lines = inner$("div");
var $startLine = $lines.eq(1);
var $endLine = $lines.eq(3);
helper.selectLines($startLine, $endLine, startOffset, endOffset);
var selection = inner$.document.getSelection();
/*
* replace() is required here because Firefox keeps the line breaks.
*
* I'm not sure this is ideal behavior of getSelection() where the text
* is not consistent between browsers but that's the situation so that's
* how I'm covering it in this test.
*/
expect(cleanText(selection.toString().replace(/(\r\n|\n|\r)/gm,""))).to.be("ort lines ");
done();
});
it("selects full line when offset is longer than line content", function(done){
var inner$ = helper.padInner$;
var startOffset = 2;
var endOffset = 50;
var $lines = inner$("div");
var $startLine = $lines.eq(1);
var $endLine = $lines.eq(3);
helper.selectLines($startLine, $endLine, startOffset, endOffset);
var selection = inner$.document.getSelection();
/*
* replace() is required here because Firefox keeps the line breaks.
*
* I'm not sure this is ideal behavior of getSelection() where the text
* is not consistent between browsers but that's the situation so that's
* how I'm covering it in this test.
*/
expect(cleanText(selection.toString().replace(/(\r\n|\n|\r)/gm,""))).to.be("ort lines to test");
done();
});
it("selects all text between beginning of $startLine and end of $endLine when no offset is provided", function(done){
var inner$ = helper.padInner$;
var $lines = inner$("div");
var $startLine = $lines.eq(1);
var $endLine = $lines.eq(3);
helper.selectLines($startLine, $endLine);
var selection = inner$.document.getSelection();
/*
* replace() is required here because Firefox keeps the line breaks.
*
* I'm not sure this is ideal behavior of getSelection() where the text
* is not consistent between browsers but that's the situation so that's
* how I'm covering it in this test.
*/
expect(cleanText(selection.toString().replace(/(\r\n|\n|\r)/gm,""))).to.be("short lines to test");
done();
});
});
describe('helper',function(){
before(function(cb){
helper.newPad(function(){
cb();
})
})
it(".textLines() returns the text of the pad as strings", async function(){
let lines = helper.textLines();
let defaultText = helper.defaultText();
expect(Array.isArray(lines)).to.be(true);
expect(lines[0]).to.be.an('string');
// @todo
// final "\n" is added automatically, but my understanding is this should happen
// only when the default text does not end with "\n" already
expect(lines.join("\n")+"\n").to.equal(defaultText);
})
it(".linesDiv() returns the text of the pad as div elements", async function(){
let lines = helper.linesDiv();
let defaultText = helper.defaultText();
expect(Array.isArray(lines)).to.be(true);
expect(lines[0]).to.be.an('object');
expect(lines[0].text()).to.be.an('string');
_.each(defaultText.split("\n"), function(line, index){
//last line of default text
if(index === lines.length){
expect(line).to.equal('');
} else {
expect(lines[index].text()).to.equal(line);
}
})
})
it(".edit() defaults to send an edit to the first line", async function(){
let firstLine = helper.textLines()[0];
await helper.edit("line")
expect(helper.textLines()[0]).to.be(`line${firstLine}`);
})
it(".edit() to the line specified with parameter lineNo", async function(){
let firstLine = helper.textLines()[0];
await helper.edit("second line", 2);
let text = helper.textLines();
expect(text[0]).to.equal(firstLine);
expect(text[1]).to.equal("second line");
})
it(".edit() supports sendkeys syntax ({selectall},{del},{enter})", async function(){
expect(helper.textLines()[0]).to.not.equal('');
// select first line
helper.linesDiv()[0].sendkeys("{selectall}")
// delete first line
await helper.edit("{del}")
expect(helper.textLines()[0]).to.be('');
let noOfLines = helper.textLines().length;
await helper.edit("{enter}")
expect(helper.textLines().length).to.be(noOfLines+1);
})
})
});

View File

@ -1,237 +0,0 @@
describe("import functionality", function(){
beforeEach(function(cb){
helper.newPad(cb); // creates a new pad
this.timeout(60000);
});
function getinnertext(){
var inner = helper.padInner$
if(!inner){
return ""
}
var newtext = ""
inner("div").each(function(line,el){
newtext += el.innerHTML+"\n"
})
return newtext
}
function importrequest(data,importurl,type){
var success;
var error;
var result = $.ajax({
url: importurl,
type: "post",
processData: false,
async: false,
contentType: 'multipart/form-data; boundary=boundary',
accepts: {
text: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
},
data: 'Content-Type: multipart/form-data; boundary=--boundary\r\n\r\n--boundary\r\nContent-Disposition: form-data; name="file"; filename="import.'+type+'"\r\nContent-Type: text/plain\r\n\r\n' + data + '\r\n\r\n--boundary',
error: function(res){
error = res
}
})
expect(error).to.be(undefined)
return result
}
function exportfunc(link){
var exportresults = []
$.ajaxSetup({
async:false
})
$.get(link+"/export/html",function(data){
var start = data.indexOf("<body>")
var end = data.indexOf("</body>")
var html = data.substr(start+6,end-start-6)
exportresults.push(["html",html])
})
$.get(link+"/export/txt",function(data){
exportresults.push(["txt",data])
})
return exportresults
}
xit("import a pad with newlines from txt", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var textWithNewLines = 'imported text\nnewline'
importrequest(textWithNewLines,importurl,"txt")
helper.waitFor(function(){
return expect(getinnertext()).to.be('<span class="">imported text</span>\n<span class="">newline</span>\n<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be("imported text<br>newline<br><br>")
expect(results[1][1]).to.be("imported text\nnewline\n\n")
done()
})
xit("import a pad with newlines from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithNewLines = '<html><body>htmltext<br/>newline</body></html>'
importrequest(htmlWithNewLines,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('<span class="">htmltext</span>\n<span class="">newline</span>\n<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be("htmltext<br>newline<br><br>")
expect(results[1][1]).to.be("htmltext\nnewline\n\n")
done()
})
xit("import a pad with attributes from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithNewLines = '<html><body>htmltext<br/><span class="b s i u"><b><i><s><u>newline</u></s></i></b></body></html>'
importrequest(htmlWithNewLines,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('<span class="">htmltext</span>\n<span class="b i s u"><b><i><s><u>newline</u></s></i></b></span>\n<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('htmltext<br><strong><em><s><u>newline</u></s></em></strong><br><br>')
expect(results[1][1]).to.be('htmltext\nnewline\n\n')
done()
})
xit("import a pad with bullets from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ul class="list-bullet1"><li>bullet line 1</li><li>bullet line 2</li><ul class="list-bullet2"><li>bullet2 line 1</li><li>bullet2 line 2</li></ul></ul></body></html>'
importrequest(htmlWithBullets,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-bullet1"><li><span class="">bullet line 1</span></li></ul>\n\
<ul class="list-bullet1"><li><span class="">bullet line 2</span></li></ul>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 1</span></li></ul>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 2</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="bullet"><li>bullet line 1</li><li>bullet line 2</li><ul class="bullet"><li>bullet2 line 1</li><li>bullet2 line 2</li></ul></ul><br>')
expect(results[1][1]).to.be('\t* bullet line 1\n\t* bullet line 2\n\t\t* bullet2 line 1\n\t\t* bullet2 line 2\n\n')
done()
})
xit("import a pad with bullets and newlines from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ul class="list-bullet1"><li>bullet line 1</li></ul><br/><ul class="list-bullet1"><li>bullet line 2</li><ul class="list-bullet2"><li>bullet2 line 1</li></ul></ul><br/><ul class="list-bullet1"><ul class="list-bullet2"><li>bullet2 line 2</li></ul></ul></body></html>'
importrequest(htmlWithBullets,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-bullet1"><li><span class="">bullet line 1</span></li></ul>\n\
<br>\n\
<ul class="list-bullet1"><li><span class="">bullet line 2</span></li></ul>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 1</span></li></ul>\n\
<br>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 2</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="bullet"><li>bullet line 1</li></ul><br><ul class="bullet"><li>bullet line 2</li><ul class="bullet"><li>bullet2 line 1</li></ul></ul><br><ul><ul class="bullet"><li>bullet2 line 2</li></ul></ul><br>')
expect(results[1][1]).to.be('\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t* bullet2 line 2\n\n')
done()
})
xit("import a pad with bullets and newlines and attributes from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ul class="list-bullet1"><li>bullet line 1</li></ul><br/><ul class="list-bullet1"><li>bullet line 2</li><ul class="list-bullet2"><li>bullet2 line 1</li></ul></ul><br/><ul class="list-bullet1"><ul class="list-bullet2"><ul class="list-bullet3"><ul class="list-bullet4"><li><span class="b s i u"><b><i><s><u>bullet4 line 2 bisu</u></s></i></b></span></li><li><span class="b s "><b><s>bullet4 line 2 bs</s></b></span></li><li><span class="u"><u>bullet4 line 2 u</u></span><span class="u i s"><i><s><u>uis</u></s></i></span></li></ul></ul></ul></ul></body></html>'
importrequest(htmlWithBullets,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-bullet1"><li><span class="">bullet line 1</span></li></ul>\n\<br>\n\
<ul class="list-bullet1"><li><span class="">bullet line 2</span></li></ul>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 1</span></li></ul>\n<br>\n\
<ul class="list-bullet4"><li><span class="b i s u"><b><i><s><u>bullet4 line 2 bisu</u></s></i></b></span></li></ul>\n\
<ul class="list-bullet4"><li><span class="b s"><b><s>bullet4 line 2 bs</s></b></span></li></ul>\n\
<ul class="list-bullet4"><li><span class="u"><u>bullet4 line 2 u</u></span><span class="i s u"><i><s><u>uis</u></s></i></span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="bullet"><li>bullet line 1</li></ul><br><ul class="bullet"><li>bullet line 2</li><ul class="bullet"><li>bullet2 line 1</li></ul></ul><br><ul><ul><ul><ul class="bullet"><li><strong><em><s><u>bullet4 line 2 bisu</u></s></em></strong></li><li><strong><s>bullet4 line 2 bs</s></strong></li><li><u>bullet4 line 2 u<em><s>uis</s></em></u></li></ul></ul></ul></ul><br>')
expect(results[1][1]).to.be('\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t\t\t* bullet4 line 2 bisu\n\t\t\t\t* bullet4 line 2 bs\n\t\t\t\t* bullet4 line 2 uuis\n\n')
done()
})
xit("import a pad with nested bullets from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ul class="list-bullet1"><li>bullet line 1</li></ul><ul class="list-bullet1"><li>bullet line 2</li><ul class="list-bullet2"><li>bullet2 line 1</li></ul></ul><ul class="list-bullet1"><ul class="list-bullet2"><ul class="list-bullet3"><ul class="list-bullet4"><li>bullet4 line 2</li><li>bullet4 line 2</li><li>bullet4 line 2</li></ul><li>bullet3 line 1</li></ul></ul><li>bullet2 line 1</li></ul></body></html>'
importrequest(htmlWithBullets,importurl,"html")
var oldtext=getinnertext()
helper.waitFor(function(){
return oldtext != getinnertext()
// return expect(getinnertext()).to.be('\
//<ul class="list-bullet1"><li><span class="">bullet line 1</span></li></ul>\n\
//<ul class="list-bullet1"><li><span class="">bullet line 2</span></li></ul>\n\
//<ul class="list-bullet2"><li><span class="">bullet2 line 1</span></li></ul>\n\
//<ul class="list-bullet4"><li><span class="">bullet4 line 2</span></li></ul>\n\
//<ul class="list-bullet4"><li><span class="">bullet4 line 2</span></li></ul>\n\
//<ul class="list-bullet4"><li><span class="">bullet4 line 2</span></li></ul>\n\
//<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="bullet"><li>bullet line 1</li><li>bullet line 2</li><ul class="bullet"><li>bullet2 line 1</li><ul><ul class="bullet"><li>bullet4 line 2</li><li>bullet4 line 2</li><li>bullet4 line 2</li></ul><li>bullet3 line 1</li></ul></ul><li>bullet2 line 1</li></ul><br>')
expect(results[1][1]).to.be('\t* bullet line 1\n\t* bullet line 2\n\t\t* bullet2 line 1\n\t\t\t\t* bullet4 line 2\n\t\t\t\t* bullet4 line 2\n\t\t\t\t* bullet4 line 2\n\t\t\t* bullet3 line 1\n\t* bullet2 line 1\n\n')
done()
})
xit("import a pad with 8 levels of bullets and newlines and attributes from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ul class="list-bullet1"><li>bullet line 1</li></ul><br/><ul class="list-bullet1"><li>bullet line 2</li><ul class="list-bullet2"><li>bullet2 line 1</li></ul></ul><br/><ul class="list-bullet1"><ul class="list-bullet2"><ul class="list-bullet3"><ul class="list-bullet4"><li><span class="b s i u"><b><i><s><u>bullet4 line 2 bisu</u></s></i></b></span></li><li><span class="b s "><b><s>bullet4 line 2 bs</s></b></span></li><li><span class="u"><u>bullet4 line 2 u</u></span><span class="u i s"><i><s><u>uis</u></s></i></span></li><ul class="list-bullet5"><ul class="list-bullet6"><ul class="list-bullet7"><ul class="list-bullet8"><li><span class="">foo</span></li><li><span class="b s"><b><s>foobar bs</b></s></span></li></ul></ul></ul></ul><ul class="list-bullet5"><li>foobar</li></ul></ul></ul></ul></body></html>'
importrequest(htmlWithBullets,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-bullet1"><li><span class="">bullet line 1</span></li></ul>\n\<br>\n\
<ul class="list-bullet1"><li><span class="">bullet line 2</span></li></ul>\n\
<ul class="list-bullet2"><li><span class="">bullet2 line 1</span></li></ul>\n<br>\n\
<ul class="list-bullet4"><li><span class="b i s u"><b><i><s><u>bullet4 line 2 bisu</u></s></i></b></span></li></ul>\n\
<ul class="list-bullet4"><li><span class="b s"><b><s>bullet4 line 2 bs</s></b></span></li></ul>\n\
<ul class="list-bullet4"><li><span class="u"><u>bullet4 line 2 u</u></span><span class="i s u"><i><s><u>uis</u></s></i></span></li></ul>\n\
<ul class="list-bullet8"><li><span class="">foo</span></li></ul>\n\
<ul class="list-bullet8"><li><span class="b s"><b><s>foobar bs</s></b></span></li></ul>\n\
<ul class="list-bullet5"><li><span class="">foobar</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="bullet"><li>bullet line 1</li></ul><br><ul class="bullet"><li>bullet line 2</li><ul class="bullet"><li>bullet2 line 1</li></ul></ul><br><ul><ul><ul><ul class="bullet"><li><strong><em><s><u>bullet4 line 2 bisu</u></s></em></strong></li><li><strong><s>bullet4 line 2 bs</s></strong></li><li><u>bullet4 line 2 u<em><s>uis</s></em></u></li><ul><ul><ul><ul class="bullet"><li>foo</li><li><strong><s>foobar bs</s></strong></li></ul></ul></ul><li>foobar</li></ul></ul></ul></ul></ul><br>')
expect(results[1][1]).to.be('\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t\t\t* bullet4 line 2 bisu\n\t\t\t\t* bullet4 line 2 bs\n\t\t\t\t* bullet4 line 2 uuis\n\t\t\t\t\t\t\t\t* foo\n\t\t\t\t\t\t\t\t* foobar bs\n\t\t\t\t\t* foobar\n\n')
done()
})
xit("import a pad with ordered lists from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ol class="list-number1" start="1"><li>number 1 line 1</li></ol><ol class="list-number1" start="2"><li>number 2 line 2</li></ol></body></html>'
importrequest(htmlWithBullets,importurl,"html")
-console.error(getinnertext())
expect(getinnertext()).to.be('\
<ol class="list-number1" start="1"><li><span class="">number 1 line 1</span></li></ol>\n\
<ol class="list-number1" start="2"><li><span class="">number 2 line 2</span></li></ol>\n\
<br>\n')
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ol class="list-number1" start="1"><li>number 1 line 1</li></ol><ol class="list-number1" start="2"><li>number 2 line 2</li></ol>')
expect(results[1][1]).to.be('')
done()
})
xit("import a pad with ordered lists and newlines from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ol class="list-number1" start="1"><li>number 9 line 1</li></ol><br/><ol class="list-number1" start="2"><li>number 10 line 2</li><ol class="list-number2"><li>number 2 times line 1</li></ol></ol><br/><ol class="list-bullet1"><ol class="list-number2"><li>number 2 times line 2</li></ol></ol></body></html>'
importrequest(htmlWithBullets,importurl,"html")
expect(getinnertext()).to.be('\
<ol class="list-number1" start="1"><li><span class="">number 9 line 1</span></li></ol>\n\
<br>\n\
<ol class="list-number1" start="2"><li><span class="">number 10 line 2</span></li></ol>\n\
<ol class="list-number2"><li><span class="">number 2 times line 1</span></li></ol>\n\
<br>\n\
<ol class="list-number2"><li><span class="">number 2 times line 2</span></li></ol>\n\
<br>\n')
var results = exportfunc(helper.padChrome$.window.location.href)
console.error(results)
done()
})
xit("import a pad with nested ordered lists and attributes and newlines from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithBullets = '<html><body><ol class="list-number1" start="1"><li><span class="b s i u"><b><i><s><u>bold strikethrough italics underline</u></s><i/></b></span> line <span class="b"><b>1bold</b></span></li></ol><br/><span class="i"><i><ol class="list-number1" start="2"><li>number 10 line 2</li><ol class="list-number2"><li>number 2 times line 1</li></ol></ol></i></span><br/><ol class="list-bullet1"><ol class="list-number2"><li>number 2 times line 2</li></ol></ol></body></html>'
importrequest(htmlWithBullets,importurl,"html")
expect(getinnertext()).to.be('\
<ol class="list-number1"><li><span class="b i s u"><b><i><s><u>bold strikethrough italics underline</u></s></i></b></span><span class=""> line </span><span class="b"><b>1bold</b></span></li></ol>\n\
<br>\n\
<ol class="list-number1"><li><span class="i"><i>number 10 line 2</i></span></li></ol>\n\
<ol class="list-number2"><li><span class="i"><i>number 2 times line 1</i></span></li></ol>\n\
<br>\n\
<ol class="list-number2"><li><span class="">number 2 times line 2</span></li></ol>\n\
<br>\n')
var results = exportfunc(helper.padChrome$.window.location.href)
console.error(results)
done()
})
})

View File

@ -1,111 +0,0 @@
describe("import indents functionality", function(){
beforeEach(function(cb){
helper.newPad(cb); // creates a new pad
this.timeout(60000);
});
function getinnertext(){
var inner = helper.padInner$
var newtext = ""
inner("div").each(function(line,el){
newtext += el.innerHTML+"\n"
})
return newtext
}
function importrequest(data,importurl,type){
var success;
var error;
var result = $.ajax({
url: importurl,
type: "post",
processData: false,
async: false,
contentType: 'multipart/form-data; boundary=boundary',
accepts: {
text: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
},
data: 'Content-Type: multipart/form-data; boundary=--boundary\r\n\r\n--boundary\r\nContent-Disposition: form-data; name="file"; filename="import.'+type+'"\r\nContent-Type: text/plain\r\n\r\n' + data + '\r\n\r\n--boundary',
error: function(res){
error = res
}
})
expect(error).to.be(undefined)
return result
}
function exportfunc(link){
var exportresults = []
$.ajaxSetup({
async:false
})
$.get(link+"/export/html",function(data){
var start = data.indexOf("<body>")
var end = data.indexOf("</body>")
var html = data.substr(start+6,end-start-6)
exportresults.push(["html",html])
})
$.get(link+"/export/txt",function(data){
exportresults.push(["txt",data])
})
return exportresults
}
xit("import a pad with indents from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithIndents = '<html><body><ul class="list-indent1"><li>indent line 1</li><li>indent line 2</li><ul class="list-indent2"><li>indent2 line 1</li><li>indent2 line 2</li></ul></ul></body></html>'
importrequest(htmlWithIndents,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-indent1"><li><span class="">indent line 1</span></li></ul>\n\
<ul class="list-indent1"><li><span class="">indent line 2</span></li></ul>\n\
<ul class="list-indent2"><li><span class="">indent2 line 1</span></li></ul>\n\
<ul class="list-indent2"><li><span class="">indent2 line 2</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="indent"><li>indent line 1</li><li>indent line 2</li><ul class="indent"><li>indent2 line 1</li><li>indent2 line 2</li></ul></ul><br>')
expect(results[1][1]).to.be('\tindent line 1\n\tindent line 2\n\t\tindent2 line 1\n\t\tindent2 line 2\n\n')
done()
})
xit("import a pad with indented lists and newlines from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithIndents = '<html><body><ul class="list-indent1"><li>indent line 1</li></ul><br/><ul class="list-indent1"><li>indent 1 line 2</li><ul class="list-indent2"><li>indent 2 times line 1</li></ul></ul><br/><ul class="list-indent1"><ul class="list-indent2"><li>indent 2 times line 2</li></ul></ul></body></html>'
importrequest(htmlWithIndents,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-indent1"><li><span class="">indent line 1</span></li></ul>\n\
<br>\n\
<ul class="list-indent1"><li><span class="">indent 1 line 2</span></li></ul>\n\
<ul class="list-indent2"><li><span class="">indent 2 times line 1</span></li></ul>\n\
<br>\n\
<ul class="list-indent2"><li><span class="">indent 2 times line 2</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="indent"><li>indent line 1</li></ul><br><ul class="indent"><li>indent 1 line 2</li><ul class="indent"><li>indent 2 times line 1</li></ul></ul><br><ul><ul class="indent"><li>indent 2 times line 2</li></ul></ul><br>')
expect(results[1][1]).to.be('\tindent line 1\n\n\tindent 1 line 2\n\t\tindent 2 times line 1\n\n\t\tindent 2 times line 2\n\n')
done()
})
xit("import a pad with 8 levels of indents and newlines and attributes from html", function(done){
var importurl = helper.padChrome$.window.location.href+'/import'
var htmlWithIndents = '<html><body><ul class="list-indent1"><li>indent line 1</li></ul><br/><ul class="list-indent1"><li>indent line 2</li><ul class="list-indent2"><li>indent2 line 1</li></ul></ul><br/><ul class="list-indent1"><ul class="list-indent2"><ul class="list-indent3"><ul class="list-indent4"><li><span class="b s i u"><b><i><s><u>indent4 line 2 bisu</u></s></i></b></span></li><li><span class="b s "><b><s>indent4 line 2 bs</s></b></span></li><li><span class="u"><u>indent4 line 2 u</u></span><span class="u i s"><i><s><u>uis</u></s></i></span></li><ul class="list-indent5"><ul class="list-indent6"><ul class="list-indent7"><ul class="list-indent8"><li><span class="">foo</span></li><li><span class="b s"><b><s>foobar bs</b></s></span></li></ul></ul></ul></ul><ul class="list-indent5"><li>foobar</li></ul></ul></ul></ul></body></html>'
importrequest(htmlWithIndents,importurl,"html")
helper.waitFor(function(){
return expect(getinnertext()).to.be('\
<ul class="list-indent1"><li><span class="">indent line 1</span></li></ul>\n\<br>\n\
<ul class="list-indent1"><li><span class="">indent line 2</span></li></ul>\n\
<ul class="list-indent2"><li><span class="">indent2 line 1</span></li></ul>\n<br>\n\
<ul class="list-indent4"><li><span class="b i s u"><b><i><s><u>indent4 line 2 bisu</u></s></i></b></span></li></ul>\n\
<ul class="list-indent4"><li><span class="b s"><b><s>indent4 line 2 bs</s></b></span></li></ul>\n\
<ul class="list-indent4"><li><span class="u"><u>indent4 line 2 u</u></span><span class="i s u"><i><s><u>uis</u></s></i></span></li></ul>\n\
<ul class="list-indent8"><li><span class="">foo</span></li></ul>\n\
<ul class="list-indent8"><li><span class="b s"><b><s>foobar bs</s></b></span></li></ul>\n\
<ul class="list-indent5"><li><span class="">foobar</span></li></ul>\n\
<br>\n')
})
var results = exportfunc(helper.padChrome$.window.location.href)
expect(results[0][1]).to.be('<ul class="indent"><li>indent line 1</li></ul><br><ul class="indent"><li>indent line 2</li><ul class="indent"><li>indent2 line 1</li></ul></ul><br><ul><ul><ul><ul class="indent"><li><strong><em><s><u>indent4 line 2 bisu</u></s></em></strong></li><li><strong><s>indent4 line 2 bs</s></strong></li><li><u>indent4 line 2 u<em><s>uis</s></em></u></li><ul><ul><ul><ul class="indent"><li>foo</li><li><strong><s>foobar bs</s></strong></li></ul></ul></ul><li>foobar</li></ul></ul></ul></ul></ul><br>')
expect(results[1][1]).to.be('\tindent line 1\n\n\tindent line 2\n\t\tindent2 line 1\n\n\t\t\t\tindent4 line 2 bisu\n\t\t\t\tindent4 line 2 bs\n\t\t\t\tindent4 line 2 uuis\n\t\t\t\t\t\t\t\tfoo\n\t\t\t\t\t\t\t\tfoobar bs\n\t\t\t\t\tfoobar\n\n')
done()
})
})

View File

@ -1,325 +0,0 @@
describe("indentation button", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("indent text with keypress", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var e = inner$.Event(helper.evtType);
e.keyCode = 9; // tab :|
inner$("#innerdocbody").trigger(e);
helper.waitFor(function(){
return inner$("div").first().find("ul li").length === 1;
}).done(done);
});
it("indent text with button", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $indentButton = chrome$(".buttonicon-indent");
$indentButton.click();
helper.waitFor(function(){
return inner$("div").first().find("ul li").length === 1;
}).done(done);
});
it("keeps the indent on enter for the new line", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $indentButton = chrome$(".buttonicon-indent");
$indentButton.click();
//type a bit, make a line break and type again
var $firstTextElement = inner$("div span").first();
$firstTextElement.sendkeys('line 1');
$firstTextElement.sendkeys('{enter}');
$firstTextElement.sendkeys('line 2');
$firstTextElement.sendkeys('{enter}');
helper.waitFor(function(){
return inner$("div span").first().text().indexOf("line 2") === -1;
}).done(function(){
var $newSecondLine = inner$("div").first().next();
var hasULElement = $newSecondLine.find("ul li").length === 1;
expect(hasULElement).to.be(true);
expect($newSecondLine.text()).to.be("line 2");
done();
});
});
it("indents text with spaces on enter if previous line ends with ':', '[', '(', or '{'", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//type a bit, make a line break and type again
var $firstTextElement = inner$("div").first();
$firstTextElement.sendkeys("line with ':'{enter}");
$firstTextElement.sendkeys("line with '['{enter}");
$firstTextElement.sendkeys("line with '('{enter}");
$firstTextElement.sendkeys("line with '{{}'{enter}");
helper.waitFor(function(){
// wait for Etherpad to split four lines into separated divs
var $fourthLine = inner$("div").first().next().next().next();
return $fourthLine.text().indexOf("line with '{'") === 0;
}).done(function(){
// we validate bottom to top for easier implementation
// curly braces
var $lineWithCurlyBraces = inner$("div").first().next().next().next();
$lineWithCurlyBraces.sendkeys('{{}');
pressEnter(); // cannot use sendkeys('{enter}') here, browser does not read the command properly
var $lineAfterCurlyBraces = inner$("div").first().next().next().next().next();
expect($lineAfterCurlyBraces.text()).to.match(/\s{4}/); // tab === 4 spaces
// parenthesis
var $lineWithParenthesis = inner$("div").first().next().next();
$lineWithParenthesis.sendkeys('(');
pressEnter();
var $lineAfterParenthesis = inner$("div").first().next().next().next();
expect($lineAfterParenthesis.text()).to.match(/\s{4}/);
// bracket
var $lineWithBracket = inner$("div").first().next();
$lineWithBracket.sendkeys('[');
pressEnter();
var $lineAfterBracket = inner$("div").first().next().next();
expect($lineAfterBracket.text()).to.match(/\s{4}/);
// colon
var $lineWithColon = inner$("div").first();
$lineWithColon.sendkeys(':');
pressEnter();
var $lineAfterColon = inner$("div").first().next();
expect($lineAfterColon.text()).to.match(/\s{4}/);
done();
});
});
it("appends indentation to the indent of previous line if previous line ends with ':', '[', '(', or '{'", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//type a bit, make a line break and type again
var $firstTextElement = inner$("div").first();
$firstTextElement.sendkeys(" line with some indentation and ':'{enter}");
$firstTextElement.sendkeys("line 2{enter}");
helper.waitFor(function(){
// wait for Etherpad to split two lines into separated divs
var $secondLine = inner$("div").first().next();
return $secondLine.text().indexOf("line 2") === 0;
}).done(function(){
var $lineWithColon = inner$("div").first();
$lineWithColon.sendkeys(':');
pressEnter();
var $lineAfterColon = inner$("div").first().next();
expect($lineAfterColon.text()).to.match(/\s{6}/); // previous line indentation + regular tab (4 spaces)
done();
});
});
it("issue #2772 shows '*' when multiple indented lines receive a style and are outdented", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// make sure pad has more than one line
inner$("div").first().sendkeys("First{enter}Second{enter}");
helper.waitFor(function(){
return inner$("div").first().text().trim() === "First";
}).done(function(){
// indent first 2 lines
var $lines = inner$("div");
var $firstLine = $lines.first();
var $secondLine = $lines.slice(1,2);
helper.selectLines($firstLine, $secondLine);
var $indentButton = chrome$(".buttonicon-indent");
$indentButton.click();
helper.waitFor(function(){
return inner$("div").first().find("ul li").length === 1;
}).done(function(){
// apply bold
var $boldButton = chrome$(".buttonicon-bold");
$boldButton.click();
helper.waitFor(function(){
return inner$("div").first().find("b").length === 1;
}).done(function(){
// outdent first 2 lines
var $outdentButton = chrome$(".buttonicon-outdent");
$outdentButton.click();
helper.waitFor(function(){
return inner$("div").first().find("ul li").length === 0;
}).done(function(){
// check if '*' is displayed
var $secondLine = inner$("div").slice(1,2);
expect($secondLine.text().trim()).to.be("Second");
done();
});
});
});
});
});
/*
it("makes text indented and outdented", function() {
//get the inner iframe
var $inner = testHelper.$getPadInner();
//get the first text element out of the inner iframe
var firstTextElement = $inner.find("div").first();
//select this text element
testHelper.selectText(firstTextElement[0], $inner);
//get the indentation button and click it
var $indentButton = testHelper.$getPadChrome().find(".buttonicon-indent");
$indentButton.click();
//ace creates a new dom element when you press a button, so just get the first text element again
var newFirstTextElement = $inner.find("div").first();
// is there a list-indent class element now?
var firstChild = newFirstTextElement.children(":first");
var isUL = firstChild.is('ul');
//expect it to be the beginning of a list
expect(isUL).to.be(true);
var secondChild = firstChild.children(":first");
var isLI = secondChild.is('li');
//expect it to be part of a list
expect(isLI).to.be(true);
//indent again
$indentButton.click();
var newFirstTextElement = $inner.find("div").first();
// is there a list-indent class element now?
var firstChild = newFirstTextElement.children(":first");
var hasListIndent2 = firstChild.hasClass('list-indent2');
//expect it to be part of a list
expect(hasListIndent2).to.be(true);
//make sure the text hasn't changed
expect(newFirstTextElement.text()).to.eql(firstTextElement.text());
// test outdent
//get the unindentation button and click it twice
var $outdentButton = testHelper.$getPadChrome().find(".buttonicon-outdent");
$outdentButton.click();
$outdentButton.click();
//ace creates a new dom element when you press a button, so just get the first text element again
var newFirstTextElement = $inner.find("div").first();
// is there a list-indent class element now?
var firstChild = newFirstTextElement.children(":first");
var isUL = firstChild.is('ul');
//expect it not to be the beginning of a list
expect(isUL).to.be(false);
var secondChild = firstChild.children(":first");
var isLI = secondChild.is('li');
//expect it to not be part of a list
expect(isLI).to.be(false);
//make sure the text hasn't changed
expect(newFirstTextElement.text()).to.eql(firstTextElement.text());
// Next test tests multiple line indentation
//select this text element
testHelper.selectText(firstTextElement[0], $inner);
//indent twice
$indentButton.click();
$indentButton.click();
//get the first text element out of the inner iframe
var firstTextElement = $inner.find("div").first();
//select this text element
testHelper.selectText(firstTextElement[0], $inner);
/* this test creates the below content, both should have double indentation
line1
line2
firstTextElement.sendkeys('{rightarrow}'); // simulate a keypress of enter
firstTextElement.sendkeys('{enter}'); // simulate a keypress of enter
firstTextElement.sendkeys('line 1'); // simulate writing the first line
firstTextElement.sendkeys('{enter}'); // simulate a keypress of enter
firstTextElement.sendkeys('line 2'); // simulate writing the second line
//get the second text element out of the inner iframe
setTimeout(function(){ // THIS IS REALLY BAD
var secondTextElement = $('iframe').contents().find('iframe').contents().find('iframe').contents().find('body > div').get(1); // THIS IS UGLY
// is there a list-indent class element now?
var firstChild = secondTextElement.children(":first");
var isUL = firstChild.is('ul');
//expect it to be the beginning of a list
expect(isUL).to.be(true);
var secondChild = secondChild.children(":first");
var isLI = secondChild.is('li');
//expect it to be part of a list
expect(isLI).to.be(true);
//get the first text element out of the inner iframe
var thirdTextElement = $('iframe').contents().find('iframe').contents().find('iframe').contents().find('body > div').get(2); // THIS IS UGLY TOO
// is there a list-indent class element now?
var firstChild = thirdTextElement.children(":first");
var isUL = firstChild.is('ul');
//expect it to be the beginning of a list
expect(isUL).to.be(true);
var secondChild = firstChild.children(":first");
var isLI = secondChild.is('li');
//expect it to be part of a list
expect(isLI).to.be(true);
},1000);
});*/
});
function pressEnter(){
var inner$ = helper.padInner$;
var e = inner$.Event(helper.evtType);
e.keyCode = 13; // enter :|
inner$("#innerdocbody").trigger(e);
}

View File

@ -1,67 +0,0 @@
describe("italic some text", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text italic using button", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
//get the bold button and click it
var $boldButton = chrome$(".buttonicon-italic");
$boldButton.click();
//ace creates a new dom element when you press a button, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// is there a <i> element now?
var isItalic = $newFirstTextElement.find("i").length === 1;
//expect it to be bold
expect(isItalic).to.be(true);
//make sure the text hasn't changed
expect($newFirstTextElement.text()).to.eql($firstTextElement.text());
done();
});
it("makes text italic using keypress", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 105; // i
inner$("#innerdocbody").trigger(e);
//ace creates a new dom element when you press a button, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// is there a <i> element now?
var isItalic = $newFirstTextElement.find("i").length === 1;
//expect it to be bold
expect(isItalic).to.be(true);
//make sure the text hasn't changed
expect($newFirstTextElement.text()).to.eql($firstTextElement.text());
done();
});
});

View File

@ -1,135 +0,0 @@
function deletecookie(name) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
describe("Language select and change", function(){
// Destroy language cookies
deletecookie("language", null);
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
// Destroy language cookies
it("makes text german", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $settingsButton = chrome$(".buttonicon-settings");
$settingsButton.click();
//click the language button
var $language = chrome$("#languagemenu");
var $languageoption = $language.find("[value=de]");
//select german
$languageoption.attr('selected','selected');
$language.change();
helper.waitFor(function() {
return chrome$(".buttonicon-bold").parent()[0]["title"] == "Fett (Strg-B)";
})
.done(function(){
//get the value of the bold button
var $boldButton = chrome$(".buttonicon-bold").parent();
//get the title of the bold button
var boldButtonTitle = $boldButton[0]["title"];
//check if the language is now german
expect(boldButtonTitle).to.be("Fett (Strg-B)");
done();
});
});
it("makes text English", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $settingsButton = chrome$(".buttonicon-settings");
$settingsButton.click();
//click the language button
var $language = chrome$("#languagemenu");
//select english
$language.val("en");
$language.change();
//get the value of the bold button
var $boldButton = chrome$(".buttonicon-bold").parent();
helper.waitFor(function() { return $boldButton[0]["title"] != "Fett (Strg+B)";})
.done(function(){
//get the value of the bold button
var $boldButton = chrome$(".buttonicon-bold").parent();
//get the title of the bold button
var boldButtonTitle = $boldButton[0]["title"];
//check if the language is now English
expect(boldButtonTitle).to.be("Bold (Ctrl+B)");
done();
});
});
it("changes direction when picking an rtl lang", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $settingsButton = chrome$(".buttonicon-settings");
$settingsButton.click();
//click the language button
var $language = chrome$("#languagemenu");
var $languageoption = $language.find("[value=ar]");
//select arabic
// $languageoption.attr('selected','selected'); // Breaks the test..
$language.val("ar");
$languageoption.change();
helper.waitFor(function() {
return chrome$("html")[0]["dir"] != 'ltr';
})
.done(function(){
// check if the document's direction was changed
expect(chrome$("html")[0]["dir"]).to.be("rtl");
done();
});
});
it("changes direction when picking an ltr lang", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//click on the settings button to make settings visible
var $settingsButton = chrome$(".buttonicon-settings");
$settingsButton.click();
//click the language button
var $language = chrome$("#languagemenu");
var $languageoption = $language.find("[value=en]");
//select english
//select arabic
$languageoption.attr('selected','selected');
$language.val("en");
$languageoption.change();
helper.waitFor(function() {
return chrome$("html")[0]["dir"] != 'rtl';
})
.done(function(){
// check if the document's direction was changed
expect(chrome$("html")[0]["dir"]).to.be("ltr");
done();
});
});
});

View File

@ -1,51 +0,0 @@
describe('author of pad edition', function() {
// author 1 creates a new pad with some content (regular lines and lists)
before(function(done) {
var padId = helper.newPad(function() {
// make sure pad has at least 3 lines
var $firstLine = helper.padInner$('div').first();
$firstLine.html("Hello World");
// wait for lines to be processed by Etherpad
helper.waitFor(function() {
return $firstLine.text() === 'Hello World';
}).done(function() {
// Reload pad, to make changes as a second user. Need a timeout here to make sure
// all changes were saved before reloading
setTimeout(function() {
// Expire cookie, so author is changed after reloading the pad.
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_4_Reset_the_previous_cookie
helper.padChrome$.document.cookie = 'token=foo;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
helper.newPad(done, padId);
}, 1000);
});
});
this.timeout(60000);
});
// author 2 makes some changes on the pad
it('Clears Authorship by second user', function(done) {
clearAuthorship(done);
});
var clearAuthorship = function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// override the confirm dialogue functioon
helper.padChrome$.window.confirm = function(){
return true;
}
//get the clear authorship colors button and click it
var $clearauthorshipcolorsButton = chrome$(".buttonicon-clearauthorship");
$clearauthorshipcolorsButton.click();
// does the first divs span include an author class?
var hasAuthorClass = inner$("div span").first().attr("class").indexOf("author") !== -1;
expect(hasAuthorClass).to.be(false)
done();
}
});

View File

@ -1,204 +0,0 @@
describe("assign ordered list", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("inserts ordered list text", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist");
$insertorderedlistButton.click();
helper.waitFor(function(){
return inner$("div").first().find("ol li").length === 1;
}).done(done);
});
context('when user presses Ctrl+Shift+N', function() {
context('and pad shortcut is enabled', function() {
beforeEach(function() {
makeSureShortcutIsEnabled('cmdShiftN');
triggerCtrlShiftShortcut('N');
});
it('inserts unordered list', function(done) {
helper.waitFor(function() {
return helper.padInner$('div').first().find('ol li').length === 1;
}).done(done);
});
});
context('and pad shortcut is disabled', function() {
beforeEach(function() {
makeSureShortcutIsDisabled('cmdShiftN');
triggerCtrlShiftShortcut('N');
});
it('does not insert unordered list', function(done) {
helper.waitFor(function() {
return helper.padInner$('div').first().find('ol li').length === 1;
}).done(function() {
expect().fail(function() { return 'Unordered list inserted, should ignore shortcut' });
}).fail(function() {
done();
});
});
});
});
context('when user presses Ctrl+Shift+1', function() {
context('and pad shortcut is enabled', function() {
beforeEach(function() {
makeSureShortcutIsEnabled('cmdShift1');
triggerCtrlShiftShortcut('1');
});
it('inserts unordered list', function(done) {
helper.waitFor(function() {
return helper.padInner$('div').first().find('ol li').length === 1;
}).done(done);
});
});
context('and pad shortcut is disabled', function() {
beforeEach(function() {
makeSureShortcutIsDisabled('cmdShift1');
triggerCtrlShiftShortcut('1');
});
it('does not insert unordered list', function(done) {
helper.waitFor(function() {
return helper.padInner$('div').first().find('ol li').length === 1;
}).done(function() {
expect().fail(function() { return 'Unordered list inserted, should ignore shortcut' });
}).fail(function() {
done();
});
});
});
});
xit("issue #1125 keeps the numbered list on enter for the new line - EMULATES PASTING INTO A PAD", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist");
$insertorderedlistButton.click();
//type a bit, make a line break and type again
var $firstTextElement = inner$("div span").first();
$firstTextElement.sendkeys('line 1');
$firstTextElement.sendkeys('{enter}');
$firstTextElement.sendkeys('line 2');
$firstTextElement.sendkeys('{enter}');
helper.waitFor(function(){
return inner$("div span").first().text().indexOf("line 2") === -1;
}).done(function(){
var $newSecondLine = inner$("div").first().next();
var hasOLElement = $newSecondLine.find("ol li").length === 1;
expect(hasOLElement).to.be(true);
expect($newSecondLine.text()).to.be("line 2");
var hasLineNumber = $newSecondLine.find("ol").attr("start") === 2;
expect(hasLineNumber).to.be(true); // This doesn't work because pasting in content doesn't work
done();
});
});
var triggerCtrlShiftShortcut = function(shortcutChar) {
var inner$ = helper.padInner$;
var e = inner$.Event(helper.evtType);
e.ctrlKey = true;
e.shiftKey = true;
e.which = shortcutChar.toString().charCodeAt(0);
inner$("#innerdocbody").trigger(e);
}
var makeSureShortcutIsDisabled = function(shortcut) {
helper.padChrome$.window.clientVars.padShortcutEnabled[shortcut] = false;
}
var makeSureShortcutIsEnabled = function(shortcut) {
helper.padChrome$.window.clientVars.padShortcutEnabled[shortcut] = true;
}
});
describe("Pressing Tab in an OL increases and decreases indentation", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("indent and de-indent list item with keypress", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist");
$insertorderedlistButton.click();
var e = inner$.Event(helper.evtType);
e.keyCode = 9; // tab
inner$("#innerdocbody").trigger(e);
expect(inner$("div").first().find(".list-number2").length === 1).to.be(true);
e.shiftKey = true; // shift
e.keyCode = 9; // tab
inner$("#innerdocbody").trigger(e);
helper.waitFor(function(){
return inner$("div").first().find(".list-number1").length === 1;
}).done(done);
});
});
describe("Pressing indent/outdent button in an OL increases and decreases indentation and bullet / ol formatting", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("indent and de-indent list item with indent button", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var $insertorderedlistButton = chrome$(".buttonicon-insertorderedlist");
$insertorderedlistButton.click();
var $indentButton = chrome$(".buttonicon-indent");
$indentButton.click(); // make it indented twice
expect(inner$("div").first().find(".list-number2").length === 1).to.be(true);
var $outdentButton = chrome$(".buttonicon-outdent");
$outdentButton.click(); // make it deindented to 1
helper.waitFor(function(){
return inner$("div").first().find(".list-number1").length === 1;
}).done(done);
});
});

View File

@ -1,133 +0,0 @@
describe('Pad modal', function() {
context('when modal is a "force reconnect" message', function() {
var MODAL_SELECTOR = '#connectivity';
beforeEach(function(done) {
helper.newPad(function() {
// force a "slowcommit" error
helper.padChrome$.window.pad.handleChannelStateChange('DISCONNECTED', 'slowcommit');
// wait for modal to be displayed
var $modal = helper.padChrome$(MODAL_SELECTOR);
helper.waitFor(function() {
return $modal.hasClass('popup-show');
}, 50000).done(done);
});
this.timeout(60000);
});
it('disables editor', function(done) {
expect(isEditorDisabled()).to.be(true);
done();
});
context('and user clicks on editor', function() {
beforeEach(function() {
clickOnPadInner();
});
it('does not close the modal', function(done) {
var $modal = helper.padChrome$(MODAL_SELECTOR);
var modalIsVisible = $modal.hasClass('popup-show');
expect(modalIsVisible).to.be(true);
done();
});
});
context('and user clicks on pad outer', function() {
beforeEach(function() {
clickOnPadOuter();
});
it('does not close the modal', function(done) {
var $modal = helper.padChrome$(MODAL_SELECTOR);
var modalIsVisible = $modal.hasClass('popup-show');
expect(modalIsVisible).to.be(true);
done();
});
});
});
// we use "settings" here, but other modals have the same behaviour
context('when modal is not an error message', function() {
var MODAL_SELECTOR = '#settings';
beforeEach(function(done) {
helper.newPad(function() {
openSettingsAndWaitForModalToBeVisible(done);
});
this.timeout(60000);
});
// This test breaks safari testing
/*
it('does not disable editor', function(done) {
expect(isEditorDisabled()).to.be(false);
done();
});
*/
context('and user clicks on editor', function() {
beforeEach(function() {
clickOnPadInner();
});
it('closes the modal', function(done) {
expect(isModalOpened(MODAL_SELECTOR)).to.be(false);
done();
});
});
context('and user clicks on pad outer', function() {
beforeEach(function() {
clickOnPadOuter();
});
it('closes the modal', function(done) {
expect(isModalOpened(MODAL_SELECTOR)).to.be(false);
done();
});
});
});
var clickOnPadInner = function() {
var $editor = helper.padInner$('#innerdocbody');
$editor.click();
}
var clickOnPadOuter = function() {
var $lineNumbersColumn = helper.padOuter$('#sidedivinner');
$lineNumbersColumn.click();
}
var openSettingsAndWaitForModalToBeVisible = function(done) {
helper.padChrome$('.buttonicon-settings').click();
// wait for modal to be displayed
var modalSelector = '#settings';
helper.waitFor(function() {
return isModalOpened(modalSelector);
}, 10000).done(done);
}
var isEditorDisabled = function() {
var editorDocument = helper.padOuter$("iframe[name='ace_inner']").get(0).contentDocument;
var editorBody = editorDocument.getElementById('innerdocbody');
var editorIsDisabled = editorBody.contentEditable === 'false' // IE/Safari
|| editorDocument.designMode === 'off'; // other browsers
return editorIsDisabled;
}
var isModalOpened = function(modalSelector) {
var $modal = helper.padChrome$(modalSelector);
return $modal.hasClass('popup-show');
}
});

View File

@ -1,68 +0,0 @@
describe("undo button then redo button", function(){
beforeEach(function(cb){
helper.newPad(cb); // creates a new pad
this.timeout(60000);
});
it("redo some typing with button", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// get the first text element inside the editable space
var $firstTextElement = inner$("div span").first();
var originalValue = $firstTextElement.text(); // get the original value
var newString = "Foo";
$firstTextElement.sendkeys(newString); // send line 1 to the pad
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
// get undo and redo buttons
var $undoButton = chrome$(".buttonicon-undo");
var $redoButton = chrome$(".buttonicon-redo");
// click the buttons
$undoButton.click(); // removes foo
$redoButton.click(); // resends foo
helper.waitFor(function(){
return inner$("div span").first().text() === newString;
}).done(function(){
var finalValue = inner$("div").first().text();
expect(finalValue).to.be(modifiedValue); // expect the value to change
done();
});
});
it("redo some typing with keypress", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// get the first text element inside the editable space
var $firstTextElement = inner$("div span").first();
var originalValue = $firstTextElement.text(); // get the original value
var newString = "Foo";
$firstTextElement.sendkeys(newString); // send line 1 to the pad
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 90; // z
inner$("#innerdocbody").trigger(e);
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 121; // y
inner$("#innerdocbody").trigger(e);
helper.waitFor(function(){
return inner$("div span").first().text() === newString;
}).done(function(){
var finalValue = inner$("div").first().text();
expect(finalValue).to.be(modifiedValue); // expect the value to change
done();
});
});
});

View File

@ -1,89 +0,0 @@
// Test for https://github.com/ether/etherpad-lite/issues/1763
// This test fails in Opera, IE and Safari
// Opera fails due to a weird way of handling the order of execution, yet actual performance seems fine
// Safari fails due the delay being too great yet the actual performance seems fine
// Firefox might panic that the script is taking too long so will fail
// IE will fail due to running out of memory as it can't fit 2M chars in memory.
// Just FYI Google Docs crashes on large docs whilst trying to Save, it's likely the limitations we are
// experiencing are more to do with browser limitations than improper implementation.
// A ueber fix for this would be to have a separate lower cpu priority thread that handles operations that aren't
// visible to the user.
// Adapted from John McLear's original test case.
xdescribe('Responsiveness of Editor', function() {
// create a new pad before each test run
beforeEach(function(cb) {
helper.newPad(cb);
this.timeout(6000);
});
// JM commented out on 8th Sep 2020 for a release, after release this needs uncommenting
// And the test needs to be fixed to work in Firefox 52 on Windows 7. I am not sure why it fails on this specific platform
// The errors show this.timeout... then crash the browser but I am sure something is actually causing the stack trace and
// I just need to narrow down what, offers to help accepted.
it('Fast response to keypress in pad with large amount of contents', function(done) {
//skip on Windows Firefox 52.0
if(window.bowser && window.bowser.windows && window.bowser.firefox && window.bowser.version == "52.0") {
this.skip();
}
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var chars = '0000000000'; // row of placeholder chars
var amount = 200000; //number of blocks of chars we will insert
var length = (amount * (chars.length) +1); // include a counter for each space
var text = ''; // the text we're gonna insert
this.timeout(amount * 150); // Changed from 100 to 150 to allow Mac OSX Safari to be slow.
// get keys to send
var keyMultiplier = 10; // multiplier * 10 == total number of key events
var keysToSend = '';
for(var i=0; i <= keyMultiplier; i++) {
keysToSend += chars;
}
var textElement = inner$('div');
textElement.sendkeys('{selectall}'); // select all
textElement.sendkeys('{del}'); // clear the pad text
for(var i=0; i <= amount; i++) {
text = text + chars + ' '; // add the chars and space to the text contents
}
inner$('div').first().text(text); // Put the text contents into the pad
helper.waitFor(function(){ // Wait for the new contents to be on the pad
return inner$('div').text().length > length;
}).done(function(){
expect( inner$('div').text().length ).to.be.greaterThan( length ); // has the text changed?
var start = Date.now(); // get the start time
// send some new text to the screen (ensure all 3 key events are sent)
var el = inner$('div').first();
for(var i = 0; i < keysToSend.length; ++i) {
var x = keysToSend.charCodeAt(i);
['keyup', 'keypress', 'keydown'].forEach(function(type) {
var e = $.Event(type);
e.keyCode = x;
el.trigger(e);
});
}
helper.waitFor(function(){ // Wait for the ability to process
var el = inner$('body');
if(el[0].textContent.length > amount) return true;
}).done(function(){
var end = Date.now(); // get the current time
var delay = end - start; // get the delay as the current time minus the start time
expect(delay).to.be.below(600);
done();
}, 5000);
}, 10000);
});
});

View File

@ -1,164 +0,0 @@
describe("select formatting buttons when selection has style applied", function(){
var STYLES = ['italic', 'bold', 'underline', 'strikethrough'];
var SHORTCUT_KEYS = ['I', 'B', 'U', '5']; // italic, bold, underline, strikethrough
var FIRST_LINE = 0;
before(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
var applyStyleOnLine = function(style, line) {
var chrome$ = helper.padChrome$;
selectLine(line);
var $formattingButton = chrome$('.buttonicon-' + style);
$formattingButton.click();
}
var isButtonSelected = function(style) {
var chrome$ = helper.padChrome$;
var $formattingButton = chrome$('.buttonicon-' + style);
return $formattingButton.parent().hasClass('selected');
}
var selectLine = function(lineNumber, offsetStart, offsetEnd) {
var inner$ = helper.padInner$;
var $line = inner$("div").eq(lineNumber);
helper.selectLines($line, $line, offsetStart, offsetEnd);
}
var placeCaretOnLine = function(lineNumber) {
var inner$ = helper.padInner$;
var $line = inner$("div").eq(lineNumber);
$line.sendkeys('{leftarrow}');
}
var undo = function() {
var $undoButton = helper.padChrome$(".buttonicon-undo");
$undoButton.click();
}
var testIfFormattingButtonIsDeselected = function(style) {
it('deselects the ' + style + ' button', function(done) {
helper.waitFor(function(){
return isButtonSelected(style) === false;
}).done(done)
});
}
var testIfFormattingButtonIsSelected = function(style) {
it('selects the ' + style + ' button', function(done) {
helper.waitFor(function(){
return isButtonSelected(style);
}).done(done)
});
}
var applyStyleOnLineAndSelectIt = function(line, style, cb) {
applyStyleOnLineOnFullLineAndRemoveSelection(line, style, selectLine, cb);
}
var applyStyleOnLineAndPlaceCaretOnit = function(line, style, cb) {
applyStyleOnLineOnFullLineAndRemoveSelection(line, style, placeCaretOnLine, cb);
}
var applyStyleOnLineOnFullLineAndRemoveSelection = function(line, style, selectTarget, cb) {
// see if line html has changed
var inner$ = helper.padInner$;
var oldLineHTML = inner$.find("div")[line];
applyStyleOnLine(style, line);
helper.waitFor(function(){
var lineHTML = inner$.find("div")[line];
return lineHTML !== oldLineHTML;
});
// remove selection from previous line
selectLine(line + 1);
//setTimeout(function() {
// select the text or place the caret on a position that
// has the formatting text applied previously
selectTarget(line);
cb();
//}, 1000);
}
var pressFormattingShortcutOnSelection = function(key) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = key.charCodeAt(0); // I, U, B, 5
inner$("#innerdocbody").trigger(e);
}
STYLES.forEach(function(style){
context('when selection is in a text with ' + style + ' applied', function(){
before(function (done) {
this.timeout(4000);
applyStyleOnLineAndSelectIt(FIRST_LINE, style, done);
});
after(function () {
undo();
});
testIfFormattingButtonIsSelected(style);
});
context('when caret is in a position with ' + style + ' applied', function(){
before(function (done) {
this.timeout(4000);
applyStyleOnLineAndPlaceCaretOnit(FIRST_LINE, style, done);
});
after(function () {
undo();
});
testIfFormattingButtonIsSelected(style)
});
});
context('when user applies a style and the selection does not change', function() {
var style = STYLES[0]; // italic
before(function () {
applyStyleOnLine(style, FIRST_LINE);
});
// clean the style applied
after(function () {
applyStyleOnLine(style, FIRST_LINE);
});
it('selects the style button', function (done) {
expect(isButtonSelected(style)).to.be(true);
done();
});
});
SHORTCUT_KEYS.forEach(function(key, index){
var styleOfTheShortcut = STYLES[index]; // italic, bold, ...
context('when user presses CMD + ' + key, function() {
before(function () {
pressFormattingShortcutOnSelection(key);
});
testIfFormattingButtonIsSelected(styleOfTheShortcut);
context('and user presses CMD + ' + key + ' again', function() {
before(function () {
pressFormattingShortcutOnSelection(key);
});
testIfFormattingButtonIsDeselected(styleOfTheShortcut);
});
});
});
});

View File

@ -1,36 +0,0 @@
describe("strikethrough button", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("makes text strikethrough", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
//get the strikethrough button and click it
var $strikethroughButton = chrome$(".buttonicon-strikethrough");
$strikethroughButton.click();
//ace creates a new dom element when you press a button, so just get the first text element again
var $newFirstTextElement = inner$("div").first();
// is there a <i> element now?
var isstrikethrough = $newFirstTextElement.find("s").length === 1;
//expect it to be strikethrough
expect(isstrikethrough).to.be(true);
//make sure the text hasn't changed
expect($newFirstTextElement.text()).to.eql($firstTextElement.text());
done();
});
});

View File

@ -1,47 +0,0 @@
//deactivated, we need a nice way to get the timeslider, this is ugly
xdescribe("timeslider button takes you to the timeslider of a pad", function(){
beforeEach(function(cb){
helper.newPad(cb); // creates a new pad
this.timeout(60000);
});
it("timeslider contained in URL", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// get the first text element inside the editable space
var $firstTextElement = inner$("div span").first();
var originalValue = $firstTextElement.text(); // get the original value
var newValue = "Testing"+originalValue;
$firstTextElement.sendkeys("Testing"); // send line 1 to the pad
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
helper.waitFor(function(){
return modifiedValue !== originalValue; // The value has changed so we can..
}).done(function(){
var $timesliderButton = chrome$("#timesliderlink");
$timesliderButton.click(); // So click the timeslider link
helper.waitFor(function(){
var iFrameURL = chrome$.window.location.href;
if(iFrameURL){
return iFrameURL.indexOf("timeslider") !== -1;
}else{
return false; // the URL hasnt been set yet
}
}).done(function(){
// click the buttons
var iFrameURL = chrome$.window.location.href; // get the url
var inTimeslider = iFrameURL.indexOf("timeslider") !== -1;
expect(inTimeslider).to.be(true); // expect the value to change
done();
});
});
});
});

View File

@ -1,120 +0,0 @@
describe("timeslider follow", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
});
it("content as it's added to timeslider", async function() {
// send 6 revisions
let revs = 6;
let message = 'a\n\n\n\n\n\n\n\n\n\n';
let newLines = message.split('\n').length
for (let i=0;i<revs;i++){
await helper.edit(message, newLines*i + 1);
}
await helper.gotoTimeslider(0);
await helper.waitForPromise(function(){return helper.contentWindow().location.hash === '#0'})
let originalTop = helper.contentWindow().$('#innerdocbody').offset();
// set to follow contents as it arrives
helper.contentWindow().$('#options-followContents').prop("checked", true);
helper.contentWindow().$('#playpause_button_icon').click();
let newTop;
return helper.waitForPromise(function(){
newTop = helper.contentWindow().$('#innerdocbody').offset();
return newTop.top < originalTop.top;
})
});
/**
* Tests for bug described in #4389
* The goal is to scroll to the first line that contains a change right before
* the change is applied.
*
*/
it("only to lines that exist in the current pad view, see #4389", async function(){
// Select everything and clear via delete key
let e = helper.padInner$.Event(helper.evtType);
e.keyCode = 8; //delete key
let lines = helper.linesDiv();
helper.selectLines(lines[0], lines[lines.length - 1]); // select all lines
// probably unnecessary, but wait for the selection to be Range not Caret
await helper.waitForPromise(function(){
return !helper.padInner$.document.getSelection().isCollapsed;
//only supported in FF57+
//return helper.padInner$.document.getSelection().type === 'Range';
})
helper.padInner$('#innerdocbody').trigger(e);
await helper.waitForPromise(function(){
return helper.commits.length === 1;
})
await helper.edit("Test line\n\n")
await helper.edit("Another test line", 3)
await helper.gotoTimeslider();
// set to follow contents as it arrives
helper.contentWindow().$('#options-followContents').prop("checked", true);
let oldYPosition = helper.contentWindow().$("#editorcontainerbox")[0].scrollTop;
expect(oldYPosition).to.be(0);
/**
* pad content rev 0 [default Pad text]
* pad content rev 1 ['']
* pad content rev 2 ['Test line','','']
* pad content rev 3 ['Test line','','Another test line']
*/
// line 3 changed
helper.contentWindow().$('#leftstep').click();
await helper.waitForPromise(function(){
return hasFollowedToLine(3);
})
// line 1 is the first line that changed
helper.contentWindow().$('#leftstep').click();
await helper.waitForPromise(function(){
return hasFollowedToLine(1);
})
// line 1 changed
helper.contentWindow().$('#leftstep').click();
await helper.waitForPromise(function(){
return hasFollowedToLine(1);
})
// line 1 changed
helper.contentWindow().$('#rightstep').click();
await helper.waitForPromise(function(){
return hasFollowedToLine(1);
})
// line 1 is the first line that changed
helper.contentWindow().$('#rightstep').click();
await helper.waitForPromise(function(){
return hasFollowedToLine(1);
})
// line 3 changed
helper.contentWindow().$('#rightstep').click();
return helper.waitForPromise(function(){
return hasFollowedToLine(3);
})
})
});
/**
* @param {number} lineNum
* @returns {boolean} scrolled to the lineOffset?
*/
function hasFollowedToLine(lineNum) {
let scrollPosition = helper.contentWindow().$("#editorcontainerbox")[0].scrollTop;
let lineOffset = helper.contentWindow().$('#innerdocbody').find(`div:nth-child(${lineNum})`)[0].offsetTop;
return Math.abs(scrollPosition - lineOffset) < 1;
}

View File

@ -1,62 +0,0 @@
describe("timeslider", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
});
/**
* @todo test authorsList
*/
it("Shows a date and time in the timeslider and make sure it doesn't include NaN", async function() {
// make some changes to produce 3 revisions
let revs = 3;
for(let i=0; i < revs; i++) {
await helper.edit('a\n');
}
await helper.gotoTimeslider(revs);
await helper.waitForPromise(function(){return helper.contentWindow().location.hash === '#'+revs})
// the datetime of last edit
let timerTimeLast = new Date(helper.timesliderTimerTime()).getTime();
// the day of this revision, e.g. August 12, 2020 (stripped the string "Saved")
let dateLast = new Date(helper.revisionDateElem().substr(6)).getTime();
// the label/revision, ie Version 3
let labelLast = helper.revisionLabelElem().text();
// the datetime should be a date
expect( Number.isNaN(timerTimeLast)).to.eql(false);
// the Date object of the day should not be NaN
expect( Number.isNaN(dateLast) ).to.eql(false)
// the label should be Version `Number`
expect(labelLast).to.be(`Version ${revs}`);
// Click somewhere left on the timeslider to go to revision 0
helper.sliderClick(1);
// the datetime of last edit
let timerTime = new Date(helper.timesliderTimerTime()).getTime();
// the day of this revision, e.g. August 12, 2020
let date = new Date(helper.revisionDateElem().substr(6)).getTime();
// the label/revision, e.g. Version 0
let label = helper.revisionLabelElem().text();
// the datetime should be a date
expect( Number.isNaN(timerTime)).to.eql(false);
// the last revision should be newer or have the same time
expect(timerTimeLast).to.not.be.lessThan(timerTime);
// the Date object of the day should not be NaN
expect( Number.isNaN(date) ).to.eql(false)
// the label should be Version 0
expect( label ).to.be('Version 0');
});
});

View File

@ -1,29 +0,0 @@
describe("timeslider", function(){
var padId = 735773577357+(Math.round(Math.random()*1000));
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb, padId);
});
it("Makes sure the export URIs are as expected when the padID is numeric", async function() {
await helper.edit('a\n');
await helper.gotoTimeslider(1);
// ensure we are on revision 1
await helper.waitForPromise(function(){return helper.contentWindow().location.hash === '#1'})
// expect URI to be similar to
// http://192.168.1.48:9001/p/2/1/export/html
// http://192.168.1.48:9001/p/735773577399/1/export/html
let rev1ExportLink = helper.contentWindow().$('#exporthtmla').attr('href');
expect(rev1ExportLink).to.contain('/1/export/html');
// Click somewhere left on the timeslider to go to revision 0
helper.sliderClick(30);
let rev0ExportLink = helper.contentWindow().$('#exporthtmla').attr('href');
expect(rev0ExportLink).to.contain('/0/export/html');
});
});

View File

@ -1,181 +0,0 @@
describe("timeslider", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("loads adds a hundred revisions", function(done) { // passes
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// make some changes to produce 100 revisions
var timePerRev = 900
, revs = 99;
this.timeout(revs*timePerRev+10000);
for(var i=0; i < revs; i++) {
setTimeout(function() {
// enter 'a' in the first text element
inner$("div").first().sendkeys('a');
}, timePerRev*i);
}
chrome$('.buttonicon-savedRevision').click();
setTimeout(function() {
// go to timeslider
$('#iframe-container iframe').attr('src', $('#iframe-container iframe').attr('src')+'/timeslider');
setTimeout(function() {
var timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
var $sliderBar = timeslider$('#ui-slider-bar');
var latestContents = timeslider$('#innerdocbody').text();
// Click somewhere on the timeslider
var e = new jQuery.Event('mousedown');
// sets y co-ordinate of the pad slider modal.
var base = (timeslider$('#ui-slider-bar').offset().top - 24)
e.clientX = e.pageX = 150;
e.clientY = e.pageY = base+5;
$sliderBar.trigger(e);
e = new jQuery.Event('mousedown');
e.clientX = e.pageX = 150;
e.clientY = e.pageY = base;
$sliderBar.trigger(e);
e = new jQuery.Event('mousedown');
e.clientX = e.pageX = 150;
e.clientY = e.pageY = base-5;
$sliderBar.trigger(e);
$sliderBar.trigger('mouseup')
setTimeout(function() {
//make sure the text has changed
expect( timeslider$('#innerdocbody').text() ).not.to.eql( latestContents );
var starIsVisible = timeslider$('.star').is(":visible");
expect( starIsVisible ).to.eql( true );
done();
}, 1000);
}, 6000);
}, revs*timePerRev);
});
// Disabled as jquery trigger no longer works properly
xit("changes the url when clicking on the timeslider", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// make some changes to produce 7 revisions
var timePerRev = 1000
, revs = 20;
this.timeout(revs*timePerRev+10000);
for(var i=0; i < revs; i++) {
setTimeout(function() {
// enter 'a' in the first text element
inner$("div").first().sendkeys('a');
}, timePerRev*i);
}
setTimeout(function() {
// go to timeslider
$('#iframe-container iframe').attr('src', $('#iframe-container iframe').attr('src')+'/timeslider');
setTimeout(function() {
var timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
var $sliderBar = timeslider$('#ui-slider-bar');
var latestContents = timeslider$('#innerdocbody').text();
var oldUrl = $('#iframe-container iframe')[0].contentWindow.location.hash;
// Click somewhere on the timeslider
var e = new jQuery.Event('mousedown');
e.clientX = e.pageX = 150;
e.clientY = e.pageY = 60;
$sliderBar.trigger(e);
helper.waitFor(function(){
return $('#iframe-container iframe')[0].contentWindow.location.hash != oldUrl;
}, 6000).always(function(){
expect( $('#iframe-container iframe')[0].contentWindow.location.hash ).not.to.eql( oldUrl );
done();
});
}, 6000);
}, revs*timePerRev);
});
it("jumps to a revision given in the url", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
this.timeout(40000);
// wait for the text to be loaded
helper.waitFor(function(){
return inner$('body').text().length != 0;
}, 10000).always(function() {
var newLines = inner$('body div').length;
var oldLength = inner$('body').text().length + newLines / 2;
expect( oldLength ).to.not.eql( 0 );
inner$("div").first().sendkeys('a');
var timeslider$;
// wait for our additional revision to be added
helper.waitFor(function(){
// newLines takes the new lines into account which are strippen when using
// inner$('body').text(), one <div> is used for one line in ACE.
var lenOkay = inner$('body').text().length + newLines / 2 != oldLength;
// this waits for the color to be added to our <span>, which means that the revision
// was accepted by the server.
var colorOkay = inner$('span').first().attr('class').indexOf("author-") == 0;
return lenOkay && colorOkay;
}, 10000).always(function() {
// go to timeslider with a specific revision set
$('#iframe-container iframe').attr('src', $('#iframe-container iframe').attr('src')+'/timeslider#0');
// wait for the timeslider to be loaded
helper.waitFor(function(){
try {
timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
} catch(e){}
if(timeslider$){
return timeslider$('#innerdocbody').text().length == oldLength;
}
}, 10000).always(function(){
expect( timeslider$('#innerdocbody').text().length ).to.eql( oldLength );
done();
});
});
});
});
it("checks the export url", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
this.timeout(11000);
inner$("div").first().sendkeys('a');
setTimeout(function() {
// go to timeslider
$('#iframe-container iframe').attr('src', $('#iframe-container iframe').attr('src')+'/timeslider#0');
var timeslider$;
var exportLink;
helper.waitFor(function(){
try{
timeslider$ = $('#iframe-container iframe')[0].contentWindow.$;
}catch(e){}
if(!timeslider$)
return false;
exportLink = timeslider$('#exportplaina').attr('href');
if(!exportLink)
return false;
return exportLink.substr(exportLink.length - 12) == "0/export/txt";
}, 6000).always(function(){
expect( exportLink.substr(exportLink.length - 12) ).to.eql( "0/export/txt" );
done();
});
}, 2500);
});
});

View File

@ -1,61 +0,0 @@
describe("undo button", function(){
beforeEach(function(cb){
helper.newPad(cb); // creates a new pad
this.timeout(60000);
});
it("undo some typing by clicking undo button", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// get the first text element inside the editable space
var $firstTextElement = inner$("div span").first();
var originalValue = $firstTextElement.text(); // get the original value
$firstTextElement.sendkeys("foo"); // send line 1 to the pad
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
// get clear authorship button as a variable
var $undoButton = chrome$(".buttonicon-undo");
// click the button
$undoButton.click();
helper.waitFor(function(){
return inner$("div span").first().text() === originalValue;
}).done(function(){
var finalValue = inner$("div span").first().text();
expect(finalValue).to.be(originalValue); // expect the value to change
done();
});
});
it("undo some typing using a keypress", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
// get the first text element inside the editable space
var $firstTextElement = inner$("div span").first();
var originalValue = $firstTextElement.text(); // get the original value
$firstTextElement.sendkeys("foo"); // send line 1 to the pad
var modifiedValue = $firstTextElement.text(); // get the modified value
expect(modifiedValue).not.to.be(originalValue); // expect the value to change
var e = inner$.Event(helper.evtType);
e.ctrlKey = true; // Control key
e.which = 90; // z
inner$("#innerdocbody").trigger(e);
helper.waitFor(function(){
return inner$("div span").first().text() === originalValue;
}).done(function(){
var finalValue = inner$("div span").first().text();
expect(finalValue).to.be(originalValue); // expect the value to change
done();
});
});
});

View File

@ -1,177 +0,0 @@
describe("assign unordered list", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("insert unordered list text then removes by outdent", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var originalText = inner$("div").first().text();
var $insertunorderedlistButton = chrome$(".buttonicon-insertunorderedlist");
$insertunorderedlistButton.click();
helper.waitFor(function(){
var newText = inner$("div").first().text();
if(newText === originalText){
return inner$("div").first().find("ul li").length === 1;
}
}).done(function(){
// remove indentation by bullet and ensure text string remains the same
chrome$(".buttonicon-outdent").click();
helper.waitFor(function(){
var newText = inner$("div").first().text();
return (newText === originalText);
}).done(function(){
done();
});
});
});
});
describe("unassign unordered list", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("insert unordered list text then remove by clicking list again", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var originalText = inner$("div").first().text();
var $insertunorderedlistButton = chrome$(".buttonicon-insertunorderedlist");
$insertunorderedlistButton.click();
helper.waitFor(function(){
var newText = inner$("div").first().text();
if(newText === originalText){
return inner$("div").first().find("ul li").length === 1;
}
}).done(function(){
// remove indentation by bullet and ensure text string remains the same
$insertunorderedlistButton.click();
helper.waitFor(function(){
var isList = inner$("div").find("ul").length === 1;
// sohuldn't be list
return (isList === false);
}).done(function(){
done();
});
});
});
});
describe("keep unordered list on enter key", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("Keeps the unordered list on enter for the new line", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
var $insertorderedlistButton = chrome$(".buttonicon-insertunorderedlist");
$insertorderedlistButton.click();
//type a bit, make a line break and type again
var $firstTextElement = inner$("div span").first();
$firstTextElement.sendkeys('line 1');
$firstTextElement.sendkeys('{enter}');
$firstTextElement.sendkeys('line 2');
$firstTextElement.sendkeys('{enter}');
helper.waitFor(function(){
return inner$("div span").first().text().indexOf("line 2") === -1;
}).done(function(){
var $newSecondLine = inner$("div").first().next();
var hasULElement = $newSecondLine.find("ul li").length === 1;
expect(hasULElement).to.be(true);
expect($newSecondLine.text()).to.be("line 2");
done();
});
});
});
describe("Pressing Tab in an UL increases and decreases indentation", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("indent and de-indent list item with keypress", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var $insertorderedlistButton = chrome$(".buttonicon-insertunorderedlist");
$insertorderedlistButton.click();
var e = inner$.Event(helper.evtType);
e.keyCode = 9; // tab
inner$("#innerdocbody").trigger(e);
expect(inner$("div").first().find(".list-bullet2").length === 1).to.be(true);
e.shiftKey = true; // shift
e.keyCode = 9; // tab
inner$("#innerdocbody").trigger(e);
helper.waitFor(function(){
return inner$("div").first().find(".list-bullet1").length === 1;
}).done(done);
});
});
describe("Pressing indent/outdent button in an UL increases and decreases indentation and bullet / ol formatting", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("indent and de-indent list item with indent button", function(done){
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var $firstTextElement = inner$("div").first();
//select this text element
$firstTextElement.sendkeys('{selectall}');
var $insertunorderedlistButton = chrome$(".buttonicon-insertunorderedlist");
$insertunorderedlistButton.click();
var $indentButton = chrome$(".buttonicon-indent");
$indentButton.click(); // make it indented twice
expect(inner$("div").first().find(".list-bullet2").length === 1).to.be(true);
var $outdentButton = chrome$(".buttonicon-outdent");
$outdentButton.click(); // make it deindented to 1
helper.waitFor(function(){
return inner$("div").first().find(".list-bullet1").length === 1;
}).done(done);
});
});

View File

@ -1,70 +0,0 @@
describe("urls", function(){
//create a new pad before each test run
beforeEach(function(cb){
helper.newPad(cb);
this.timeout(60000);
});
it("when you enter an url, it becomes clickable", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var firstTextElement = inner$("div").first();
// simulate key presses to delete content
firstTextElement.sendkeys('{selectall}'); // select all
firstTextElement.sendkeys('{del}'); // clear the first line
firstTextElement.sendkeys('https://etherpad.org'); // insert a URL
helper.waitFor(function(){
return inner$("div").first().find("a").length === 1;
}, 2000).done(done);
});
it("when you enter a url containing a !, it becomes clickable and contains the whole URL", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var firstTextElement = inner$("div").first();
var url = "https://etherpad.org/!foo";
// simulate key presses to delete content
firstTextElement.sendkeys('{selectall}'); // select all
firstTextElement.sendkeys('{del}'); // clear the first line
firstTextElement.sendkeys(url); // insert a URL
helper.waitFor(function(){
if(inner$("div").first().find("a").length === 1){ // if it contains an A link
if(inner$("div").first().find("a")[0].href === url){
return true;
}
};
}, 2000).done(done);
});
it("when you enter a url followed by a ], the ] is not included in the URL", function(done) {
var inner$ = helper.padInner$;
var chrome$ = helper.padChrome$;
//get the first text element out of the inner iframe
var firstTextElement = inner$("div").first();
var url = "https://etherpad.org/";
// simulate key presses to delete content
firstTextElement.sendkeys('{selectall}'); // select all
firstTextElement.sendkeys('{del}'); // clear the first line
firstTextElement.sendkeys(url); // insert a URL
firstTextElement.sendkeys(']'); // put a ] after it
helper.waitFor(function(){
if(inner$("div").first().find("a").length === 1){ // if it contains an A link
if(inner$("div").first().find("a")[0].href === url){
return true;
}
};
}, 2000).done(done);
});
});

View File

@ -1,71 +0,0 @@
describe('Automatic pad reload on Force Reconnect message', function() {
var padId, $originalPadFrame;
beforeEach(function(done) {
padId = helper.newPad(function() {
// enable userdup error to have timer to force reconnect
var $errorMessageModal = helper.padChrome$('#connectivity .userdup');
$errorMessageModal.addClass('with_reconnect_timer');
// make sure there's a timeout set, otherwise automatic reconnect won't be enabled
helper.padChrome$.window.clientVars.automaticReconnectionTimeout = 2;
// open same pad on another iframe, to force userdup error
var $otherIframeWithSamePad = $('<iframe src="/p/' + padId + '" style="height: 1px;"></iframe>');
$originalPadFrame = $('#iframe-container iframe');
$otherIframeWithSamePad.insertAfter($originalPadFrame);
// wait for modal to be displayed
helper.waitFor(function() {
return $errorMessageModal.is(':visible');
}, 50000).done(done);
});
this.timeout(60000);
});
it('displays a count down timer to automatically reconnect', function(done) {
var $errorMessageModal = helper.padChrome$('#connectivity .userdup');
var $countDownTimer = $errorMessageModal.find('.reconnecttimer');
expect($countDownTimer.is(':visible')).to.be(true);
done();
});
context('and user clicks on Cancel', function() {
beforeEach(function() {
var $errorMessageModal = helper.padChrome$('#connectivity .userdup');
$errorMessageModal.find('#cancelreconnect').click();
});
it('does not show Cancel button nor timer anymore', function(done) {
var $errorMessageModal = helper.padChrome$('#connectivity .userdup');
var $countDownTimer = $errorMessageModal.find('.reconnecttimer');
var $cancelButton = $errorMessageModal.find('#cancelreconnect');
expect($countDownTimer.is(':visible')).to.be(false);
expect($cancelButton.is(':visible')).to.be(false);
done();
});
});
context('and user does not click on Cancel until timer expires', function() {
var padWasReloaded = false;
beforeEach(function() {
$originalPadFrame.one('load', function() {
padWasReloaded = true;
});
});
it('reloads the pad', function(done) {
helper.waitFor(function() {
return padWasReloaded;
}, 5000).done(done);
this.timeout(5000);
});
});
});