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",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
20
riot/stop.sh
20
riot/stop.sh
|
@ -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
|
||||||
|
|
|
@ -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});
|
||||||
}
|
}
|
||||||
|
|
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 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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,
|
||||||
};
|
};
|
|
@ -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};
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
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 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);
|
||||||
});
|
});
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue