Merge pull request #8 from matrix-org/bwindels/indentation
bring indentation in line with other front-end projects
This commit is contained in:
commit
956688237a
22 changed files with 583 additions and 560 deletions
23
.editorconfig
Normal file
23
.editorconfig
Normal 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
|
24
package.json
24
package.json
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"name": "e2e-tests",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"puppeteer": "^1.6.0"
|
||||
}
|
||||
"name": "e2e-tests",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"puppeteer": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ RIOT_BRANCH=master
|
|||
|
||||
BASE_DIR=$(readlink -f $(dirname $0))
|
||||
if [ -d $BASE_DIR/riot-web ]; then
|
||||
echo "riot is already installed"
|
||||
exit
|
||||
echo "riot is already installed"
|
||||
exit
|
||||
fi
|
||||
|
||||
cd $BASE_DIR
|
||||
|
|
|
@ -5,7 +5,7 @@ PIDFILE=$BASE_DIR/riot.pid
|
|||
CONFIG_BACKUP=config.e2etests_backup.json
|
||||
|
||||
if [ -f $PIDFILE ]; then
|
||||
exit
|
||||
exit
|
||||
fi
|
||||
|
||||
cd $BASE_DIR/
|
||||
|
@ -14,29 +14,29 @@ pushd riot-web/webapp/ > /dev/null
|
|||
|
||||
# backup config file before we copy template
|
||||
if [ -f config.json ]; then
|
||||
mv config.json $CONFIG_BACKUP
|
||||
mv config.json $CONFIG_BACKUP
|
||||
fi
|
||||
cp $BASE_DIR/config-template/config.json .
|
||||
|
||||
LOGFILE=$(mktemp)
|
||||
# run web server in the background, showing output on error
|
||||
(
|
||||
python -m SimpleHTTPServer $PORT > $LOGFILE 2>&1 &
|
||||
PID=$!
|
||||
echo $PID > $PIDFILE
|
||||
# wait so subshell does not exit
|
||||
# otherwise sleep below would not work
|
||||
wait $PID; RESULT=$?
|
||||
python -m SimpleHTTPServer $PORT > $LOGFILE 2>&1 &
|
||||
PID=$!
|
||||
echo $PID > $PIDFILE
|
||||
# wait so subshell does not exit
|
||||
# otherwise sleep below would not work
|
||||
wait $PID; RESULT=$?
|
||||
|
||||
# NOT expected SIGTERM (128 + 15)
|
||||
# from stop.sh?
|
||||
if [ $RESULT -ne 143 ]; then
|
||||
echo "failed"
|
||||
cat $LOGFILE
|
||||
rm $PIDFILE 2> /dev/null
|
||||
fi
|
||||
rm $LOGFILE
|
||||
exit $RESULT
|
||||
# NOT expected SIGTERM (128 + 15)
|
||||
# from stop.sh?
|
||||
if [ $RESULT -ne 143 ]; then
|
||||
echo "failed"
|
||||
cat $LOGFILE
|
||||
rm $PIDFILE 2> /dev/null
|
||||
fi
|
||||
rm $LOGFILE
|
||||
exit $RESULT
|
||||
)&
|
||||
# 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
|
||||
|
@ -46,6 +46,6 @@ sleep 0.5 &
|
|||
wait -n; RESULT=$?
|
||||
# return exit code of first child to exit
|
||||
if [ $RESULT -eq 0 ]; then
|
||||
echo "running"
|
||||
echo "running"
|
||||
fi
|
||||
exit $RESULT
|
||||
|
|
20
riot/stop.sh
20
riot/stop.sh
|
@ -6,15 +6,15 @@ CONFIG_BACKUP=config.e2etests_backup.json
|
|||
cd $BASE_DIR
|
||||
|
||||
if [ -f $PIDFILE ]; then
|
||||
echo "stopping riot server ..."
|
||||
PID=$(cat $PIDFILE)
|
||||
rm $PIDFILE
|
||||
kill $PID
|
||||
echo "stopping riot server ..."
|
||||
PID=$(cat $PIDFILE)
|
||||
rm $PIDFILE
|
||||
kill $PID
|
||||
|
||||
# revert config file
|
||||
cd riot-web/webapp
|
||||
rm config.json
|
||||
if [ -f $CONFIG_BACKUP ]; then
|
||||
mv $CONFIG_BACKUP config.json
|
||||
fi
|
||||
# revert config file
|
||||
cd riot-web/webapp
|
||||
rm config.json
|
||||
if [ -f $CONFIG_BACKUP ]; then
|
||||
mv $CONFIG_BACKUP config.json
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -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 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
|
||||
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");
|
||||
|
||||
module.exports = async function scenario(createSession) {
|
||||
async function createUser(username) {
|
||||
const session = await createSession(username);
|
||||
await signup(session, session.username, 'testtest');
|
||||
await acceptServerNoticesInviteAndConsent(session);
|
||||
return session;
|
||||
}
|
||||
async function createUser(username) {
|
||||
const session = await createSession(username);
|
||||
await signup(session, session.username, 'testtest');
|
||||
await acceptServerNoticesInviteAndConsent(session);
|
||||
return session;
|
||||
}
|
||||
|
||||
const alice = await createUser("alice");
|
||||
const bob = await createUser("bob");
|
||||
const alice = await createUser("alice");
|
||||
const bob = await createUser("bob");
|
||||
|
||||
await createDirectoryRoomAndTalk(alice, bob);
|
||||
await createE2ERoomAndTalk(alice, bob);
|
||||
await createDirectoryRoomAndTalk(alice, bob);
|
||||
await createE2ERoomAndTalk(alice, bob);
|
||||
}
|
||||
|
||||
async function createDirectoryRoomAndTalk(alice, bob) {
|
||||
console.log(" creating a public room and join through directory:");
|
||||
const room = 'test';
|
||||
await createRoom(alice, room);
|
||||
await changeRoomSettings(alice, {directory: true, visibility: "public_no_guests"});
|
||||
await join(bob, room);
|
||||
const bobMessage = "hi Alice!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage});
|
||||
const aliceMessage = "hi Bob, welcome!"
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage});
|
||||
console.log(" creating a public room and join through directory:");
|
||||
const room = 'test';
|
||||
await createRoom(alice, room);
|
||||
await changeRoomSettings(alice, {directory: true, visibility: "public_no_guests"});
|
||||
await join(bob, room);
|
||||
const bobMessage = "hi Alice!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage});
|
||||
const aliceMessage = "hi Bob, welcome!"
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage});
|
||||
}
|
||||
|
||||
async function createE2ERoomAndTalk(alice, bob) {
|
||||
console.log(" creating an e2e encrypted room and join through invite:");
|
||||
const room = "secrets";
|
||||
await createRoom(bob, room);
|
||||
await changeRoomSettings(bob, {encryption: true});
|
||||
await invite(bob, "@alice:localhost");
|
||||
await acceptInvite(alice, room);
|
||||
const bobDevice = await getE2EDeviceFromSettings(bob);
|
||||
// wait some time for the encryption warning dialog
|
||||
// to appear after closing the settings
|
||||
await bob.delay(500);
|
||||
await acceptDialog(bob, "encryption");
|
||||
const aliceDevice = await getE2EDeviceFromSettings(alice);
|
||||
// wait some time for the encryption warning dialog
|
||||
// to appear after closing the settings
|
||||
await alice.delay(500);
|
||||
await acceptDialog(alice, "encryption");
|
||||
await verifyDeviceForUser(bob, "alice", aliceDevice);
|
||||
await verifyDeviceForUser(alice, "bob", bobDevice);
|
||||
const aliceMessage = "Guess what I just heard?!"
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage, encrypted: true});
|
||||
const bobMessage = "You've got to tell me!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true});
|
||||
console.log(" creating an e2e encrypted room and join through invite:");
|
||||
const room = "secrets";
|
||||
await createRoom(bob, room);
|
||||
await changeRoomSettings(bob, {encryption: true});
|
||||
await invite(bob, "@alice:localhost");
|
||||
await acceptInvite(alice, room);
|
||||
const bobDevice = await getE2EDeviceFromSettings(bob);
|
||||
// wait some time for the encryption warning dialog
|
||||
// to appear after closing the settings
|
||||
await bob.delay(500);
|
||||
await acceptDialog(bob, "encryption");
|
||||
const aliceDevice = await getE2EDeviceFromSettings(alice);
|
||||
// wait some time for the encryption warning dialog
|
||||
// to appear after closing the settings
|
||||
await alice.delay(500);
|
||||
await acceptDialog(alice, "encryption");
|
||||
await verifyDeviceForUser(bob, "alice", aliceDevice);
|
||||
await verifyDeviceForUser(alice, "bob", bobDevice);
|
||||
const aliceMessage = "Guess what I just heard?!"
|
||||
await sendMessage(alice, aliceMessage);
|
||||
await receiveMessage(bob, {sender: "alice", body: aliceMessage, encrypted: true});
|
||||
const bobMessage = "You've got to tell me!";
|
||||
await sendMessage(bob, bobMessage);
|
||||
await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true});
|
||||
}
|
||||
|
|
304
src/session.js
304
src/session.js
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,180 +17,180 @@ limitations under the License.
|
|||
const puppeteer = require('puppeteer');
|
||||
|
||||
class LogBuffer {
|
||||
constructor(page, eventName, eventMapper, reduceAsync=false, initialValue = "") {
|
||||
this.buffer = initialValue;
|
||||
page.on(eventName, (arg) => {
|
||||
const result = eventMapper(arg);
|
||||
if (reduceAsync) {
|
||||
result.then((r) => this.buffer += r);
|
||||
}
|
||||
else {
|
||||
this.buffer += result;
|
||||
}
|
||||
});
|
||||
}
|
||||
constructor(page, eventName, eventMapper, reduceAsync=false, initialValue = "") {
|
||||
this.buffer = initialValue;
|
||||
page.on(eventName, (arg) => {
|
||||
const result = eventMapper(arg);
|
||||
if (reduceAsync) {
|
||||
result.then((r) => this.buffer += r);
|
||||
}
|
||||
else {
|
||||
this.buffer += result;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class Logger {
|
||||
constructor(username) {
|
||||
this.indent = 0;
|
||||
this.username = username;
|
||||
}
|
||||
constructor(username) {
|
||||
this.indent = 0;
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
startGroup(description) {
|
||||
const indent = " ".repeat(this.indent * 2);
|
||||
console.log(`${indent} * ${this.username} ${description}:`);
|
||||
this.indent += 1;
|
||||
}
|
||||
startGroup(description) {
|
||||
const indent = " ".repeat(this.indent * 2);
|
||||
console.log(`${indent} * ${this.username} ${description}:`);
|
||||
this.indent += 1;
|
||||
}
|
||||
|
||||
endGroup() {
|
||||
this.indent -= 1;
|
||||
}
|
||||
endGroup() {
|
||||
this.indent -= 1;
|
||||
}
|
||||
|
||||
step(description) {
|
||||
const indent = " ".repeat(this.indent * 2);
|
||||
process.stdout.write(`${indent} * ${this.username} ${description} ... `);
|
||||
}
|
||||
step(description) {
|
||||
const indent = " ".repeat(this.indent * 2);
|
||||
process.stdout.write(`${indent} * ${this.username} ${description} ... `);
|
||||
}
|
||||
|
||||
done(status = "done") {
|
||||
process.stdout.write(status + "\n");
|
||||
}
|
||||
done(status = "done") {
|
||||
process.stdout.write(status + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = class RiotSession {
|
||||
constructor(browser, page, username, riotserver) {
|
||||
this.browser = browser;
|
||||
this.page = page;
|
||||
this.riotserver = riotserver;
|
||||
this.username = username;
|
||||
this.consoleLog = new LogBuffer(page, "console", (msg) => `${msg.text()}\n`);
|
||||
this.networkLog = new LogBuffer(page, "requestfinished", async (req) => {
|
||||
const type = req.resourceType();
|
||||
const response = await req.response();
|
||||
return `${type} ${response.status()} ${req.method()} ${req.url()} \n`;
|
||||
}, true);
|
||||
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();
|
||||
constructor(browser, page, username, riotserver) {
|
||||
this.browser = browser;
|
||||
this.page = page;
|
||||
this.riotserver = riotserver;
|
||||
this.username = username;
|
||||
this.consoleLog = new LogBuffer(page, "console", (msg) => `${msg.text()}\n`);
|
||||
this.networkLog = new LogBuffer(page, "requestfinished", async (req) => {
|
||||
const type = req.resourceType();
|
||||
const response = await req.response();
|
||||
return `${type} ${response.status()} ${req.method()} ${req.url()} \n`;
|
||||
}, true);
|
||||
this.log = new Logger(this.username);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async getElementProperty(handle, property) {
|
||||
const propHandle = await handle.getProperty(property);
|
||||
return await propHandle.jsonValue();
|
||||
}
|
||||
|
||||
innerText(field) {
|
||||
return this.getElementProperty(field, 'innerText');
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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 printElements(label, elements) {
|
||||
console.log(label, await Promise.all(elements.map(getOuterHTML)));
|
||||
}
|
||||
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 replaceInputText(input, text) {
|
||||
// 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);
|
||||
}
|
||||
async getElementProperty(handle, property) {
|
||||
const propHandle = await handle.getProperty(property);
|
||||
return await propHandle.jsonValue();
|
||||
}
|
||||
|
||||
query(selector) {
|
||||
return this.page.$(selector);
|
||||
}
|
||||
|
||||
waitAndQuery(selector, timeout = 500) {
|
||||
return this.page.waitForSelector(selector, {visible: true, timeout});
|
||||
}
|
||||
innerText(field) {
|
||||
return this.getElementProperty(field, 'innerText');
|
||||
}
|
||||
|
||||
queryAll(selector) {
|
||||
return this.page.$$(selector);
|
||||
}
|
||||
getOuterHTML(element_handle) {
|
||||
return this.getElementProperty(field, 'outerHTML');
|
||||
}
|
||||
|
||||
async waitAndQueryAll(selector, timeout = 500) {
|
||||
await this.waitAndQuery(selector, timeout);
|
||||
return await this.queryAll(selector);
|
||||
}
|
||||
consoleLogs() {
|
||||
return this.consoleLog.buffer;
|
||||
}
|
||||
|
||||
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);
|
||||
networkLogs() {
|
||||
return this.networkLog.buffer;
|
||||
}
|
||||
|
||||
const callback = async (target) => {
|
||||
clearTimeout(timeoutHandle);
|
||||
const page = await target.page();
|
||||
resolve(page);
|
||||
};
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.browser.once('targetcreated', callback);
|
||||
});
|
||||
}
|
||||
async printElements(label, elements) {
|
||||
console.log(label, await Promise.all(elements.map(getOuterHTML)));
|
||||
}
|
||||
|
||||
goto(url) {
|
||||
return this.page.goto(url);
|
||||
}
|
||||
async replaceInputText(input, text) {
|
||||
// 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) {
|
||||
return this.riotserver + path;
|
||||
}
|
||||
query(selector) {
|
||||
return this.page.$(selector);
|
||||
}
|
||||
|
||||
delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
waitAndQuery(selector, timeout = 500) {
|
||||
return this.page.waitForSelector(selector, {visible: true, timeout});
|
||||
}
|
||||
|
||||
close() {
|
||||
return this.browser.close();
|
||||
}
|
||||
queryAll(selector) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -18,24 +18,24 @@ const assert = require('assert');
|
|||
const {acceptDialogMaybe} = require('./dialog');
|
||||
|
||||
module.exports = async function acceptInvite(session, name) {
|
||||
session.log.step(`accepts "${name}" invite`);
|
||||
//TODO: brittle selector
|
||||
const invitesHandles = await session.waitAndQueryAll('.mx_RoomTile_name.mx_RoomTile_invite', 1000);
|
||||
const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => {
|
||||
const text = await session.innerText(inviteHandle);
|
||||
return {inviteHandle, text};
|
||||
}));
|
||||
const inviteHandle = invitesWithText.find(({inviteHandle, text}) => {
|
||||
return text.trim() === name;
|
||||
}).inviteHandle;
|
||||
session.log.step(`accepts "${name}" invite`);
|
||||
//TODO: brittle selector
|
||||
const invitesHandles = await session.waitAndQueryAll('.mx_RoomTile_name.mx_RoomTile_invite', 1000);
|
||||
const invitesWithText = await Promise.all(invitesHandles.map(async (inviteHandle) => {
|
||||
const text = await session.innerText(inviteHandle);
|
||||
return {inviteHandle, text};
|
||||
}));
|
||||
const inviteHandle = invitesWithText.find(({inviteHandle, text}) => {
|
||||
return text.trim() === name;
|
||||
}).inviteHandle;
|
||||
|
||||
await inviteHandle.click();
|
||||
await inviteHandle.click();
|
||||
|
||||
const acceptInvitationLink = await session.waitAndQuery(".mx_RoomPreviewBar_join_text a:first-child");
|
||||
await acceptInvitationLink.click();
|
||||
const acceptInvitationLink = await session.waitAndQuery(".mx_RoomPreviewBar_join_text a:first-child");
|
||||
await acceptInvitationLink.click();
|
||||
|
||||
// accept e2e warning dialog
|
||||
acceptDialogMaybe(session, "encryption");
|
||||
// accept e2e warning dialog
|
||||
acceptDialogMaybe(session, "encryption");
|
||||
|
||||
session.log.done();
|
||||
session.log.done();
|
||||
}
|
|
@ -17,11 +17,11 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function acceptTerms(session) {
|
||||
const reviewTermsButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary', 5000);
|
||||
const termsPagePromise = session.waitForNewPage();
|
||||
await reviewTermsButton.click();
|
||||
const termsPage = await termsPagePromise;
|
||||
const acceptButton = await termsPage.$('input[type=submit]');
|
||||
await acceptButton.click();
|
||||
await session.delay(500); //TODO yuck, timers
|
||||
const reviewTermsButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary', 5000);
|
||||
const termsPagePromise = session.waitForNewPage();
|
||||
await reviewTermsButton.click();
|
||||
const termsPage = await termsPagePromise;
|
||||
const acceptButton = await termsPage.$('input[type=submit]');
|
||||
await acceptButton.click();
|
||||
await session.delay(500); //TODO yuck, timers
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,17 +17,17 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function createRoom(session, roomName) {
|
||||
session.log.step(`creates room "${roomName}"`);
|
||||
//TODO: brittle selector
|
||||
const createRoomButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Create new room"]');
|
||||
await createRoomButton.click();
|
||||
session.log.step(`creates room "${roomName}"`);
|
||||
//TODO: brittle selector
|
||||
const createRoomButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Create new room"]');
|
||||
await createRoomButton.click();
|
||||
|
||||
const roomNameInput = await session.waitAndQuery('.mx_CreateRoomDialog_input');
|
||||
await session.replaceInputText(roomNameInput, roomName);
|
||||
const roomNameInput = await session.waitAndQuery('.mx_CreateRoomDialog_input');
|
||||
await session.replaceInputText(roomNameInput, roomName);
|
||||
|
||||
const createButton = await session.waitAndQuery('.mx_Dialog_primary');
|
||||
await createButton.click();
|
||||
const createButton = await session.waitAndQuery('.mx_Dialog_primary');
|
||||
await createButton.click();
|
||||
|
||||
await session.waitAndQuery('.mx_MessageComposer');
|
||||
session.log.done();
|
||||
await session.waitAndQuery('.mx_MessageComposer');
|
||||
session.log.done();
|
||||
}
|
|
@ -18,30 +18,30 @@ const assert = require('assert');
|
|||
|
||||
|
||||
async function acceptDialog(session, expectedContent) {
|
||||
const foundDialog = await acceptDialogMaybe(session, expectedContent);
|
||||
if (!foundDialog) {
|
||||
throw new Error("could not find a dialog");
|
||||
}
|
||||
const foundDialog = await acceptDialogMaybe(session, expectedContent);
|
||||
if (!foundDialog) {
|
||||
throw new Error("could not find a dialog");
|
||||
}
|
||||
}
|
||||
|
||||
async function acceptDialogMaybe(session, expectedContent) {
|
||||
let dialog = null;
|
||||
try {
|
||||
dialog = await session.waitAndQuery(".mx_QuestionDialog", 100);
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
if (expectedContent) {
|
||||
const contentElement = await dialog.$(".mx_Dialog_content");
|
||||
const content = await (await contentElement.getProperty("innerText")).jsonValue();
|
||||
assert.ok(content.indexOf(expectedContent) !== -1);
|
||||
}
|
||||
const primaryButton = await dialog.$(".mx_Dialog_primary");
|
||||
await primaryButton.click();
|
||||
return true;
|
||||
let dialog = null;
|
||||
try {
|
||||
dialog = await session.waitAndQuery(".mx_QuestionDialog", 100);
|
||||
} catch(err) {
|
||||
return false;
|
||||
}
|
||||
if (expectedContent) {
|
||||
const contentElement = await dialog.$(".mx_Dialog_content");
|
||||
const content = await (await contentElement.getProperty("innerText")).jsonValue();
|
||||
assert.ok(content.indexOf(expectedContent) !== -1);
|
||||
}
|
||||
const primaryButton = await dialog.$(".mx_Dialog_primary");
|
||||
await primaryButton.click();
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
acceptDialog,
|
||||
acceptDialogMaybe,
|
||||
acceptDialog,
|
||||
acceptDialogMaybe,
|
||||
};
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function getE2EDeviceFromSettings(session) {
|
||||
session.log.step(`gets e2e device/key from settings`);
|
||||
const settingsButton = await session.query('.mx_BottomLeftMenu_settings');
|
||||
await settingsButton.click();
|
||||
const deviceAndKey = await session.waitAndQueryAll(".mx_UserSettings_section.mx_UserSettings_cryptoSection code");
|
||||
assert.equal(deviceAndKey.length, 2);
|
||||
const id = await (await deviceAndKey[0].getProperty("innerText")).jsonValue();
|
||||
const key = await (await deviceAndKey[1].getProperty("innerText")).jsonValue();
|
||||
const closeButton = await session.query(".mx_RoomHeader_cancelButton");
|
||||
await closeButton.click();
|
||||
session.log.done();
|
||||
return {id, key};
|
||||
session.log.step(`gets e2e device/key from settings`);
|
||||
const settingsButton = await session.query('.mx_BottomLeftMenu_settings');
|
||||
await settingsButton.click();
|
||||
const deviceAndKey = await session.waitAndQueryAll(".mx_UserSettings_section.mx_UserSettings_cryptoSection code");
|
||||
assert.equal(deviceAndKey.length, 2);
|
||||
const id = await (await deviceAndKey[0].getProperty("innerText")).jsonValue();
|
||||
const key = await (await deviceAndKey[1].getProperty("innerText")).jsonValue();
|
||||
const closeButton = await session.query(".mx_RoomHeader_cancelButton");
|
||||
await closeButton.click();
|
||||
session.log.done();
|
||||
return {id, key};
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,14 +17,14 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function invite(session, userId) {
|
||||
session.log.step(`invites "${userId}" to room`);
|
||||
await session.delay(200);
|
||||
const inviteButton = await session.waitAndQuery(".mx_RightPanel_invite");
|
||||
await inviteButton.click();
|
||||
const inviteTextArea = await session.waitAndQuery(".mx_ChatInviteDialog textarea");
|
||||
await inviteTextArea.type(userId);
|
||||
await inviteTextArea.press("Enter");
|
||||
const confirmButton = await session.query(".mx_Dialog_primary");
|
||||
await confirmButton.click();
|
||||
session.log.done();
|
||||
session.log.step(`invites "${userId}" to room`);
|
||||
await session.delay(200);
|
||||
const inviteButton = await session.waitAndQuery(".mx_RightPanel_invite");
|
||||
await inviteButton.click();
|
||||
const inviteTextArea = await session.waitAndQuery(".mx_ChatInviteDialog textarea");
|
||||
await inviteTextArea.type(userId);
|
||||
await inviteTextArea.press("Enter");
|
||||
const confirmButton = await session.query(".mx_Dialog_primary");
|
||||
await confirmButton.click();
|
||||
session.log.done();
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,20 +17,20 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function join(session, roomName) {
|
||||
session.log.step(`joins room "${roomName}"`);
|
||||
//TODO: brittle selector
|
||||
const directoryButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Room directory"]');
|
||||
await directoryButton.click();
|
||||
session.log.step(`joins room "${roomName}"`);
|
||||
//TODO: brittle selector
|
||||
const directoryButton = await session.waitAndQuery('.mx_RoleButton[aria-label="Room directory"]');
|
||||
await directoryButton.click();
|
||||
|
||||
const roomInput = await session.waitAndQuery('.mx_DirectorySearchBox_input');
|
||||
await session.replaceInputText(roomInput, roomName);
|
||||
const roomInput = await session.waitAndQuery('.mx_DirectorySearchBox_input');
|
||||
await session.replaceInputText(roomInput, roomName);
|
||||
|
||||
const firstRoomLabel = await session.waitAndQuery('.mx_RoomDirectory_table .mx_RoomDirectory_name:first-child', 1000);
|
||||
await firstRoomLabel.click();
|
||||
const firstRoomLabel = await session.waitAndQuery('.mx_RoomDirectory_table .mx_RoomDirectory_name:first-child', 1000);
|
||||
await firstRoomLabel.click();
|
||||
|
||||
const joinLink = await session.waitAndQuery('.mx_RoomPreviewBar_join_text a');
|
||||
await joinLink.click();
|
||||
const joinLink = await session.waitAndQuery('.mx_RoomPreviewBar_join_text a');
|
||||
await joinLink.click();
|
||||
|
||||
await session.waitAndQuery('.mx_MessageComposer');
|
||||
session.log.done();
|
||||
await session.waitAndQuery('.mx_MessageComposer');
|
||||
session.log.done();
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,33 +17,33 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function receiveMessage(session, message) {
|
||||
session.log.step(`receives message "${message.body}" from ${message.sender}`);
|
||||
// wait for a response to come in that contains the message
|
||||
// crude, but effective
|
||||
await session.page.waitForResponse(async (response) => {
|
||||
if (response.request().url().indexOf("/sync") === -1) {
|
||||
return false;
|
||||
}
|
||||
const body = await response.text();
|
||||
session.log.step(`receives message "${message.body}" from ${message.sender}`);
|
||||
// wait for a response to come in that contains the message
|
||||
// crude, but effective
|
||||
await session.page.waitForResponse(async (response) => {
|
||||
if (response.request().url().indexOf("/sync") === -1) {
|
||||
return false;
|
||||
}
|
||||
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) {
|
||||
return body.indexOf(message.sender) !== -1 &&
|
||||
body.indexOf("m.room.encrypted") !== -1;
|
||||
} else {
|
||||
return body.indexOf(message.body) !== -1;
|
||||
const e2eIcon = await lastTile.$(".mx_EventTile_e2eIcon");
|
||||
assert.ok(e2eIcon);
|
||||
}
|
||||
});
|
||||
// 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) {
|
||||
const e2eIcon = await lastTile.$(".mx_EventTile_e2eIcon");
|
||||
assert.ok(e2eIcon);
|
||||
}
|
||||
assert.equal(body, message.body);
|
||||
assert.equal(sender, message.sender);
|
||||
session.log.done();
|
||||
assert.equal(body, message.body);
|
||||
assert.equal(sender, message.sender);
|
||||
session.log.done();
|
||||
}
|
|
@ -18,66 +18,66 @@ const assert = require('assert');
|
|||
const {acceptDialog} = require('./dialog');
|
||||
|
||||
async function setCheckboxSetting(session, checkbox, enabled) {
|
||||
const checked = await session.getElementProperty(checkbox, "checked");
|
||||
assert.equal(typeof checked, "boolean");
|
||||
if (checked !== enabled) {
|
||||
await checkbox.click();
|
||||
session.log.done();
|
||||
return true;
|
||||
} else {
|
||||
session.log.done("already set");
|
||||
}
|
||||
const checked = await session.getElementProperty(checkbox, "checked");
|
||||
assert.equal(typeof checked, "boolean");
|
||||
if (checked !== enabled) {
|
||||
await checkbox.click();
|
||||
session.log.done();
|
||||
return true;
|
||||
} else {
|
||||
session.log.done("already set");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async function changeRoomSettings(session, settings) {
|
||||
session.log.startGroup(`changes the room settings`);
|
||||
/// XXX delay is needed here, possible because the header is being rerendered
|
||||
/// click doesn't do anything otherwise
|
||||
await session.delay(500);
|
||||
const settingsButton = await session.query(".mx_RoomHeader .mx_AccessibleButton[title=Settings]");
|
||||
await settingsButton.click();
|
||||
const checks = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=checkbox]");
|
||||
assert.equal(checks.length, 3);
|
||||
const e2eEncryptionCheck = checks[0];
|
||||
const sendToUnverifiedDevices = checks[1];
|
||||
const isDirectory = checks[2];
|
||||
session.log.startGroup(`changes the room settings`);
|
||||
/// XXX delay is needed here, possible because the header is being rerendered
|
||||
/// click doesn't do anything otherwise
|
||||
await session.delay(500);
|
||||
const settingsButton = await session.query(".mx_RoomHeader .mx_AccessibleButton[title=Settings]");
|
||||
await settingsButton.click();
|
||||
const checks = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=checkbox]");
|
||||
assert.equal(checks.length, 3);
|
||||
const e2eEncryptionCheck = checks[0];
|
||||
const sendToUnverifiedDevices = checks[1];
|
||||
const isDirectory = checks[2];
|
||||
|
||||
if (typeof settings.directory === "boolean") {
|
||||
session.log.step(`sets directory listing to ${settings.directory}`);
|
||||
await setCheckboxSetting(session, isDirectory, settings.directory);
|
||||
}
|
||||
if (typeof settings.directory === "boolean") {
|
||||
session.log.step(`sets directory listing to ${settings.directory}`);
|
||||
await setCheckboxSetting(session, isDirectory, settings.directory);
|
||||
}
|
||||
|
||||
if (typeof settings.encryption === "boolean") {
|
||||
session.log.step(`sets room e2e encryption to ${settings.encryption}`);
|
||||
const clicked = await setCheckboxSetting(session, e2eEncryptionCheck, settings.encryption);
|
||||
// if enabling, accept beta warning dialog
|
||||
if (clicked && settings.encryption) {
|
||||
await acceptDialog(session, "encryption");
|
||||
}
|
||||
}
|
||||
if (typeof settings.encryption === "boolean") {
|
||||
session.log.step(`sets room e2e encryption to ${settings.encryption}`);
|
||||
const clicked = await setCheckboxSetting(session, e2eEncryptionCheck, settings.encryption);
|
||||
// if enabling, accept beta warning dialog
|
||||
if (clicked && settings.encryption) {
|
||||
await acceptDialog(session, "encryption");
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.visibility) {
|
||||
session.log.step(`sets visibility to ${settings.visibility}`);
|
||||
const radios = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=radio]");
|
||||
assert.equal(radios.length, 7);
|
||||
const inviteOnly = radios[0];
|
||||
const publicNoGuests = radios[1];
|
||||
const publicWithGuests = radios[2];
|
||||
|
||||
if (settings.visibility === "invite_only") {
|
||||
await inviteOnly.click();
|
||||
} else if (settings.visibility === "public_no_guests") {
|
||||
await publicNoGuests.click();
|
||||
} else if (settings.visibility === "public_with_guests") {
|
||||
await publicWithGuests.click();
|
||||
} else {
|
||||
throw new Error(`unrecognized room visibility setting: ${settings.visibility}`);
|
||||
}
|
||||
session.log.done();
|
||||
}
|
||||
if (settings.visibility) {
|
||||
session.log.step(`sets visibility to ${settings.visibility}`);
|
||||
const radios = await session.waitAndQueryAll(".mx_RoomSettings_settings input[type=radio]");
|
||||
assert.equal(radios.length, 7);
|
||||
const inviteOnly = radios[0];
|
||||
const publicNoGuests = radios[1];
|
||||
const publicWithGuests = radios[2];
|
||||
|
||||
if (settings.visibility === "invite_only") {
|
||||
await inviteOnly.click();
|
||||
} else if (settings.visibility === "public_no_guests") {
|
||||
await publicNoGuests.click();
|
||||
} else if (settings.visibility === "public_with_guests") {
|
||||
await publicWithGuests.click();
|
||||
} else {
|
||||
throw new Error(`unrecognized room visibility setting: ${settings.visibility}`);
|
||||
}
|
||||
session.log.done();
|
||||
}
|
||||
|
||||
const saveButton = await session.query(".mx_RoomHeader_wrapper .mx_RoomHeader_textButton");
|
||||
await saveButton.click();
|
||||
const saveButton = await session.query(".mx_RoomHeader_wrapper .mx_RoomHeader_textButton");
|
||||
await saveButton.click();
|
||||
|
||||
session.log.endGroup();
|
||||
session.log.endGroup();
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,13 +17,13 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function sendMessage(session, message) {
|
||||
session.log.step(`writes "${message}" in room`);
|
||||
// this selector needs to be the element that has contenteditable=true,
|
||||
// not any if its parents, otherwise it behaves flaky at best.
|
||||
const composer = await session.waitAndQuery('.mx_MessageComposer_editor');
|
||||
await composer.type(message);
|
||||
const text = await session.innerText(composer);
|
||||
assert.equal(text.trim(), message.trim());
|
||||
await composer.press("Enter");
|
||||
session.log.done();
|
||||
session.log.step(`writes "${message}" in room`);
|
||||
// this selector needs to be the element that has contenteditable=true,
|
||||
// not any if its parents, otherwise it behaves flaky at best.
|
||||
const composer = await session.waitAndQuery('.mx_MessageComposer_editor');
|
||||
await composer.type(message);
|
||||
const text = await session.innerText(composer);
|
||||
assert.equal(text.trim(), message.trim());
|
||||
await composer.press("Enter");
|
||||
session.log.done();
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
const acceptInvite = require("./accept-invite")
|
||||
module.exports = async function acceptServerNoticesInviteAndConsent(session) {
|
||||
await acceptInvite(session, "Server Notices");
|
||||
session.log.step(`accepts terms & conditions`);
|
||||
const consentLink = await session.waitAndQuery(".mx_EventTile_body a", 1000);
|
||||
const termsPagePromise = session.waitForNewPage();
|
||||
await consentLink.click();
|
||||
const termsPage = await termsPagePromise;
|
||||
const acceptButton = await termsPage.$('input[type=submit]');
|
||||
await acceptButton.click();
|
||||
await session.delay(500); //TODO yuck, timers
|
||||
await termsPage.close();
|
||||
session.log.done();
|
||||
await acceptInvite(session, "Server Notices");
|
||||
session.log.step(`accepts terms & conditions`);
|
||||
const consentLink = await session.waitAndQuery(".mx_EventTile_body a", 1000);
|
||||
const termsPagePromise = session.waitForNewPage();
|
||||
await consentLink.click();
|
||||
const termsPage = await termsPagePromise;
|
||||
const acceptButton = await termsPage.$('input[type=submit]');
|
||||
await acceptButton.click();
|
||||
await session.delay(500); //TODO yuck, timers
|
||||
await termsPage.close();
|
||||
session.log.done();
|
||||
}
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -18,52 +18,52 @@ const acceptTerms = require('./consent');
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function signup(session, username, password, homeserver) {
|
||||
session.log.step("signs up");
|
||||
await session.goto(session.url('/#/register'));
|
||||
//click 'Custom server' radio button
|
||||
if (homeserver) {
|
||||
const advancedRadioButton = await session.waitAndQuery('#advanced');
|
||||
await advancedRadioButton.click();
|
||||
}
|
||||
// wait until register button is visible
|
||||
await session.waitAndQuery('.mx_Login_submit[value=Register]');
|
||||
//fill out form
|
||||
const loginFields = await session.queryAll('.mx_Login_field');
|
||||
assert.strictEqual(loginFields.length, 7);
|
||||
const usernameField = loginFields[2];
|
||||
const passwordField = loginFields[3];
|
||||
const passwordRepeatField = loginFields[4];
|
||||
const hsurlField = loginFields[5];
|
||||
await session.replaceInputText(usernameField, username);
|
||||
await session.replaceInputText(passwordField, password);
|
||||
await session.replaceInputText(passwordRepeatField, password);
|
||||
if (homeserver) {
|
||||
await session.waitAndQuery('.mx_ServerConfig');
|
||||
await session.replaceInputText(hsurlField, homeserver);
|
||||
}
|
||||
//wait over a second because Registration/ServerConfig have a 1000ms
|
||||
//delay to internally set the homeserver url
|
||||
//see Registration::render and ServerConfig::props::delayTimeMs
|
||||
await session.delay(1200);
|
||||
/// focus on the button to make sure error validation
|
||||
/// has happened before checking the form is good to go
|
||||
const registerButton = await session.query('.mx_Login_submit');
|
||||
await registerButton.focus();
|
||||
//check no errors
|
||||
const error_text = await session.tryGetInnertext('.mx_Login_error');
|
||||
assert.strictEqual(!!error_text, false);
|
||||
//submit form
|
||||
//await page.screenshot({path: "beforesubmit.png", fullPage: true});
|
||||
await registerButton.click();
|
||||
session.log.step("signs up");
|
||||
await session.goto(session.url('/#/register'));
|
||||
//click 'Custom server' radio button
|
||||
if (homeserver) {
|
||||
const advancedRadioButton = await session.waitAndQuery('#advanced');
|
||||
await advancedRadioButton.click();
|
||||
}
|
||||
// wait until register button is visible
|
||||
await session.waitAndQuery('.mx_Login_submit[value=Register]');
|
||||
//fill out form
|
||||
const loginFields = await session.queryAll('.mx_Login_field');
|
||||
assert.strictEqual(loginFields.length, 7);
|
||||
const usernameField = loginFields[2];
|
||||
const passwordField = loginFields[3];
|
||||
const passwordRepeatField = loginFields[4];
|
||||
const hsurlField = loginFields[5];
|
||||
await session.replaceInputText(usernameField, username);
|
||||
await session.replaceInputText(passwordField, password);
|
||||
await session.replaceInputText(passwordRepeatField, password);
|
||||
if (homeserver) {
|
||||
await session.waitAndQuery('.mx_ServerConfig');
|
||||
await session.replaceInputText(hsurlField, homeserver);
|
||||
}
|
||||
//wait over a second because Registration/ServerConfig have a 1000ms
|
||||
//delay to internally set the homeserver url
|
||||
//see Registration::render and ServerConfig::props::delayTimeMs
|
||||
await session.delay(1200);
|
||||
/// focus on the button to make sure error validation
|
||||
/// has happened before checking the form is good to go
|
||||
const registerButton = await session.query('.mx_Login_submit');
|
||||
await registerButton.focus();
|
||||
//check no errors
|
||||
const error_text = await session.tryGetInnertext('.mx_Login_error');
|
||||
assert.strictEqual(!!error_text, false);
|
||||
//submit form
|
||||
//await page.screenshot({path: "beforesubmit.png", fullPage: true});
|
||||
await registerButton.click();
|
||||
|
||||
//confirm dialog saying you cant log back in without e-mail
|
||||
const continueButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary');
|
||||
await continueButton.click();
|
||||
//wait for registration to finish so the hash gets set
|
||||
//onhashchange better?
|
||||
await session.delay(2000);
|
||||
//confirm dialog saying you cant log back in without e-mail
|
||||
const continueButton = await session.waitAndQuery('.mx_QuestionDialog button.mx_Dialog_primary');
|
||||
await continueButton.click();
|
||||
//wait for registration to finish so the hash gets set
|
||||
//onhashchange better?
|
||||
await session.delay(2000);
|
||||
|
||||
const url = session.page.url();
|
||||
assert.strictEqual(url, session.url('/#/home'));
|
||||
session.log.done();
|
||||
const url = session.page.url();
|
||||
assert.strictEqual(url, session.url('/#/home'));
|
||||
session.log.done();
|
||||
}
|
||||
|
|
|
@ -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 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
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
@ -17,26 +17,26 @@ limitations under the License.
|
|||
const assert = require('assert');
|
||||
|
||||
module.exports = async function verifyDeviceForUser(session, name, expectedDevice) {
|
||||
session.log.step(`verifies e2e device for ${name}`);
|
||||
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
|
||||
const membersAndNames = await Promise.all(memberNameElements.map(async (el) => {
|
||||
return [el, await session.innerText(el)];
|
||||
}));
|
||||
const matchingMember = membersAndNames.filter(([el, text]) => {
|
||||
return text === name;
|
||||
}).map(([el]) => el)[0];
|
||||
await matchingMember.click();
|
||||
const firstVerifyButton = await session.waitAndQuery(".mx_MemberDeviceInfo_verify");
|
||||
await firstVerifyButton.click();
|
||||
const dialogCodeFields = await session.waitAndQueryAll(".mx_QuestionDialog code");
|
||||
assert.equal(dialogCodeFields.length, 2);
|
||||
const deviceId = await session.innerText(dialogCodeFields[0]);
|
||||
const deviceKey = await session.innerText(dialogCodeFields[1]);
|
||||
assert.equal(expectedDevice.id, deviceId);
|
||||
assert.equal(expectedDevice.key, deviceKey);
|
||||
const confirmButton = await session.query(".mx_Dialog_primary");
|
||||
await confirmButton.click();
|
||||
const closeMemberInfo = await session.query(".mx_MemberInfo_cancel");
|
||||
await closeMemberInfo.click();
|
||||
session.log.done();
|
||||
session.log.step(`verifies e2e device for ${name}`);
|
||||
const memberNameElements = await session.queryAll(".mx_MemberList .mx_EntityTile_name");
|
||||
const membersAndNames = await Promise.all(memberNameElements.map(async (el) => {
|
||||
return [el, await session.innerText(el)];
|
||||
}));
|
||||
const matchingMember = membersAndNames.filter(([el, text]) => {
|
||||
return text === name;
|
||||
}).map(([el]) => el)[0];
|
||||
await matchingMember.click();
|
||||
const firstVerifyButton = await session.waitAndQuery(".mx_MemberDeviceInfo_verify");
|
||||
await firstVerifyButton.click();
|
||||
const dialogCodeFields = await session.waitAndQueryAll(".mx_QuestionDialog code");
|
||||
assert.equal(dialogCodeFields.length, 2);
|
||||
const deviceId = await session.innerText(dialogCodeFields[0]);
|
||||
const deviceKey = await session.innerText(dialogCodeFields[1]);
|
||||
assert.equal(expectedDevice.id, deviceId);
|
||||
assert.equal(expectedDevice.key, deviceKey);
|
||||
const confirmButton = await session.query(".mx_Dialog_primary");
|
||||
await confirmButton.click();
|
||||
const closeMemberInfo = await session.query(".mx_MemberInfo_cancel");
|
||||
await closeMemberInfo.click();
|
||||
session.log.done();
|
||||
}
|
106
start.js
106
start.js
|
@ -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 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
|
||||
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;
|
||||
|
||||
async function runTests() {
|
||||
let sessions = [];
|
||||
let sessions = [];
|
||||
|
||||
console.log("running tests ...");
|
||||
const options = {};
|
||||
if (debug) {
|
||||
// options.slowMo = 10;
|
||||
options.headless = false;
|
||||
}
|
||||
if (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)`);
|
||||
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 ----------------`);
|
||||
}
|
||||
console.log("running tests ...");
|
||||
const options = {};
|
||||
if (debug) {
|
||||
options.slowMo = 20;
|
||||
options.headless = false;
|
||||
}
|
||||
if (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)`);
|
||||
options.executablePath = path;
|
||||
}
|
||||
}
|
||||
|
||||
// wait 5 minutes on failure if not running headless
|
||||
// to inspect what went wrong
|
||||
if (failure && options.headless === false) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5 * 60 * 1000));
|
||||
}
|
||||
async function createSession(username) {
|
||||
const session = await RiotSession.create(username, options, riotserver);
|
||||
sessions.push(session);
|
||||
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) {
|
||||
process.exit(-1);
|
||||
} else {
|
||||
console.log('all tests finished successfully');
|
||||
}
|
||||
// wait 5 minutes on failure if not running headless
|
||||
// to inspect what went wrong
|
||||
if (failure && options.headless === false) {
|
||||
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) {
|
||||
console.log(err);
|
||||
process.exit(-1);
|
||||
console.log(err);
|
||||
process.exit(-1);
|
||||
});
|
|
@ -9,8 +9,8 @@ PORT=5005
|
|||
BASE_DIR=$(readlink -f $(dirname $0))
|
||||
|
||||
if [ -d $BASE_DIR/$SERVER_DIR ]; then
|
||||
echo "synapse is already installed"
|
||||
exit
|
||||
echo "synapse is already installed"
|
||||
exit
|
||||
fi
|
||||
|
||||
cd $BASE_DIR
|
||||
|
|
Loading…
Reference in a new issue