bring indentation in line with other front-end projects

This commit is contained in:
Bruno Windels 2018-08-14 12:53:16 +02:00
parent 2c983f8cee
commit 377a20fffa
22 changed files with 583 additions and 560 deletions

23
.editorconfig Normal file
View File

@ -0,0 +1,23 @@
# Copyright 2017 Aviral Dasgupta
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
root = true
[*]
charset=utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

View File

@ -1,14 +1,14 @@
{ {
"name": "e2e-tests", "name": "e2e-tests",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"puppeteer": "^1.6.0" "puppeteer": "^1.6.0"
} }
} }

View File

@ -3,8 +3,8 @@ RIOT_BRANCH=master
BASE_DIR=$(readlink -f $(dirname $0)) BASE_DIR=$(readlink -f $(dirname $0))
if [ -d $BASE_DIR/riot-web ]; then if [ -d $BASE_DIR/riot-web ]; then
echo "riot is already installed" echo "riot is already installed"
exit exit
fi fi
cd $BASE_DIR cd $BASE_DIR

View File

@ -5,7 +5,7 @@ PIDFILE=$BASE_DIR/riot.pid
CONFIG_BACKUP=config.e2etests_backup.json CONFIG_BACKUP=config.e2etests_backup.json
if [ -f $PIDFILE ]; then if [ -f $PIDFILE ]; then
exit exit
fi fi
cd $BASE_DIR/ cd $BASE_DIR/
@ -14,29 +14,29 @@ pushd riot-web/webapp/ > /dev/null
# backup config file before we copy template # backup config file before we copy template
if [ -f config.json ]; then if [ -f config.json ]; then
mv config.json $CONFIG_BACKUP mv config.json $CONFIG_BACKUP
fi fi
cp $BASE_DIR/config-template/config.json . cp $BASE_DIR/config-template/config.json .
LOGFILE=$(mktemp) LOGFILE=$(mktemp)
# run web server in the background, showing output on error # run web server in the background, showing output on error
( (
python -m SimpleHTTPServer $PORT > $LOGFILE 2>&1 & python -m SimpleHTTPServer $PORT > $LOGFILE 2>&1 &
PID=$! PID=$!
echo $PID > $PIDFILE echo $PID > $PIDFILE
# wait so subshell does not exit # wait so subshell does not exit
# otherwise sleep below would not work # otherwise sleep below would not work
wait $PID; RESULT=$? wait $PID; RESULT=$?
# NOT expected SIGTERM (128 + 15) # NOT expected SIGTERM (128 + 15)
# from stop.sh? # from stop.sh?
if [ $RESULT -ne 143 ]; then if [ $RESULT -ne 143 ]; then
echo "failed" echo "failed"
cat $LOGFILE cat $LOGFILE
rm $PIDFILE 2> /dev/null rm $PIDFILE 2> /dev/null
fi fi
rm $LOGFILE rm $LOGFILE
exit $RESULT exit $RESULT
)& )&
# to be able to return the exit code for immediate errors (like address already in use) # to be able to return the exit code for immediate errors (like address already in use)
# we wait for a short amount of time in the background and exit when the first # we wait for a short amount of time in the background and exit when the first
@ -46,6 +46,6 @@ sleep 0.5 &
wait -n; RESULT=$? wait -n; RESULT=$?
# return exit code of first child to exit # return exit code of first child to exit
if [ $RESULT -eq 0 ]; then if [ $RESULT -eq 0 ]; then
echo "running" echo "running"
fi fi
exit $RESULT exit $RESULT

View File

@ -6,15 +6,15 @@ CONFIG_BACKUP=config.e2etests_backup.json
cd $BASE_DIR cd $BASE_DIR
if [ -f $PIDFILE ]; then if [ -f $PIDFILE ]; then
echo "stopping riot server ..." echo "stopping riot server ..."
PID=$(cat $PIDFILE) PID=$(cat $PIDFILE)
rm $PIDFILE rm $PIDFILE
kill $PID kill $PID
# revert config file # revert config file
cd riot-web/webapp cd riot-web/webapp
rm config.json rm config.json
if [ -f $CONFIG_BACKUP ]; then if [ -f $CONFIG_BACKUP ]; then
mv $CONFIG_BACKUP config.json mv $CONFIG_BACKUP config.json
fi fi
fi fi

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -29,57 +29,57 @@ const getE2EDeviceFromSettings = require('./tests/e2e-device');
const verifyDeviceForUser = require("./tests/verify-device"); const verifyDeviceForUser = require("./tests/verify-device");
module.exports = async function scenario(createSession) { module.exports = async function scenario(createSession) {
async function createUser(username) { async function createUser(username) {
const session = await createSession(username); const session = await createSession(username);
await signup(session, session.username, 'testtest'); await signup(session, session.username, 'testtest');
await acceptServerNoticesInviteAndConsent(session); await acceptServerNoticesInviteAndConsent(session);
return session; return session;
} }
const alice = await createUser("alice"); const alice = await createUser("alice");
const bob = await createUser("bob"); const bob = await createUser("bob");
await createDirectoryRoomAndTalk(alice, bob); await createDirectoryRoomAndTalk(alice, bob);
await createE2ERoomAndTalk(alice, bob); await createE2ERoomAndTalk(alice, bob);
} }
async function createDirectoryRoomAndTalk(alice, bob) { async function createDirectoryRoomAndTalk(alice, bob) {
console.log(" creating a public room and join through directory:"); console.log(" creating a public room and join through directory:");
const room = 'test'; const room = 'test';
await createRoom(alice, room); await createRoom(alice, room);
await changeRoomSettings(alice, {directory: true, visibility: "public_no_guests"}); await changeRoomSettings(alice, {directory: true, visibility: "public_no_guests"});
await join(bob, room); await join(bob, room);
const bobMessage = "hi Alice!"; const bobMessage = "hi Alice!";
await sendMessage(bob, bobMessage); await sendMessage(bob, bobMessage);
await receiveMessage(alice, {sender: "bob", body: bobMessage}); await receiveMessage(alice, {sender: "bob", body: bobMessage});
const aliceMessage = "hi Bob, welcome!" const aliceMessage = "hi Bob, welcome!"
await sendMessage(alice, aliceMessage); await sendMessage(alice, aliceMessage);
await receiveMessage(bob, {sender: "alice", body: aliceMessage}); await receiveMessage(bob, {sender: "alice", body: aliceMessage});
} }
async function createE2ERoomAndTalk(alice, bob) { async function createE2ERoomAndTalk(alice, bob) {
console.log(" creating an e2e encrypted room and join through invite:"); console.log(" creating an e2e encrypted room and join through invite:");
const room = "secrets"; const room = "secrets";
await createRoom(bob, room); await createRoom(bob, room);
await changeRoomSettings(bob, {encryption: true}); await changeRoomSettings(bob, {encryption: true});
await invite(bob, "@alice:localhost"); await invite(bob, "@alice:localhost");
await acceptInvite(alice, room); await acceptInvite(alice, room);
const bobDevice = await getE2EDeviceFromSettings(bob); const bobDevice = await getE2EDeviceFromSettings(bob);
// wait some time for the encryption warning dialog // wait some time for the encryption warning dialog
// to appear after closing the settings // to appear after closing the settings
await bob.delay(500); await bob.delay(500);
await acceptDialog(bob, "encryption"); await acceptDialog(bob, "encryption");
const aliceDevice = await getE2EDeviceFromSettings(alice); const aliceDevice = await getE2EDeviceFromSettings(alice);
// wait some time for the encryption warning dialog // wait some time for the encryption warning dialog
// to appear after closing the settings // to appear after closing the settings
await alice.delay(500); await alice.delay(500);
await acceptDialog(alice, "encryption"); await acceptDialog(alice, "encryption");
await verifyDeviceForUser(bob, "alice", aliceDevice); await verifyDeviceForUser(bob, "alice", aliceDevice);
await verifyDeviceForUser(alice, "bob", bobDevice); await verifyDeviceForUser(alice, "bob", bobDevice);
const aliceMessage = "Guess what I just heard?!" const aliceMessage = "Guess what I just heard?!"
await sendMessage(alice, aliceMessage); await sendMessage(alice, aliceMessage);
await receiveMessage(bob, {sender: "alice", body: aliceMessage, encrypted: true}); await receiveMessage(bob, {sender: "alice", body: aliceMessage, encrypted: true});
const bobMessage = "You've got to tell me!"; const bobMessage = "You've got to tell me!";
await sendMessage(bob, bobMessage); await sendMessage(bob, bobMessage);
await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true}); await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true});
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,180 +17,180 @@ limitations under the License.
const puppeteer = require('puppeteer'); const puppeteer = require('puppeteer');
class LogBuffer { class LogBuffer {
constructor(page, eventName, eventMapper, reduceAsync=false, initialValue = "") { constructor(page, eventName, eventMapper, reduceAsync=false, initialValue = "") {
this.buffer = initialValue; this.buffer = initialValue;
page.on(eventName, (arg) => { page.on(eventName, (arg) => {
const result = eventMapper(arg); const result = eventMapper(arg);
if (reduceAsync) { if (reduceAsync) {
result.then((r) => this.buffer += r); result.then((r) => this.buffer += r);
} }
else { else {
this.buffer += result; this.buffer += result;
} }
}); });
} }
} }
class Logger { class Logger {
constructor(username) { constructor(username) {
this.indent = 0; this.indent = 0;
this.username = username; this.username = username;
} }
startGroup(description) { startGroup(description) {
const indent = " ".repeat(this.indent * 2); const indent = " ".repeat(this.indent * 2);
console.log(`${indent} * ${this.username} ${description}:`); console.log(`${indent} * ${this.username} ${description}:`);
this.indent += 1; this.indent += 1;
} }
endGroup() { endGroup() {
this.indent -= 1; this.indent -= 1;
} }
step(description) { step(description) {
const indent = " ".repeat(this.indent * 2); const indent = " ".repeat(this.indent * 2);
process.stdout.write(`${indent} * ${this.username} ${description} ... `); process.stdout.write(`${indent} * ${this.username} ${description} ... `);
} }
done(status = "done") { done(status = "done") {
process.stdout.write(status + "\n"); process.stdout.write(status + "\n");
} }
} }
module.exports = class RiotSession { module.exports = class RiotSession {
constructor(browser, page, username, riotserver) { constructor(browser, page, username, riotserver) {
this.browser = browser; this.browser = browser;
this.page = page; this.page = page;
this.riotserver = riotserver; this.riotserver = riotserver;
this.username = username; this.username = username;
this.consoleLog = new LogBuffer(page, "console", (msg) => `${msg.text()}\n`); this.consoleLog = new LogBuffer(page, "console", (msg) => `${msg.text()}\n`);
this.networkLog = new LogBuffer(page, "requestfinished", async (req) => { this.networkLog = new LogBuffer(page, "requestfinished", async (req) => {
const type = req.resourceType(); const type = req.resourceType();
const response = await req.response(); const response = await req.response();
return `${type} ${response.status()} ${req.method()} ${req.url()} \n`; return `${type} ${response.status()} ${req.method()} ${req.url()} \n`;
}, true); }, true);
this.log = new Logger(this.username); this.log = new Logger(this.username);
}
static async create(username, puppeteerOptions, riotserver) {
const browser = await puppeteer.launch(puppeteerOptions);
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
return new RiotSession(browser, page, username, riotserver);
}
async tryGetInnertext(selector) {
const field = await this.page.$(selector);
if (field != null) {
const text_handle = await field.getProperty('innerText');
return await text_handle.jsonValue();
} }
return null;
}
async getElementProperty(handle, property) { static async create(username, puppeteerOptions, riotserver) {
const propHandle = await handle.getProperty(property); const browser = await puppeteer.launch(puppeteerOptions);
return await propHandle.jsonValue(); const page = await browser.newPage();
} await page.setViewport({
width: 1280,
innerText(field) { height: 800
return this.getElementProperty(field, 'innerText'); });
} return new RiotSession(browser, page, username, riotserver);
getOuterHTML(element_handle) {
return this.getElementProperty(field, 'outerHTML');
}
consoleLogs() {
return this.consoleLog.buffer;
}
networkLogs() {
return this.networkLog.buffer;
}
logXHRRequests() {
let buffer = "";
this.page.on('requestfinished', async (req) => {
const type = req.resourceType();
const response = await req.response();
//if (type === 'xhr' || type === 'fetch') {
buffer += `${type} ${response.status()} ${req.method()} ${req.url()} \n`;
// if (req.method() === "POST") {
// buffer += " Post data: " + req.postData();
// }
//}
});
return {
logs() {
return buffer;
}
} }
}
async printElements(label, elements) { async tryGetInnertext(selector) {
console.log(label, await Promise.all(elements.map(getOuterHTML))); const field = await this.page.$(selector);
} if (field != null) {
const text_handle = await field.getProperty('innerText');
return await text_handle.jsonValue();
}
return null;
}
async replaceInputText(input, text) { async getElementProperty(handle, property) {
// click 3 times to select all text const propHandle = await handle.getProperty(property);
await input.click({clickCount: 3}); return await propHandle.jsonValue();
// then remove it with backspace }
await input.press('Backspace');
// and type the new text
await input.type(text);
}
query(selector) { innerText(field) {
return this.page.$(selector); return this.getElementProperty(field, 'innerText');
} }
waitAndQuery(selector, timeout = 500) {
return this.page.waitForSelector(selector, {visible: true, timeout});
}
queryAll(selector) { getOuterHTML(element_handle) {
return this.page.$$(selector); return this.getElementProperty(field, 'outerHTML');
} }
async waitAndQueryAll(selector, timeout = 500) { consoleLogs() {
await this.waitAndQuery(selector, timeout); return this.consoleLog.buffer;
return await this.queryAll(selector); }
}
waitForNewPage(timeout = 500) { networkLogs() {
return new Promise((resolve, reject) => { return this.networkLog.buffer;
const timeoutHandle = setTimeout(() => { }
this.browser.removeEventListener('targetcreated', callback);
reject(new Error(`timeout of ${timeout}ms for waitForNewPage elapsed`));
}, timeout);
const callback = async (target) => { logXHRRequests() {
clearTimeout(timeoutHandle); let buffer = "";
const page = await target.page(); this.page.on('requestfinished', async (req) => {
resolve(page); const type = req.resourceType();
}; const response = await req.response();
//if (type === 'xhr' || type === 'fetch') {
buffer += `${type} ${response.status()} ${req.method()} ${req.url()} \n`;
// if (req.method() === "POST") {
// buffer += " Post data: " + req.postData();
// }
//}
});
return {
logs() {
return buffer;
}
}
}
this.browser.once('targetcreated', callback); async printElements(label, elements) {
}); console.log(label, await Promise.all(elements.map(getOuterHTML)));
} }
goto(url) { async replaceInputText(input, text) {
return this.page.goto(url); // click 3 times to select all text
} await input.click({clickCount: 3});
// then remove it with backspace
await input.press('Backspace');
// and type the new text
await input.type(text);
}
url(path) { query(selector) {
return this.riotserver + path; return this.page.$(selector);
} }
delay(ms) { waitAndQuery(selector, timeout = 500) {
return new Promise(resolve => setTimeout(resolve, ms)); return this.page.waitForSelector(selector, {visible: true, timeout});
} }
close() { queryAll(selector) {
return this.browser.close(); return this.page.$$(selector);
} }
async waitAndQueryAll(selector, timeout = 500) {
await this.waitAndQuery(selector, timeout);
return await this.queryAll(selector);
}
waitForNewPage(timeout = 500) {
return new Promise((resolve, reject) => {
const timeoutHandle = setTimeout(() => {
this.browser.removeEventListener('targetcreated', callback);
reject(new Error(`timeout of ${timeout}ms for waitForNewPage elapsed`));
}, timeout);
const callback = async (target) => {
clearTimeout(timeoutHandle);
const page = await target.page();
resolve(page);
};
this.browser.once('targetcreated', callback);
});
}
goto(url) {
return this.page.goto(url);
}
url(path) {
return this.riotserver + path;
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
close() {
return this.browser.close();
}
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -18,24 +18,24 @@ const assert = require('assert');
const {acceptDialogMaybe} = require('./dialog'); const {acceptDialogMaybe} = require('./dialog');
module.exports = async function acceptInvite(session, name) { module.exports = async function acceptInvite(session, name) {
session.log.step(`accepts "${name}" invite`); session.log.step(`accepts "${name}" invite`);
//TODO: brittle selector //TODO: brittle selector
const invitesHandles = await session.waitAndQueryAll('.mx_RoomTile_name.mx_RoomTile_invite', 1000); const invitesHandles = await session.waitAndQueryAll('.mx_RoomTile_name.mx_RoomTile_invite', 1000);
const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => { const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => {
const text = await session.innerText(inviteHandle); const text = await session.innerText(inviteHandle);
return {inviteHandle, text}; return {inviteHandle, text};
})); }));
const inviteHandle = invitesWithText.find(({inviteHandle, text}) => { const inviteHandle = invitesWithText.find(({inviteHandle, text}) => {
return text.trim() === name; return text.trim() === name;
}).inviteHandle; }).inviteHandle;
await inviteHandle.click(); await inviteHandle.click();
const acceptInvitationLink = await session.waitAndQuery(".mx_RoomPreviewBar_join_text a:first-child"); const acceptInvitationLink = await session.waitAndQuery(".mx_RoomPreviewBar_join_text a:first-child");
await acceptInvitationLink.click(); await acceptInvitationLink.click();
// accept e2e warning dialog // accept e2e warning dialog
acceptDialogMaybe(session, "encryption"); acceptDialogMaybe(session, "encryption");
session.log.done(); session.log.done();
} }

View File

@ -17,11 +17,11 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function acceptTerms(session) { module.exports = async function acceptTerms(session) {
const reviewTermsButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary', 5000); const reviewTermsButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary', 5000);
const termsPagePromise = session.waitForNewPage(); const termsPagePromise = session.waitForNewPage();
await reviewTermsButton.click(); await reviewTermsButton.click();
const termsPage = await termsPagePromise; const termsPage = await termsPagePromise;
const acceptButton = await termsPage.$('input[type=submit]'); const acceptButton = await termsPage.$('input[type=submit]');
await acceptButton.click(); await acceptButton.click();
await session.delay(500); //TODO yuck, timers await session.delay(500); //TODO yuck, timers
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,17 +17,17 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function createRoom(session, roomName) { module.exports = async function createRoom(session, roomName) {
session.log.step(`creates room "${roomName}"`); session.log.step(`creates room "${roomName}"`);
//TODO: brittle selector //TODO: brittle selector
const createRoomButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Create new room"]'); const createRoomButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Create new room"]');
await createRoomButton.click(); await createRoomButton.click();
const roomNameInput = await session.waitAndQuery('.mx_CreateRoomDialog_input'); const roomNameInput = await session.waitAndQuery('.mx_CreateRoomDialog_input');
await session.replaceInputText(roomNameInput, roomName); await session.replaceInputText(roomNameInput, roomName);
const createButton = await session.waitAndQuery('.mx_Dialog_primary'); const createButton = await session.waitAndQuery('.mx_Dialog_primary');
await createButton.click(); await createButton.click();
await session.waitAndQuery('.mx_MessageComposer'); await session.waitAndQuery('.mx_MessageComposer');
session.log.done(); session.log.done();
} }

View File

@ -18,30 +18,30 @@ const assert = require('assert');
async function acceptDialog(session, expectedContent) { async function acceptDialog(session, expectedContent) {
const foundDialog = await acceptDialogMaybe(session, expectedContent); const foundDialog = await acceptDialogMaybe(session, expectedContent);
if (!foundDialog) { if (!foundDialog) {
throw new Error("could not find a dialog"); throw new Error("could not find a dialog");
} }
} }
async function acceptDialogMaybe(session, expectedContent) { async function acceptDialogMaybe(session, expectedContent) {
let dialog = null; let dialog = null;
try { try {
dialog = await session.waitAndQuery(".mx_QuestionDialog", 100); dialog = await session.waitAndQuery(".mx_QuestionDialog", 100);
} catch(err) { } catch(err) {
return false; return false;
} }
if (expectedContent) { if (expectedContent) {
const contentElement = await dialog.$(".mx_Dialog_content"); const contentElement = await dialog.$(".mx_Dialog_content");
const content = await (await contentElement.getProperty("innerText")).jsonValue(); const content = await (await contentElement.getProperty("innerText")).jsonValue();
assert.ok(content.indexOf(expectedContent) !== -1); assert.ok(content.indexOf(expectedContent) !== -1);
} }
const primaryButton = await dialog.$(".mx_Dialog_primary"); const primaryButton = await dialog.$(".mx_Dialog_primary");
await primaryButton.click(); await primaryButton.click();
return true; return true;
} }
module.exports = { module.exports = {
acceptDialog, acceptDialog,
acceptDialogMaybe, acceptDialogMaybe,
}; };

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,15 +17,15 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function getE2EDeviceFromSettings(session) { module.exports = async function getE2EDeviceFromSettings(session) {
session.log.step(`gets e2e device/key from settings`); session.log.step(`gets e2e device/key from settings`);
const settingsButton = await session.query('.mx_BottomLeftMenu_settings'); const settingsButton = await session.query('.mx_BottomLeftMenu_settings');
await settingsButton.click(); await settingsButton.click();
const deviceAndKey = await session.waitAndQueryAll(".mx_UserSettings_section.mx_UserSettings_cryptoSection code"); const deviceAndKey = await session.waitAndQueryAll(".mx_UserSettings_section.mx_UserSettings_cryptoSection code");
assert.equal(deviceAndKey.length, 2); assert.equal(deviceAndKey.length, 2);
const id = await (await deviceAndKey[0].getProperty("innerText")).jsonValue(); const id = await (await deviceAndKey[0].getProperty("innerText")).jsonValue();
const key = await (await deviceAndKey[1].getProperty("innerText")).jsonValue(); const key = await (await deviceAndKey[1].getProperty("innerText")).jsonValue();
const closeButton = await session.query(".mx_RoomHeader_cancelButton"); const closeButton = await session.query(".mx_RoomHeader_cancelButton");
await closeButton.click(); await closeButton.click();
session.log.done(); session.log.done();
return {id, key}; return {id, key};
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,14 +17,14 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function invite(session, userId) { module.exports = async function invite(session, userId) {
session.log.step(`invites "${userId}" to room`); session.log.step(`invites "${userId}" to room`);
await session.delay(200); await session.delay(200);
const inviteButton = await session.waitAndQuery(".mx_RightPanel_invite"); const inviteButton = await session.waitAndQuery(".mx_RightPanel_invite");
await inviteButton.click(); await inviteButton.click();
const inviteTextArea = await session.waitAndQuery(".mx_ChatInviteDialog textarea"); const inviteTextArea = await session.waitAndQuery(".mx_ChatInviteDialog textarea");
await inviteTextArea.type(userId); await inviteTextArea.type(userId);
await inviteTextArea.press("Enter"); await inviteTextArea.press("Enter");
const confirmButton = await session.query(".mx_Dialog_primary"); const confirmButton = await session.query(".mx_Dialog_primary");
await confirmButton.click(); await confirmButton.click();
session.log.done(); session.log.done();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,20 +17,20 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function join(session, roomName) { module.exports = async function join(session, roomName) {
session.log.step(`joins room "${roomName}"`); session.log.step(`joins room "${roomName}"`);
//TODO: brittle selector //TODO: brittle selector
const directoryButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Room directory"]'); const directoryButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Room directory"]');
await directoryButton.click(); await directoryButton.click();
const roomInput = await session.waitAndQuery('.mx_DirectorySearchBox_input'); const roomInput = await session.waitAndQuery('.mx_DirectorySearchBox_input');
await session.replaceInputText(roomInput, roomName); await session.replaceInputText(roomInput, roomName);
const firstRoomLabel = await session.waitAndQuery('.mx_RoomDirectory_table .mx_RoomDirectory_name:first-child', 1000); const firstRoomLabel = await session.waitAndQuery('.mx_RoomDirectory_table .mx_RoomDirectory_name:first-child', 1000);
await firstRoomLabel.click(); await firstRoomLabel.click();
const joinLink = await session.waitAndQuery('.mx_RoomPreviewBar_join_text a'); const joinLink = await session.waitAndQuery('.mx_RoomPreviewBar_join_text a');
await joinLink.click(); await joinLink.click();
await session.waitAndQuery('.mx_MessageComposer'); await session.waitAndQuery('.mx_MessageComposer');
session.log.done(); session.log.done();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,33 +17,33 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function receiveMessage(session, message) { module.exports = async function receiveMessage(session, message) {
session.log.step(`receives message "${message.body}" from ${message.sender}`); session.log.step(`receives message "${message.body}" from ${message.sender}`);
// wait for a response to come in that contains the message // wait for a response to come in that contains the message
// crude, but effective // crude, but effective
await session.page.waitForResponse(async (response) => { await session.page.waitForResponse(async (response) => {
if (response.request().url().indexOf("/sync") === -1) { if (response.request().url().indexOf("/sync") === -1) {
return false; return false;
} }
const body = await response.text(); const body = await response.text();
if (message.encrypted) {
return body.indexOf(message.sender) !== -1 &&
body.indexOf("m.room.encrypted") !== -1;
} else {
return body.indexOf(message.body) !== -1;
}
});
// wait a bit for the incoming event to be rendered
await session.delay(300);
let lastTile = await session.query(".mx_EventTile_last");
const senderElement = await lastTile.$(".mx_SenderProfile_name");
const bodyElement = await lastTile.$(".mx_EventTile_body");
const sender = await(await senderElement.getProperty("innerText")).jsonValue();
const body = await(await bodyElement.getProperty("innerText")).jsonValue();
if (message.encrypted) { if (message.encrypted) {
return body.indexOf(message.sender) !== -1 && const e2eIcon = await lastTile.$(".mx_EventTile_e2eIcon");
body.indexOf("m.room.encrypted") !== -1; assert.ok(e2eIcon);
} else {
return body.indexOf(message.body) !== -1;
} }
}); assert.equal(body, message.body);
// wait a bit for the incoming event to be rendered assert.equal(sender, message.sender);
await session.delay(300); session.log.done();
let lastTile = await session.query(".mx_EventTile_last");
const senderElement = await lastTile.$(".mx_SenderProfile_name");
const bodyElement = await lastTile.$(".mx_EventTile_body");
const sender = await(await senderElement.getProperty("innerText")).jsonValue();
const body = await(await bodyElement.getProperty("innerText")).jsonValue();
if (message.encrypted) {
const e2eIcon = await lastTile.$(".mx_EventTile_e2eIcon");
assert.ok(e2eIcon);
}
assert.equal(body, message.body);
assert.equal(sender, message.sender);
session.log.done();
} }

View File

@ -18,66 +18,66 @@ const assert = require('assert');
const {acceptDialog} = require('./dialog'); const {acceptDialog} = require('./dialog');
async function setCheckboxSetting(session, checkbox, enabled) { async function setCheckboxSetting(session, checkbox, enabled) {
const checked = await session.getElementProperty(checkbox, "checked"); const checked = await session.getElementProperty(checkbox, "checked");
assert.equal(typeof checked, "boolean"); assert.equal(typeof checked, "boolean");
if (checked !== enabled) { if (checked !== enabled) {
await checkbox.click(); await checkbox.click();
session.log.done(); session.log.done();
return true; return true;
} else { } else {
session.log.done("already set"); session.log.done("already set");
} }
} }
module.exports = async function changeRoomSettings(session, settings) { module.exports = async function changeRoomSettings(session, settings) {
session.log.startGroup(`changes the room settings`); session.log.startGroup(`changes the room settings`);
/// XXX delay is needed here, possible because the header is being rerendered /// XXX delay is needed here, possible because the header is being rerendered
/// click doesn't do anything otherwise /// click doesn't do anything otherwise
await session.delay(500); await session.delay(500);
const settingsButton = await session.query(".mx_RoomHeader .mx_AccessibleButton[title=Settings]"); const settingsButton = await session.query(".mx_RoomHeader .mx_AccessibleButton[title=Settings]");
await settingsButton.click(); await settingsButton.click();
const checks = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=checkbox]"); const checks = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=checkbox]");
assert.equal(checks.length, 3); assert.equal(checks.length, 3);
const e2eEncryptionCheck = checks[0]; const e2eEncryptionCheck = checks[0];
const sendToUnverifiedDevices = checks[1]; const sendToUnverifiedDevices = checks[1];
const isDirectory = checks[2]; const isDirectory = checks[2];
if (typeof settings.directory === "boolean") { if (typeof settings.directory === "boolean") {
session.log.step(`sets directory listing to ${settings.directory}`); session.log.step(`sets directory listing to ${settings.directory}`);
await setCheckboxSetting(session, isDirectory, settings.directory); await setCheckboxSetting(session, isDirectory, settings.directory);
} }
if (typeof settings.encryption === "boolean") { if (typeof settings.encryption === "boolean") {
session.log.step(`sets room e2e encryption to ${settings.encryption}`); session.log.step(`sets room e2e encryption to ${settings.encryption}`);
const clicked = await setCheckboxSetting(session, e2eEncryptionCheck, settings.encryption); const clicked = await setCheckboxSetting(session, e2eEncryptionCheck, settings.encryption);
// if enabling, accept beta warning dialog // if enabling, accept beta warning dialog
if (clicked && settings.encryption) { if (clicked && settings.encryption) {
await acceptDialog(session, "encryption"); await acceptDialog(session, "encryption");
} }
} }
if (settings.visibility) { if (settings.visibility) {
session.log.step(`sets visibility to ${settings.visibility}`); session.log.step(`sets visibility to ${settings.visibility}`);
const radios = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=radio]"); const radios = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=radio]");
assert.equal(radios.length, 7); assert.equal(radios.length, 7);
const inviteOnly = radios[0]; const inviteOnly = radios[0];
const publicNoGuests = radios[1]; const publicNoGuests = radios[1];
const publicWithGuests = radios[2]; const publicWithGuests = radios[2];
if (settings.visibility === "invite_only") { if (settings.visibility === "invite_only") {
await inviteOnly.click(); await inviteOnly.click();
} else if (settings.visibility === "public_no_guests") { } else if (settings.visibility === "public_no_guests") {
await publicNoGuests.click(); await publicNoGuests.click();
} else if (settings.visibility === "public_with_guests") { } else if (settings.visibility === "public_with_guests") {
await publicWithGuests.click(); await publicWithGuests.click();
} else { } else {
throw new Error(`unrecognized room visibility setting: ${settings.visibility}`); throw new Error(`unrecognized room visibility setting: ${settings.visibility}`);
} }
session.log.done(); session.log.done();
} }
const saveButton = await session.query(".mx_RoomHeader_wrapper .mx_RoomHeader_textButton"); const saveButton = await session.query(".mx_RoomHeader_wrapper .mx_RoomHeader_textButton");
await saveButton.click(); await saveButton.click();
session.log.endGroup(); session.log.endGroup();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,13 +17,13 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function sendMessage(session, message) { module.exports = async function sendMessage(session, message) {
session.log.step(`writes "${message}" in room`); session.log.step(`writes "${message}" in room`);
// this selector needs to be the element that has contenteditable=true, // this selector needs to be the element that has contenteditable=true,
// not any if its parents, otherwise it behaves flaky at best. // not any if its parents, otherwise it behaves flaky at best.
const composer = await session.waitAndQuery('.mx_MessageComposer_editor'); const composer = await session.waitAndQuery('.mx_MessageComposer_editor');
await composer.type(message); await composer.type(message);
const text = await session.innerText(composer); const text = await session.innerText(composer);
assert.equal(text.trim(), message.trim()); assert.equal(text.trim(), message.trim());
await composer.press("Enter"); await composer.press("Enter");
session.log.done(); session.log.done();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,15 +17,15 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
const acceptInvite = require("./accept-invite") const acceptInvite = require("./accept-invite")
module.exports = async function acceptServerNoticesInviteAndConsent(session) { module.exports = async function acceptServerNoticesInviteAndConsent(session) {
await acceptInvite(session, "Server Notices"); await acceptInvite(session, "Server Notices");
session.log.step(`accepts terms & conditions`); session.log.step(`accepts terms & conditions`);
const consentLink = await session.waitAndQuery(".mx_EventTile_body a", 1000); const consentLink = await session.waitAndQuery(".mx_EventTile_body a", 1000);
const termsPagePromise = session.waitForNewPage(); const termsPagePromise = session.waitForNewPage();
await consentLink.click(); await consentLink.click();
const termsPage = await termsPagePromise; const termsPage = await termsPagePromise;
const acceptButton = await termsPage.$('input[type=submit]'); const acceptButton = await termsPage.$('input[type=submit]');
await acceptButton.click(); await acceptButton.click();
await session.delay(500); //TODO yuck, timers await session.delay(500); //TODO yuck, timers
await termsPage.close(); await termsPage.close();
session.log.done(); session.log.done();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -18,52 +18,52 @@ const acceptTerms = require('./consent');
const assert = require('assert'); const assert = require('assert');
module.exports = async function signup(session, username, password, homeserver) { module.exports = async function signup(session, username, password, homeserver) {
session.log.step("signs up"); session.log.step("signs up");
await session.goto(session.url('/#/register')); await session.goto(session.url('/#/register'));
//click 'Custom server' radio button //click 'Custom server' radio button
if (homeserver) { if (homeserver) {
const advancedRadioButton = await session.waitAndQuery('#advanced'); const advancedRadioButton = await session.waitAndQuery('#advanced');
await advancedRadioButton.click(); await advancedRadioButton.click();
} }
// wait until register button is visible // wait until register button is visible
await session.waitAndQuery('.mx_Login_submit[value=Register]'); await session.waitAndQuery('.mx_Login_submit[value=Register]');
//fill out form //fill out form
const loginFields = await session.queryAll('.mx_Login_field'); const loginFields = await session.queryAll('.mx_Login_field');
assert.strictEqual(loginFields.length, 7); assert.strictEqual(loginFields.length, 7);
const usernameField = loginFields[2]; const usernameField = loginFields[2];
const passwordField = loginFields[3]; const passwordField = loginFields[3];
const passwordRepeatField = loginFields[4]; const passwordRepeatField = loginFields[4];
const hsurlField = loginFields[5]; const hsurlField = loginFields[5];
await session.replaceInputText(usernameField, username); await session.replaceInputText(usernameField, username);
await session.replaceInputText(passwordField, password); await session.replaceInputText(passwordField, password);
await session.replaceInputText(passwordRepeatField, password); await session.replaceInputText(passwordRepeatField, password);
if (homeserver) { if (homeserver) {
await session.waitAndQuery('.mx_ServerConfig'); await session.waitAndQuery('.mx_ServerConfig');
await session.replaceInputText(hsurlField, homeserver); await session.replaceInputText(hsurlField, homeserver);
} }
//wait over a second because Registration/ServerConfig have a 1000ms //wait over a second because Registration/ServerConfig have a 1000ms
//delay to internally set the homeserver url //delay to internally set the homeserver url
//see Registration::render and ServerConfig::props::delayTimeMs //see Registration::render and ServerConfig::props::delayTimeMs
await session.delay(1200); await session.delay(1200);
/// focus on the button to make sure error validation /// focus on the button to make sure error validation
/// has happened before checking the form is good to go /// has happened before checking the form is good to go
const registerButton = await session.query('.mx_Login_submit'); const registerButton = await session.query('.mx_Login_submit');
await registerButton.focus(); await registerButton.focus();
//check no errors //check no errors
const error_text = await session.tryGetInnertext('.mx_Login_error'); const error_text = await session.tryGetInnertext('.mx_Login_error');
assert.strictEqual(!!error_text, false); assert.strictEqual(!!error_text, false);
//submit form //submit form
//await page.screenshot({path: "beforesubmit.png", fullPage: true}); //await page.screenshot({path: "beforesubmit.png", fullPage: true});
await registerButton.click(); await registerButton.click();
//confirm dialog saying you cant log back in without e-mail //confirm dialog saying you cant log back in without e-mail
const continueButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary'); const continueButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary');
await continueButton.click(); await continueButton.click();
//wait for registration to finish so the hash gets set //wait for registration to finish so the hash gets set
//onhashchange better? //onhashchange better?
await session.delay(2000); await session.delay(2000);
const url = session.page.url(); const url = session.page.url();
assert.strictEqual(url, session.url('/#/home')); assert.strictEqual(url, session.url('/#/home'));
session.log.done(); session.log.done();
} }

View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -17,26 +17,26 @@ limitations under the License.
const assert = require('assert'); const assert = require('assert');
module.exports = async function verifyDeviceForUser(session, name, expectedDevice) { module.exports = async function verifyDeviceForUser(session, name, expectedDevice) {
session.log.step(`verifies e2e device for ${name}`); session.log.step(`verifies e2e device for ${name}`);
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name"); const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
const membersAndNames = await Promise.all(memberNameElements.map(async (el) => { const membersAndNames = await Promise.all(memberNameElements.map(async (el) => {
return [el, await session.innerText(el)]; return [el, await session.innerText(el)];
})); }));
const matchingMember = membersAndNames.filter(([el, text]) => { const matchingMember = membersAndNames.filter(([el, text]) => {
return text === name; return text === name;
}).map(([el]) => el)[0]; }).map(([el]) => el)[0];
await matchingMember.click(); await matchingMember.click();
const firstVerifyButton = await session.waitAndQuery(".mx_MemberDeviceInfo_verify"); const firstVerifyButton = await session.waitAndQuery(".mx_MemberDeviceInfo_verify");
await firstVerifyButton.click(); await firstVerifyButton.click();
const dialogCodeFields = await session.waitAndQueryAll(".mx_QuestionDialog code"); const dialogCodeFields = await session.waitAndQueryAll(".mx_QuestionDialog code");
assert.equal(dialogCodeFields.length, 2); assert.equal(dialogCodeFields.length, 2);
const deviceId = await session.innerText(dialogCodeFields[0]); const deviceId = await session.innerText(dialogCodeFields[0]);
const deviceKey = await session.innerText(dialogCodeFields[1]); const deviceKey = await session.innerText(dialogCodeFields[1]);
assert.equal(expectedDevice.id, deviceId); assert.equal(expectedDevice.id, deviceId);
assert.equal(expectedDevice.key, deviceKey); assert.equal(expectedDevice.key, deviceKey);
const confirmButton = await session.query(".mx_Dialog_primary"); const confirmButton = await session.query(".mx_Dialog_primary");
await confirmButton.click(); await confirmButton.click();
const closeMemberInfo = await session.query(".mx_MemberInfo_cancel"); const closeMemberInfo = await session.query(".mx_MemberInfo_cancel");
await closeMemberInfo.click(); await closeMemberInfo.click();
session.log.done(); session.log.done();
} }

106
start.js
View File

@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -24,64 +24,64 @@ const noLogs = process.argv.indexOf("--no-logs") !== -1;
const debug = process.argv.indexOf("--debug") !== -1; const debug = process.argv.indexOf("--debug") !== -1;
async function runTests() { async function runTests() {
let sessions = []; let sessions = [];
console.log("running tests ..."); console.log("running tests ...");
const options = {}; const options = {};
if (debug) { if (debug) {
// options.slowMo = 10; options.slowMo = 20;
options.headless = false; options.headless = false;
} }
if (process.env.CHROME_PATH) { if (process.env.CHROME_PATH) {
const path = process.env.CHROME_PATH; const path = process.env.CHROME_PATH;
console.log(`(using external chrome/chromium at ${path}, make sure it's compatible with puppeteer)`); console.log(`(using external chrome/chromium at ${path}, make sure it's compatible with puppeteer)`);
options.executablePath = path; options.executablePath = path;
}
async function createSession(username) {
const session = await RiotSession.create(username, options, riotserver);
sessions.push(session);
return session;
}
let failure = false;
try {
await scenario(createSession);
} catch(err) {
failure = true;
console.log('failure: ', err);
if (!noLogs) {
for(let i = 0; i < sessions.length; ++i) {
const session = sessions[i];
documentHtml = await session.page.content();
console.log(`---------------- START OF ${session.username} LOGS ----------------`);
console.log('---------------- console.log output:');
console.log(session.consoleLogs());
console.log('---------------- network requests:');
console.log(session.networkLogs());
console.log('---------------- document html:');
console.log(documentHtml);
console.log(`---------------- END OF ${session.username} LOGS ----------------`);
}
} }
}
// wait 5 minutes on failure if not running headless async function createSession(username) {
// to inspect what went wrong const session = await RiotSession.create(username, options, riotserver);
if (failure && options.headless === false) { sessions.push(session);
await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000)); return session;
} }
await Promise.all(sessions.map((session) => session.close())); let failure = false;
try {
await scenario(createSession);
} catch(err) {
failure = true;
console.log('failure: ', err);
if (!noLogs) {
for(let i = 0; i < sessions.length; ++i) {
const session = sessions[i];
documentHtml = await session.page.content();
console.log(`---------------- START OF ${session.username} LOGS ----------------`);
console.log('---------------- console.log output:');
console.log(session.consoleLogs());
console.log('---------------- network requests:');
console.log(session.networkLogs());
console.log('---------------- document html:');
console.log(documentHtml);
console.log(`---------------- END OF ${session.username} LOGS ----------------`);
}
}
}
if (failure) { // wait 5 minutes on failure if not running headless
process.exit(-1); // to inspect what went wrong
} else { if (failure && options.headless === false) {
console.log('all tests finished successfully'); await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000));
} }
await Promise.all(sessions.map((session) => session.close()));
if (failure) {
process.exit(-1);
} else {
console.log('all tests finished successfully');
}
} }
runTests().catch(function(err) { runTests().catch(function(err) {
console.log(err); console.log(err);
process.exit(-1); process.exit(-1);
}); });

View File

@ -9,8 +9,8 @@ PORT=5005
BASE_DIR=$(readlink -f $(dirname $0)) BASE_DIR=$(readlink -f $(dirname $0))
if [ -d $BASE_DIR/$SERVER_DIR ]; then if [ -d $BASE_DIR/$SERVER_DIR ]; then
echo "synapse is already installed" echo "synapse is already installed"
exit exit
fi fi
cd $BASE_DIR cd $BASE_DIR