mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-20 06:29:53 +01:00
c222fc5d0b
There are a few problems with sleeping before checking the condition for the first time: * It slows down tests. * The predicate is never checked if the interval duration is greater than the timeout. * 0 can't be used to test if the condition is currently true. There is a minor disadvantage to sleeping before checking: It will cause more tests to run without an asynchronous interruption, which could theoretically mask some async bugs.
371 lines
13 KiB
JavaScript
371 lines
13 KiB
JavaScript
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(1400);
|
|
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(){
|
|
expect(checks).to.be.greaterThan(10);
|
|
expect(checks).to.be.lessThan(30);
|
|
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 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();
|
|
});
|
|
});
|
|
});
|