tests: Refine helper/multipleUsers.js

* Rename "current"/"other" to "user0"/"user1".
  * Delete unnecessary `_createTokenFor*` functions.
  * Rename helper functions to remove unnecessary leading underscore
    and for brevity.
  * Use jQuery's `.attr()` to build the second iframe.
  * Use js-cookie to manipulate the token cookie.
  * Don't attempt to set the token cookie if the pad isn't loaded.
  * Use the token generated by the pad.
  * Only clear the token cookie at path=/.
This commit is contained in:
Richard Hansen 2021-03-31 02:38:05 -04:00 committed by webzwo0i
parent f2034ad368
commit 056939cd22

View file

@ -1,47 +1,39 @@
'use strict'; 'use strict';
helper.multipleUsers = { helper.multipleUsers = {
thisUser: null, _user0: null,
otherUser: null, _user1: null,
// open the same pad on different frames (allows concurrent editions to pad) // open the same pad on different frames (allows concurrent editions to pad)
async init() { async init() {
// do some cleanup, in case any of the tests failed on the previous run this._user0 = {
const currentToken = _createTokenForCurrentUser();
const otherToken = _createTokenForAnotherUser();
_removeExistingTokensFromCookie();
this.thisUser = {
$frame: $('#iframe-container iframe'), $frame: $('#iframe-container iframe'),
token: currentToken, token: getToken(),
// we'll switch between pads, need to store current values of helper.pad* // we'll switch between pads, need to store current values of helper.pad*
// to be able to restore those values later // to be able to restore those values later
padChrome$: helper.padChrome$, padChrome$: helper.padChrome$,
padOuter$: helper.padOuter$, padOuter$: helper.padOuter$,
padInner$: helper.padInner$, padInner$: helper.padInner$,
}; };
this._user1 = {};
this.otherUser = { // Force generation of a new token.
token: otherToken, clearToken();
};
// need to perform as the other user, otherwise we'll get the userdup error message // need to perform as the other user, otherwise we'll get the userdup error message
await this.performAsOtherUser(this._createFrameForOtherUser.bind(this)); await this.performAsOtherUser(this._createUser1Frame.bind(this));
}, },
async performAsOtherUser(action) { async performAsOtherUser(action) {
_startActingLike(this.otherUser); startActingLike(this._user1);
await action(); await action();
// go back to initial state when we're done startActingLike(this._user0);
_startActingLike(this.thisUser);
}, },
close() { close() {
this.thisUser.$frame.attr('style', ''); // make the default ocopy the full height this._user0.$frame.attr('style', ''); // make the default ocopy the full height
this.otherUser.$frame.remove(); this._user1.$frame.remove();
}, },
async _loadJQueryCodeForOtherFrame() { async _loadJQueryForUser1Frame() {
const code = await $.get('/static/js/jquery.js'); const code = await $.get('/static/js/jquery.js');
// make sure we don't override existing jquery // make sure we don't override existing jquery
@ -49,49 +41,53 @@ helper.multipleUsers = {
const sendkeysCode = await $.get('/tests/frontend/lib/sendkeys.js'); const sendkeysCode = await $.get('/tests/frontend/lib/sendkeys.js');
const codesToLoad = [jQueryCode, sendkeysCode]; const codesToLoad = [jQueryCode, sendkeysCode];
this.otherUser.padChrome$ = _getFrameJQuery(codesToLoad, this.otherUser.$frame); this._user1.padChrome$ = getFrameJQuery(codesToLoad, this._user1.$frame);
this.otherUser.padOuter$ = this._user1.padOuter$ =
_getFrameJQuery(codesToLoad, this.otherUser.padChrome$('iframe[name="ace_outer"]')); getFrameJQuery(codesToLoad, this._user1.padChrome$('iframe[name="ace_outer"]'));
this.otherUser.padInner$ = this._user1.padInner$ =
_getFrameJQuery(codesToLoad, this.otherUser.padOuter$('iframe[name="ace_inner"]')); getFrameJQuery(codesToLoad, this._user1.padOuter$('iframe[name="ace_inner"]'));
// update helper vars now that they are available // update helper vars now that they are available
helper.padChrome$ = this.otherUser.padChrome$; helper.padChrome$ = this._user1.padChrome$;
helper.padOuter$ = this.otherUser.padOuter$; helper.padOuter$ = this._user1.padOuter$;
helper.padInner$ = this.otherUser.padInner$; helper.padInner$ = this._user1.padInner$;
}, },
async _createFrameForOtherUser() { async _createUser1Frame() {
// create the iframe // create the iframe
const padUrl = this.thisUser.$frame.attr('src'); const padUrl = this._user0.$frame.attr('src');
this.otherUser.$frame = $(`<iframe id="other_pad" src="${padUrl}"></iframe>`); this._user1.$frame = $('<iframe>').attr('id', 'user1_pad').attr('src', padUrl);
// place one iframe (visually) below the other // place one iframe (visually) below the other
this.thisUser.$frame.attr('style', 'height: 50%'); this._user0.$frame.attr('style', 'height: 50%');
this.otherUser.$frame.attr('style', 'height: 50%; top: 50%'); this._user1.$frame.attr('style', 'height: 50%; top: 50%');
this.otherUser.$frame.insertAfter(this.thisUser.$frame); this._user1.$frame.insertAfter(this._user0.$frame);
// wait for other pad to load // wait for user1 pad to load
await new Promise((resolve) => this.otherUser.$frame.one('load', resolve)); await new Promise((resolve) => this._user1.$frame.one('load', resolve));
const $editorLoadingMessage = this.otherUser.$frame.contents().find('#editorloadingbox'); const $editorLoadingMessage = this._user1.$frame.contents().find('#editorloadingbox');
const $errorMessageModal = this.thisUser.$frame.contents().find('#connectivity .userdup'); const $errorMessageModal = this._user0.$frame.contents().find('#connectivity .userdup');
await helper.waitForPromise(() => { await helper.waitForPromise(() => {
const finishedLoadingOtherFrame = !$editorLoadingMessage.is(':visible'); const loaded = !$editorLoadingMessage.is(':visible');
// make sure we don't get the userdup by mistake // make sure we don't get the userdup by mistake
const didNotDetectUserDup = !$errorMessageModal.is(':visible'); const didNotDetectUserDup = !$errorMessageModal.is(':visible');
return loaded && didNotDetectUserDup;
return finishedLoadingOtherFrame && didNotDetectUserDup;
}, 50000); }, 50000);
// need to get values for this.otherUser.pad* vars // need to get values for this._user1.pad* vars
await this._loadJQueryCodeForOtherFrame(); await this._loadJQueryForUser1Frame();
this._user1.token = getToken();
if (this._user0.token === this._user1.token) {
throw new Error('expected different token for user1');
}
}, },
}; };
// adapted form helper.js on Etherpad code // adapted form helper.js on Etherpad code
const _getFrameJQuery = (codesToLoad, $iframe) => { const getFrameJQuery = (codesToLoad, $iframe) => {
const win = $iframe[0].contentWindow; const win = $iframe[0].contentWindow;
const doc = win.document; const doc = win.document;
@ -105,43 +101,21 @@ const _getFrameJQuery = (codesToLoad, $iframe) => {
return win.$; return win.$;
}; };
const _getDocumentWithCookie = () => ( const getCookies =
helper.padChrome$ () => helper.padChrome$.window.require('ep_etherpad-lite/static/js/pad_utils').Cookies;
? helper.padChrome$.document
: helper.multipleUsers.thisUser.$frame.get(0).contentDocument
);
const _setTokenOnCookie = (token) => { const setToken = (token) => getCookies().set('token', token);
_getDocumentWithCookie().cookie = `token=${token};secure`;
};
const _getTokenFromCookie = () => { const getToken = () => getCookies().get('token');
const fullCookie = _getDocumentWithCookie().cookie;
return fullCookie.replace(/.*token=([^;]*).*/, '$1').trim();
};
const _createTokenForCurrentUser = () => ( const startActingLike = (user) => {
_getTokenFromCookie().replace(/-other_user.*/g, '')
);
const _createTokenForAnotherUser = () => {
const currentToken = _createTokenForCurrentUser();
return `${currentToken}-other_user${helper.randomString(4)}`;
};
const _startActingLike = (user) => {
// update helper references, so other methods will act as if the main frame // update helper references, so other methods will act as if the main frame
// was the one we're using from now on // was the one we're using from now on
helper.padChrome$ = user.padChrome$; helper.padChrome$ = user.padChrome$;
helper.padOuter$ = user.padOuter$; helper.padOuter$ = user.padOuter$;
helper.padInner$ = user.padInner$; helper.padInner$ = user.padInner$;
_setTokenOnCookie(user.token); if (helper.padChrome$) setToken(user.token);
}; };
const _removeExistingTokensFromCookie = () => { const clearToken = () => getCookies().remove('token');
// Expire cookie, to make sure it is removed by the browser.
// See https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie#Example_4_Reset_the_previous_cookie
_getDocumentWithCookie().cookie = 'token=foo;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/p';
_getDocumentWithCookie().cookie = 'token=foo;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
};