diff --git a/package.json b/package.json index 8035fbb508..f3c47ac491 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,11 @@ "author": "", "license": "ISC", "dependencies": { + "cheerio": "^1.0.0-rc.2", "commander": "^2.17.1", - "puppeteer": "^1.6.0" + "puppeteer": "^1.6.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "uuid": "^3.3.2" } } diff --git a/src/rest/consent.js b/src/rest/consent.js new file mode 100644 index 0000000000..1e36f541a3 --- /dev/null +++ b/src/rest/consent.js @@ -0,0 +1,30 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const request = require('request-promise-native'); +const cheerio = require('cheerio'); +const url = require("url"); + +module.exports.approveConsent = async function(consentUrl) { + const body = await request.get(consentUrl); + const doc = cheerio.load(body); + const v = doc("input[name=v]").val(); + const u = doc("input[name=u]").val(); + const h = doc("input[name=h]").val(); + const formAction = doc("form").attr("action"); + const absAction = url.resolve(consentUrl, formAction); + await request.post(absAction).form({v, u, h}); +}; diff --git a/src/rest/creator.js b/src/rest/creator.js new file mode 100644 index 0000000000..9090a21e70 --- /dev/null +++ b/src/rest/creator.js @@ -0,0 +1,84 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const util = require('util'); +const exec = util.promisify(require('child_process').exec); +const request = require('request-promise-native'); +const RestSession = require('./session'); +const RestMultiSession = require('./multi'); + +module.exports = class RestSessionCreator { + constructor(synapseSubdir, hsUrl, cwd) { + this.synapseSubdir = synapseSubdir; + this.hsUrl = hsUrl; + this.cwd = cwd; + } + + async createSessionRange(usernames, password) { + const sessionPromises = usernames.map((username) => this.createSession(username, password)); + const sessions = await Promise.all(sessionPromises); + return new RestMultiSession(sessions); + } + + async createSession(username, password) { + await this._register(username, password); + const authResult = await this._authenticate(username, password); + return new RestSession(authResult); + } + + _register(username, password) { + const registerArgs = [ + '-c homeserver.yaml', + `-u ${username}`, + `-p ${password}`, + // '--regular-user', + '-a', //until PR gets merged + this.hsUrl + ]; + const registerCmd = `./scripts/register_new_matrix_user ${registerArgs.join(' ')}`; + const allCmds = [ + `cd ${this.synapseSubdir}`, + "source env/bin/activate", + registerCmd + ].join(';'); + + return exec(allCmds, {cwd: this.cwd, encoding: 'utf-8'}).catch((result) => { + const lines = result.stdout.trim().split('\n'); + const failureReason = lines[lines.length - 1]; + throw new Error(`creating user ${username} failed: ${failureReason}`); + }); + } + + async _authenticate(username, password) { + const requestBody = { + "type": "m.login.password", + "identifier": { + "type": "m.id.user", + "user": username + }, + "password": password + }; + const url = `${this.hsUrl}/_matrix/client/r0/login`; + const responseBody = await request.post({url, json: true, body: requestBody}); + return { + accessToken: responseBody.access_token, + homeServer: responseBody.home_server, + userId: responseBody.user_id, + deviceId: responseBody.device_id, + hsUrl: this.hsUrl, + }; + } +} diff --git a/src/rest/multi.js b/src/rest/multi.js new file mode 100644 index 0000000000..12ebe9d4ab --- /dev/null +++ b/src/rest/multi.js @@ -0,0 +1,61 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const request = require('request-promise-native'); +const RestRoom = require('./room'); +const {approveConsent} = require('./consent'); + +module.exports = class RestMultiSession { + constructor(sessions) { + this.sessions = sessions; + } + + slice(start, end) { + return new RestMultiSession(this.sessions.slice(start, end)); + } + + pop(userName) { + const idx = this.sessions.findIndex((s) => s.userName() === userName); + if(idx === -1) { + throw new Error(`user ${userName} not found`); + } + const session = this.sessions.splice(idx, 1)[0]; + return session; + } + + async setDisplayName(fn) { + await Promise.all(this.sessions.map((s) => s.setDisplayName(fn(s)))); + } + + async join(roomId) { + const rooms = await Promise.all(this.sessions.map((s) => s.join(roomId))); + return new RestMultiRoom(rooms); + } +} + +class RestMultiRoom { + constructor(rooms) { + this.rooms = rooms; + } + + async talk(message) { + await Promise.all(this.rooms.map((r) => r.talk(message))); + } + + async leave() { + await Promise.all(this.rooms.map((r) => r.leave())); + } +} diff --git a/src/rest/room.js b/src/rest/room.js new file mode 100644 index 0000000000..d8de958a27 --- /dev/null +++ b/src/rest/room.js @@ -0,0 +1,42 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const uuidv4 = require('uuid/v4'); + +/* no pun intented */ +module.exports = class RestRoom { + constructor(session, roomId) { + this.session = session; + this._roomId = roomId; + } + + async talk(message) { + const txId = uuidv4(); + await this.session._put(`/rooms/${this._roomId}/send/m.room.message/${txId}`, { + "msgtype": "m.text", + "body": message + }); + return txId; + } + + async leave() { + await this.session._post(`/rooms/${this._roomId}/leave`); + } + + roomId() { + return this._roomId; + } +} diff --git a/src/rest/session.js b/src/rest/session.js new file mode 100644 index 0000000000..ece04f3352 --- /dev/null +++ b/src/rest/session.js @@ -0,0 +1,107 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const request = require('request-promise-native'); +const RestRoom = require('./room'); +const {approveConsent} = require('./consent'); + +module.exports = class RestSession { + constructor(credentials) { + this._credentials = credentials; + this._displayName = null; + } + + userId() { + return this._credentials.userId; + } + + userName() { + return this._credentials.userId.split(":")[0].substr(1); + } + + displayName() { + return this._displayName; + } + + async setDisplayName(displayName) { + this._displayName = displayName; + await this._put(`/profile/${this._credentials.userId}/displayname`, { + displayname: displayName + }); + } + + async join(roomIdOrAlias) { + const {room_id} = await this._post(`/join/${encodeURIComponent(roomIdOrAlias)}`); + return new RestRoom(this, room_id); + } + + async createRoom(name, options) { + const body = { + name, + }; + if (options.invite) { + body.invite = options.invite; + } + if (options.public) { + body.visibility = "public"; + } else { + body.visibility = "private"; + } + if (options.dm) { + body.is_direct = true; + } + if (options.topic) { + body.topic = options.topic; + } + + const {room_id} = await this._post(`/createRoom`, body); + return new RestRoom(this, room_id); + } + + _post(csApiPath, body) { + return this._request("POST", csApiPath, body); + } + + _put(csApiPath, body) { + return this._request("PUT", csApiPath, body); + } + + async _request(method, csApiPath, body) { + try { + const responseBody = await request({ + url: `${this._credentials.hsUrl}/_matrix/client/r0${csApiPath}`, + method, + headers: { + "Authorization": `Bearer ${this._credentials.accessToken}` + }, + json: true, + body + }); + return responseBody; + + } catch(err) { + const responseBody = err.response.body; + if (responseBody.errcode === 'M_CONSENT_NOT_GIVEN') { + await approveConsent(responseBody.consent_uri); + return this._request(method, csApiPath, body); + } else if(responseBody && responseBody.error) { + throw new Error(`${method} ${csApiPath}: ${responseBody.error}`); + } else { + throw new Error(`${method} ${csApiPath}: ${err.response.statusCode}`); + } + } + } +} diff --git a/src/scenario.js b/src/scenario.js index 394e89f7cd..946a4122ef 100644 --- a/src/scenario.js +++ b/src/scenario.js @@ -21,26 +21,47 @@ const join = require('./tests/join'); const sendMessage = require('./tests/send-message'); const acceptInvite = require('./tests/accept-invite'); const invite = require('./tests/invite'); -const receiveMessage = require('./tests/receive-message'); +const { + receiveMessage, + checkTimelineContains, + scrollToTimelineTop +} = require('./tests/timeline'); const createRoom = require('./tests/create-room'); const changeRoomSettings = require('./tests/room-settings'); const acceptServerNoticesInviteAndConsent = require('./tests/server-notices-consent'); -const getE2EDeviceFromSettings = require('./tests/e2e-device'); +const {enableLazyLoading, getE2EDeviceFromSettings} = require('./tests/settings'); const verifyDeviceForUser = require("./tests/verify-device"); -module.exports = async function scenario(createSession) { +module.exports = async function scenario(createSession, restCreator) { async function createUser(username) { const session = await createSession(username); - await signup(session, session.username, 'testtest'); + await signup(session, session.username, 'testtest', session.hsUrl); await acceptServerNoticesInviteAndConsent(session); return session; } const alice = await createUser("alice"); const bob = await createUser("bob"); + const charlies = await createRestUsers(restCreator); await createDirectoryRoomAndTalk(alice, bob); await createE2ERoomAndTalk(alice, bob); + await aLazyLoadingTest(alice, bob, charlies); +} + +function range(start, amount, step = 1) { + const r = []; + for (let i = 0; i < amount; ++i) { + r.push(start + (i * step)); + } + return r; +} + +async function createRestUsers(restCreator) { + const usernames = range(1, 10).map((i) => `charly-${i}`); + const charlies = await restCreator.createSessionRange(usernames, 'testtest'); + await charlies.setDisplayName((s) => `Charly #${s.userName().split('-')[1]}`); + return charlies; } async function createDirectoryRoomAndTalk(alice, bob) { @@ -83,3 +104,38 @@ async function createE2ERoomAndTalk(alice, bob) { await sendMessage(bob, bobMessage); await receiveMessage(alice, {sender: "bob", body: bobMessage, encrypted: true}); } + +async function aLazyLoadingTest(alice, bob, charlies) { + console.log(" creating a room for lazy loading member scenarios:"); + await enableLazyLoading(alice); + const room = "Lazy Loading Test"; + const alias = "#lltest:localhost"; + const charlyMsg1 = "hi bob!"; + const charlyMsg2 = "how's it going??"; + await createRoom(bob, room); + await changeRoomSettings(bob, {directory: true, visibility: "public_no_guests", alias}); + // wait for alias to be set by server after clicking "save" + // so the charlies can join it. + await bob.delay(500); + const charlyMembers = await charlies.join(alias); + await charlyMembers.talk(charlyMsg1); + await charlyMembers.talk(charlyMsg2); + bob.log.step("sends 20 messages").mute(); + for(let i = 20; i >= 1; --i) { + await sendMessage(bob, `I will only say this ${i} time(s)!`); + } + bob.log.unmute().done(); + await join(alice, alias); + await scrollToTimelineTop(alice); + //alice should see 2 messages from every charly with + //the correct display name + const expectedMessages = [charlyMsg1, charlyMsg2].reduce((messages, msgText) => { + return charlies.sessions.reduce((messages, charly) => { + return messages.concat({ + sender: charly.displayName(), + body: msgText, + }); + }, messages); + }, []); + await checkTimelineContains(alice, expectedMessages, "Charly #1-10"); +} diff --git a/src/session.js b/src/session.js index bcccc9d6cc..0bfe781e61 100644 --- a/src/session.js +++ b/src/session.js @@ -35,32 +35,54 @@ class Logger { constructor(username) { this.indent = 0; this.username = username; + this.muted = false; } startGroup(description) { - const indent = " ".repeat(this.indent * 2); - console.log(`${indent} * ${this.username} ${description}:`); + if (!this.muted) { + const indent = " ".repeat(this.indent * 2); + console.log(`${indent} * ${this.username} ${description}:`); + } this.indent += 1; + return this; } endGroup() { this.indent -= 1; + return this; } step(description) { - const indent = " ".repeat(this.indent * 2); - process.stdout.write(`${indent} * ${this.username} ${description} ... `); + if (!this.muted) { + const indent = " ".repeat(this.indent * 2); + process.stdout.write(`${indent} * ${this.username} ${description} ... `); + } + return this; } done(status = "done") { - process.stdout.write(status + "\n"); + if (!this.muted) { + process.stdout.write(status + "\n"); + } + return this; + } + + mute() { + this.muted = true; + return this; + } + + unmute() { + this.muted = false; + return this; } } module.exports = class RiotSession { - constructor(browser, page, username, riotserver) { + constructor(browser, page, username, riotserver, hsUrl) { this.browser = browser; this.page = page; + this.hsUrl = hsUrl; this.riotserver = riotserver; this.username = username; this.consoleLog = new LogBuffer(page, "console", (msg) => `${msg.text()}\n`); @@ -72,14 +94,14 @@ module.exports = class RiotSession { this.log = new Logger(this.username); } - static async create(username, puppeteerOptions, riotserver) { + static async create(username, puppeteerOptions, riotserver, hsUrl) { 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); + return new RiotSession(browser, page, username, riotserver, hsUrl); } async tryGetInnertext(selector) { @@ -161,6 +183,22 @@ module.exports = class RiotSession { return await this.queryAll(selector); } + waitForReload(timeout = 5000) { + return new Promise((resolve, reject) => { + const timeoutHandle = setTimeout(() => { + this.browser.removeEventListener('domcontentloaded', callback); + reject(new Error(`timeout of ${timeout}ms for waitForReload elapsed`)); + }, timeout); + + const callback = async () => { + clearTimeout(timeoutHandle); + resolve(); + }; + + this.page.once('domcontentloaded', callback); + }); + } + waitForNewPage(timeout = 5000) { return new Promise((resolve, reject) => { const timeoutHandle = setTimeout(() => { diff --git a/src/tests/receive-message.js b/src/tests/receive-message.js deleted file mode 100644 index afe4247181..0000000000 --- a/src/tests/receive-message.js +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2018 New Vector Ltd - -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. -*/ - -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(); - 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(1000); - 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(); -} diff --git a/src/tests/room-settings.js b/src/tests/room-settings.js index 9f802da711..95c7538431 100644 --- a/src/tests/room-settings.js +++ b/src/tests/room-settings.js @@ -76,6 +76,13 @@ module.exports = async function changeRoomSettings(session, settings) { session.log.done(); } + if (settings.alias) { + session.log.step(`sets alias to ${settings.alias}`); + const aliasField = await session.waitAndQuery(".mx_RoomSettings .mx_EditableItemList .mx_EditableItem_editable"); + await session.replaceInputText(aliasField, settings.alias); + session.log.done(); + } + const saveButton = await session.query(".mx_RoomHeader_wrapper .mx_RoomHeader_textButton"); await saveButton.click(); diff --git a/src/tests/send-message.js b/src/tests/send-message.js index eb70f5ce23..5bf289b03a 100644 --- a/src/tests/send-message.js +++ b/src/tests/send-message.js @@ -25,5 +25,7 @@ module.exports = async function sendMessage(session, message) { const text = await session.innerText(composer); assert.equal(text.trim(), message.trim()); await composer.press("Enter"); + // wait for the message to appear sent + await session.waitAndQuery(".mx_EventTile_last:not(.mx_EventTile_sending)"); session.log.done(); -} \ No newline at end of file +} diff --git a/src/tests/e2e-device.js b/src/tests/settings.js similarity index 64% rename from src/tests/e2e-device.js rename to src/tests/settings.js index 4be6677396..5649671e7a 100644 --- a/src/tests/e2e-device.js +++ b/src/tests/settings.js @@ -16,11 +16,23 @@ limitations under the License. const assert = require('assert'); -module.exports = async function getE2EDeviceFromSettings(session) { +module.exports.enableLazyLoading = async function(session) { + session.log.step(`enables lazy loading of members in the lab settings`); + const settingsButton = await session.query('.mx_BottomLeftMenu_settings'); + await settingsButton.click(); + const llCheckbox = await session.waitAndQuery("#feature_lazyloading"); + await llCheckbox.click(); + await session.waitForReload(); + const closeButton = await session.waitAndQuery(".mx_RoomHeader_cancelButton"); + await closeButton.click(); + session.log.done(); +} + +module.exports.getE2EDeviceFromSettings = async function(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", 1000); + 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(); diff --git a/src/tests/timeline.js b/src/tests/timeline.js new file mode 100644 index 0000000000..beaaec5e5a --- /dev/null +++ b/src/tests/timeline.js @@ -0,0 +1,125 @@ +/* +Copyright 2018 New Vector Ltd + +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. +*/ + +const assert = require('assert'); + +module.exports.scrollToTimelineTop = async function(session) { + session.log.step(`scrolls to the top of the timeline`); + await session.page.evaluate(() => { + return Promise.resolve().then(async () => { + const timelineScrollView = document.querySelector(".mx_RoomView .gm-scroll-view"); + let timedOut = false; + let timeoutHandle = null; + // set scrollTop to 0 in a loop and check every 50ms + // if content became available (scrollTop not being 0 anymore), + // assume everything is loaded after 3s + do { + if (timelineScrollView.scrollTop !== 0) { + if (timeoutHandle) { + clearTimeout(timeoutHandle); + } + timeoutHandle = setTimeout(() => timedOut = true, 3000); + timelineScrollView.scrollTop = 0; + } else { + await new Promise((resolve) => setTimeout(resolve, 50)); + } + } while (!timedOut) + }); + }) + session.log.done(); +} + +module.exports.receiveMessage = async function(session, expectedMessage) { + session.log.step(`receives message "${expectedMessage.body}" from ${expectedMessage.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 (expectedMessage.encrypted) { + return body.indexOf(expectedMessage.sender) !== -1 && + body.indexOf("m.room.encrypted") !== -1; + } else { + return body.indexOf(expectedMessage.body) !== -1; + } + }); + // wait a bit for the incoming event to be rendered + await session.delay(1000); + const lastTile = await getLastEventTile(session); + const foundMessage = await getMessageFromEventTile(lastTile); + assertMessage(foundMessage, expectedMessage); + session.log.done(); +} + + +module.exports.checkTimelineContains = async function (session, expectedMessages, sendersDescription) { + session.log.step(`checks timeline contains ${expectedMessages.length} ` + + `given messages${sendersDescription ? ` from ${sendersDescription}`:""}`); + const eventTiles = await getAllEventTiles(session); + let timelineMessages = await Promise.all(eventTiles.map((eventTile) => { + return getMessageFromEventTile(eventTile); + })); + //filter out tiles that were not messages + timelineMessages = timelineMessages .filter((m) => !!m); + expectedMessages.forEach((expectedMessage) => { + const foundMessage = timelineMessages.find((message) => { + return message.sender === expectedMessage.sender && + message.body === expectedMessage.body; + }); + assertMessage(foundMessage, expectedMessage); + }); + + session.log.done(); +} + +function assertMessage(foundMessage, expectedMessage) { + assert(foundMessage, `message ${JSON.stringify(expectedMessage)} not found in timeline`); + assert.equal(foundMessage.body, expectedMessage.body); + assert.equal(foundMessage.sender, expectedMessage.sender); + if (expectedMessage.hasOwnProperty("encrypted")) { + assert.equal(foundMessage.encrypted, expectedMessage.encrypted); + } +} + +function getLastEventTile(session) { + return session.query(".mx_EventTile_last"); +} + +function getAllEventTiles(session) { + return session.queryAll(".mx_RoomView_MessageList > *"); +} + +async function getMessageFromEventTile(eventTile) { + const senderElement = await eventTile.$(".mx_SenderProfile_name"); + const bodyElement = await eventTile.$(".mx_EventTile_body"); + let sender = null; + if (senderElement) { + sender = await(await senderElement.getProperty("innerText")).jsonValue(); + } + if (!bodyElement) { + return null; + } + const body = await(await bodyElement.getProperty("innerText")).jsonValue(); + const e2eIcon = await eventTile.$(".mx_EventTile_e2eIcon"); + + return { + sender, + body, + encrypted: !!e2eIcon + }; +} diff --git a/start.js b/start.js index 630a3a6d3d..1c3f27bbe3 100644 --- a/start.js +++ b/start.js @@ -17,6 +17,7 @@ limitations under the License. const assert = require('assert'); const RiotSession = require('./src/session'); const scenario = require('./src/scenario'); +const RestSessionCreator = require('./src/rest/creator'); const program = require('commander'); program @@ -27,6 +28,8 @@ program .option('--dev-tools', "open chrome devtools in browser window", false) .parse(process.argv); +const hsUrl = 'http://localhost:5005'; + async function runTests() { let sessions = []; console.log("running tests ..."); @@ -41,15 +44,21 @@ async function runTests() { options.executablePath = path; } + const restCreator = new RestSessionCreator( + 'synapse/installations/consent', + hsUrl, + __dirname + ); + async function createSession(username) { - const session = await RiotSession.create(username, options, program.riotUrl); + const session = await RiotSession.create(username, options, program.riotUrl, hsUrl); sessions.push(session); return session; } let failure = false; try { - await scenario(createSession); + await scenario(createSession, restCreator); } catch(err) { failure = true; console.log('failure: ', err); diff --git a/synapse/config-templates/consent/homeserver.yaml b/synapse/config-templates/consent/homeserver.yaml index 38aa4747b5..9fa16ebe5f 100644 --- a/synapse/config-templates/consent/homeserver.yaml +++ b/synapse/config-templates/consent/homeserver.yaml @@ -207,10 +207,10 @@ log_config: "{{SYNAPSE_ROOT}}localhost.log.config" ## Ratelimiting ## # Number of messages a client can send per second -rc_messages_per_second: 0.2 +rc_messages_per_second: 100 # Number of message a client can send before being throttled -rc_message_burst_count: 10.0 +rc_message_burst_count: 20.0 # The federation window size in milliseconds federation_rc_window_size: 1000