mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-04-22 00:16:15 -04:00
restructure: move bin/ and tests/ to src/
Also add symlinks from the old `bin/` and `tests/` locations to avoid breaking scripts and other tools. Motivations: * Scripts and tests no longer have to do dubious things like: require('ep_etherpad-lite/node_modules/foo') to access packages installed as dependencies in `src/package.json`. * Plugins can access the backend test helper library in a non-hacky way: require('ep_etherpad-lite/tests/backend/common') * We can delete the top-level `package.json` without breaking our ability to lint the files in `bin/` and `tests/`. Deleting the top-level `package.json` has downsides: It will cause `npm` to print warnings whenever plugins are installed, npm will no longer be able to enforce a plugin's peer dependency on ep_etherpad-lite, and npm will keep deleting the `node_modules/ep_etherpad-lite` symlink that points to `../src`. But there are significant upsides to deleting the top-level `package.json`: It will drastically speed up plugin installation because `npm` doesn't have to recursively walk the dependencies in `src/package.json`. Also, deleting the top-level `package.json` avoids npm's horrible dependency hoisting behavior (where it moves stuff from `src/node_modules/` to the top-level `node_modules/` directory). Dependency hoisting causes numerous mysterious problems such as silent failures in `npm outdated` and `npm update`. Dependency hoisting also breaks plugins that do: require('ep_etherpad-lite/node_modules/foo')
This commit is contained in:
parent
efde0b787a
commit
2ea8ea1275
146 changed files with 191 additions and 1161 deletions
|
@ -1,161 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
describe('select formatting buttons when selection has style applied', function () {
|
||||
const STYLES = ['italic', 'bold', 'underline', 'strikethrough'];
|
||||
const SHORTCUT_KEYS = ['I', 'B', 'U', '5']; // italic, bold, underline, strikethrough
|
||||
const FIRST_LINE = 0;
|
||||
|
||||
before(function (cb) {
|
||||
helper.newPad(cb);
|
||||
this.timeout(60000);
|
||||
});
|
||||
|
||||
const applyStyleOnLine = function (style, line) {
|
||||
const chrome$ = helper.padChrome$;
|
||||
selectLine(line);
|
||||
const $formattingButton = chrome$(`.buttonicon-${style}`);
|
||||
$formattingButton.click();
|
||||
};
|
||||
|
||||
const isButtonSelected = function (style) {
|
||||
const chrome$ = helper.padChrome$;
|
||||
const $formattingButton = chrome$(`.buttonicon-${style}`);
|
||||
return $formattingButton.parent().hasClass('selected');
|
||||
};
|
||||
|
||||
const selectLine = function (lineNumber, offsetStart, offsetEnd) {
|
||||
const inner$ = helper.padInner$;
|
||||
const $line = inner$('div').eq(lineNumber);
|
||||
helper.selectLines($line, $line, offsetStart, offsetEnd);
|
||||
};
|
||||
|
||||
const placeCaretOnLine = function (lineNumber) {
|
||||
const inner$ = helper.padInner$;
|
||||
const $line = inner$('div').eq(lineNumber);
|
||||
$line.sendkeys('{leftarrow}');
|
||||
};
|
||||
|
||||
const undo = function () {
|
||||
const $undoButton = helper.padChrome$('.buttonicon-undo');
|
||||
$undoButton.click();
|
||||
};
|
||||
|
||||
const testIfFormattingButtonIsDeselected = function (style) {
|
||||
it(`deselects the ${style} button`, function (done) {
|
||||
helper.waitFor(() => isButtonSelected(style) === false).done(done);
|
||||
});
|
||||
};
|
||||
|
||||
const testIfFormattingButtonIsSelected = function (style) {
|
||||
it(`selects the ${style} button`, function (done) {
|
||||
helper.waitFor(() => isButtonSelected(style)).done(done);
|
||||
});
|
||||
};
|
||||
|
||||
const applyStyleOnLineAndSelectIt = function (line, style, cb) {
|
||||
applyStyleOnLineOnFullLineAndRemoveSelection(line, style, selectLine, cb);
|
||||
};
|
||||
|
||||
const applyStyleOnLineAndPlaceCaretOnit = function (line, style, cb) {
|
||||
applyStyleOnLineOnFullLineAndRemoveSelection(line, style, placeCaretOnLine, cb);
|
||||
};
|
||||
|
||||
const applyStyleOnLineOnFullLineAndRemoveSelection = function (line, style, selectTarget, cb) {
|
||||
// see if line html has changed
|
||||
const inner$ = helper.padInner$;
|
||||
const oldLineHTML = inner$.find('div')[line];
|
||||
applyStyleOnLine(style, line);
|
||||
|
||||
helper.waitFor(() => {
|
||||
const 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);
|
||||
};
|
||||
|
||||
const pressFormattingShortcutOnSelection = function (key) {
|
||||
const inner$ = helper.padInner$;
|
||||
|
||||
// get the first text element out of the inner iframe
|
||||
const $firstTextElement = inner$('div').first();
|
||||
|
||||
// select this text element
|
||||
$firstTextElement.sendkeys('{selectall}');
|
||||
|
||||
const e = new inner$.Event(helper.evtType);
|
||||
e.ctrlKey = true; // Control key
|
||||
e.which = key.charCodeAt(0); // I, U, B, 5
|
||||
inner$('#innerdocbody').trigger(e);
|
||||
};
|
||||
|
||||
STYLES.forEach((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 () {
|
||||
const 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((key, index) => {
|
||||
const 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue