Compare commits

...

29 Commits

Author SHA1 Message Date
John McLear f33bd821ee Revert "TO REVERT: Deleting other tests."
This reverts commit a0c57b9c11.
2021-03-15 15:50:02 +00:00
John McLear 58f0000ed4 Update responsiveness.js 2021-03-15 15:34:14 +00:00
John McLear 211264c6de Update responsiveness.js 2021-03-15 15:28:28 +00:00
John McLear 05d8ba2f5a remove more sketchiness 2021-03-15 15:10:16 +00:00
John McLear a6d59e004c Update responsiveness.js 2021-03-15 14:48:42 +00:00
John McLear 6e4f3f8fab remove flakey tests 2021-03-15 14:48:30 +00:00
John McLear 1b4b243736 Update responsiveness.js 2021-03-15 14:29:29 +00:00
John McLear 4876cf7313 tests 2021-03-15 14:09:21 +00:00
John McLear 9478418984 Speed things up 2021-03-15 13:50:50 +00:00
John McLear e0dbacf86f attempts 2021-03-15 13:31:13 +00:00
John McLear 5550912d81 testing more edits... 2021-03-15 13:12:11 +00:00
John McLear 4910396f40 Update responsiveness.js 2021-03-15 12:54:11 +00:00
John McLear d3d9ec095a Update responsiveness.js 2021-03-15 12:36:31 +00:00
John McLear db2d097d5a Update responsiveness.js 2021-03-15 11:58:32 +00:00
John McLear adfe7e51ae Update responsiveness.js 2021-03-15 11:51:51 +00:00
John McLear 844c787bbf Update responsiveness.js 2021-03-15 11:21:45 +00:00
John McLear 01d4bfc753 enterkey 2021-03-15 11:17:33 +00:00
John McLear 4e38c5714f Update responsiveness.js 2021-03-15 11:09:44 +00:00
John McLear 754aa8363b Update responsiveness.js 2021-03-15 11:01:17 +00:00
John McLear 4da826dd0c exec 2021-03-15 10:58:45 +00:00
John McLear 98a83462d2 Update collabrunner.sh 2021-03-15 10:56:21 +00:00
John McLear 230336add3 executable...
silent commit..
2021-03-15 10:56:09 +00:00
John McLear 586e4a13b6 Update frontend-collab-tests.yml 2021-03-15 10:54:15 +00:00
John McLear 28c6170cd7 hrm 2021-03-15 10:50:45 +00:00
John McLear 918e642501 Update collabrunner.sh 2021-03-15 10:48:42 +00:00
John McLear d8baf7a1a7 Update frontend-collab-tests.yml 2021-03-15 10:46:45 +00:00
John McLear 47475bada6 Update frontend-collab-tests.yml 2021-03-15 10:42:11 +00:00
John McLear 5aa8d9ca5f First Test Run on Sauce Labs 2021-03-15 10:36:21 +00:00
John McLear a0c57b9c11 TO REVERT: Deleting other tests. 2021-03-15 10:10:02 +00:00
4 changed files with 145 additions and 79 deletions

View File

@ -0,0 +1,54 @@
# Leave the powered by Sauce Labs bit in as this means we get additional concurrency
name: "Frontend Collaboration tests powered by Sauce Labs"
on: [push]
jobs:
withoutplugins:
name: without plugins
runs-on: ubuntu-latest
steps:
- name: Generate Sauce Labs strings
id: sauce_strings
run: |
printf %s\\n '::set-output name=name::${{ github.workflow }} - ${{ github.job }}'
printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}'
- name: Checkout repository
uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
- name: Install all dependencies and symlink for ep_etherpad-lite
run: src/bin/installDeps.sh
- name: export GIT_HASH to env
id: environment
run: echo "::set-output name=sha_short::$(git rev-parse --short ${{ github.sha }})"
- name: Create settings.json
run: cp settings.json.template settings.json
- name: Disable import/export rate limiting
run: |
sed -e '/^ *"importExportRateLimiting":/,/^ *\}/ s/"max":.*/"max": 0/' -i settings.json
- uses: saucelabs/sauce-connect-action@v1
with:
username: ${{ secrets.SAUCE_USERNAME }}
accessKey: ${{ secrets.SAUCE_ACCESS_KEY }}
tunnelIdentifier: ${{ steps.sauce_strings.outputs.tunnel_id }}
- name: Run the frontend tests
shell: bash
env:
SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
SAUCE_NAME: ${{ steps.sauce_strings.outputs.name }}
TRAVIS_JOB_NUMBER: ${{ steps.sauce_strings.outputs.tunnel_id }}
GIT_HASH: ${{ steps.environment.outputs.sha_short }}
run: |
src/tests/frontend/travis/collabrunner.sh

View File

@ -1,91 +1,56 @@
'use strict'; 'use strict';
// Wait helper function, for simulating words per minute.
const wait = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
// Test for https://github.com/ether/etherpad-lite/issues/1763 // Test for https://github.com/ether/etherpad-lite/issues/1763
describe('Responsiveness of Editor', function () {
// 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 // create a new pad before each test run
beforeEach(function (cb) { beforeEach(function (cb) {
helper.newPad(cb); helper.newPad(cb, 'TEST_PAD_collab');
this.timeout(6000); this.timeout(1200000);
}); });
// 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();
}
const inner$ = helper.padInner$;
const chars = '0000000000'; // row of placeholder chars
const amount = 200000; // number of blocks of chars we will insert
const length = (amount * (chars.length) + 1); // include a counter for each space
let 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 it('Fast response to keypress in pad with large amount of contents', async function () {
const keyMultiplier = 10; // multiplier * 10 == total number of key events this.timeout(1200000);
let keysToSend = ''; if (top.window.location.search.indexOf('&collab=true') === -1) this.skip();
for (let i = 0; i <= keyMultiplier; i++) { const numberOfEdits = 3000; // creates 700+ lines
keysToSend += chars; const allowableLatency = 100; // allow 100 ms of latency to see our edit
// wait a minute for everyone to connect, this is skipped if &test=true is in the url
// so that it's easier to do local debug/testing without lots of users connected
if (top.window.location.search.indexOf('&test=true') === -1) {
await helper.waitForPromise(
() => parseInt(helper.padChrome$('#online_count').text()) >= 4, 60000);
} }
const textElement = inner$('div'); let i = 0;
textElement.sendkeys('{selectall}'); // select all while (i < numberOfEdits) {
textElement.sendkeys('{del}'); // clear the pad text helper.padOuter$('#outerdocbody').scrollTop(helper.padOuter$('#outerdocbody').height());
// move the caret to increase randomness of span lengths and increase likelihood that this
for (let i = 0; i <= amount; i++) { // authors content is within another authors span.
text = `${text + chars} `; // add the chars and space to the text contents helper.padInner$('div').last().sendkeys('{rightarrow}');
helper.padInner$('div').last().sendkeys('{rightarrow}');
helper.padInner$('div').last().sendkeys('{rightarrow}');
helper.padInner$('div').last().sendkeys('{rightarrow}');
// Put the text contents into the pad
// intentional white space at end of string
helper.padInner$('div').last().sendkeys(`${i}: ${Math.random().toString(36).substring(7)} `);
// 5% chance for every word we will do an enter
if (Math.random() < 0.05) {
helper.padInner$('div').last().sendkeys('{leftarrow}'); // To force enter on Chrome?
helper.padInner$('div').last().sendkeys('{enter}');
} }
inner$('div').first().text(text); // Put the text contents into the pad // wait 1500 milliseconds to simulate 40wpm if you have 20 authors you would do this
// but to speed up the test and as we only have 5 authors, we can do things ~7 times faster
// Wait for the new contents to be on the pad await wait(200);
helper.waitFor(() => inner$('div').text().length > length).done(() => { i++;
// has the text changed?
expect(inner$('div').text().length).to.be.greaterThan(length);
const start = Date.now(); // get the start time
// send some new text to the screen (ensure all 3 key events are sent)
const el = inner$('div').first();
for (let i = 0; i < keysToSend.length; ++i) {
const x = keysToSend.charCodeAt(i);
['keyup', 'keypress', 'keydown'].forEach((type) => {
const e = new $.Event(type);
e.keyCode = x;
el.trigger(e);
});
} }
helper.waitFor(() => { // Wait for the ability to process // do an edit, ensure it's on the screen within x ms.
const el = inner$('body'); const rand = Math.random().toString(36).substring(7);
if (el[0].textContent.length > amount) return true; helper.padInner$('div').last().sendkeys(`finaledit: ${rand}`);
}).done(() => { await helper.waitForPromise(
const end = Date.now(); // get the current time () => helper.padInner$('div').text().indexOf(rand) !== -1, allowableLatency);
const 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

@ -0,0 +1,40 @@
#!/bin/sh
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }
# Move to the Etherpad base directory.
MY_DIR=$(try cd "${0%/*}" && try pwd -P) || exit 1
try cd "${MY_DIR}/../../../.."
log "Assuming src/bin/installDeps.sh has already been run"
node src/node/server.js --experimental-worker "${@}" &
ep_pid=$!
log "Waiting for Etherpad to accept connections (http://localhost:9001)..."
connected=false
can_connect() {
curl -sSfo /dev/null http://localhost:9001/ || return 1
connected=true
}
now() { date +%s; }
start=$(now)
while [ $(($(now) - $start)) -le 15 ] && ! can_connect; do
sleep 1
done
[ "$connected" = true ] \
|| fatal "Timed out waiting for Etherpad to accept connections"
log "Successfully connected to Etherpad on http://localhost:9001"
# start the remote runner
try cd "${MY_DIR}"
log "Starting the remote runner..."
node remote_runner.js collab
exit_code=$?
kill "$ep_pid" && wait "$ep_pid"
log "Done."
exit "$exit_code"

View File

@ -11,6 +11,7 @@ const config = {
}; };
const isAdminRunner = process.argv[2] === 'admin'; const isAdminRunner = process.argv[2] === 'admin';
const isCollabRunner = process.argv[2] === 'collab';
let allTestsPassed = true; let allTestsPassed = true;
// overwrite the default exit code // overwrite the default exit code
@ -37,8 +38,14 @@ const sauceTestWorker = async.queue((testSettings, callback) => {
// don't know how to print them into output of the tests // don't know how to print them into output of the tests
testSettings.extendedDebugging = true; testSettings.extendedDebugging = true;
testSettings.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER; testSettings.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
let testURL;
if (isCollabRunner) {
testURL = 'http://localhost:9001/tests/frontend/index.html?grep=responsiveness%5C.js&collab=true';
} else {
testURL = 'http://localhost:9001/tests/frontend/';
}
browser.init(testSettings).get('http://localhost:9001/tests/frontend/', () => { browser.init(testSettings).get(testURL, () => {
const url = `https://saucelabs.com/jobs/${browser.sessionID}`; const url = `https://saucelabs.com/jobs/${browser.sessionID}`;
console.log(`Remote sauce test '${name}' started! ${url}`); console.log(`Remote sauce test '${name}' started! ${url}`);