Add a Cypress Test 🌲 (#8295)
* A first, maybe working cypress test Plus cypress plugins to manage synapses in docker containers * Fix yaml * This file is important * try & find where it's put the artifact * Download artifact to a directory * pics or it didn't happen * Add conditional, otherwise no artifacts on failure... * Try increasing timeout also actually give the test a name * Try in chrome * Get docker logs to see why it's failing also document the chrome setting * Try changing mode on homeserver.yaml * debug * More debugging * more file permissions debugging * ARGH * more debug * sigh * Eugh, that's not how arguments work * Add the option to really allow open registration and remove debug logging / comment fixes * failure to yaml * Upload docker logs as artifacts and temporarily remove contional to test * Put the conditional back * Upgrade types in end to end tests to be compatible with fs-extra types * Try reducing timeout a bit also make password more... sensible * Hex is not octal * Remove file mode Seems to be unnecessary since the signing key is perfectly fine * Give the log files extensions * Rename workflow file now it also does tests * Add cypress scripts * copyright headers * Use ? operator Co-authored-by: Travis Ralston <travisr@matrix.org> * Use develop synapse image * Tidy up any remaining synapses after each spec run Also: * Move the synapseStart / synapseStop functions out to the top level so they can be reused * Add a tsconfig file * Give the containers names * Don't upload video on test pass We don't upload it anyway so tell cypress not to so it can not bother encoding them * Enable linting on cypress files and fix existing lint errors * Type check cypress files and make it pass the type checks, specifically: * Upgrade sinon fake timers to a version that has the right types * Set module resolution * Type check cypress files separately * Rename workflow file again Probably better to just call it an element web build * Don't plus + characters in container name * Fix yaml * Stream logs to file * Add note to end to end tester to sya what's been ported * Put docker rm in finally block Co-authored-by: Travis Ralston <travisr@matrix.org>
This commit is contained in:
parent
bcb45f1447
commit
b8013fc52a
22 changed files with 1212 additions and 52 deletions
|
@ -92,6 +92,7 @@ module.exports = {
|
|||
files: [
|
||||
"src/**/*.{ts,tsx}",
|
||||
"test/**/*.{ts,tsx}",
|
||||
"cypress/**/*.ts",
|
||||
],
|
||||
extends: [
|
||||
"plugin:matrix-org/typescript",
|
||||
|
|
49
.github/workflows/element-build-and-test.yaml
vendored
Normal file
49
.github/workflows/element-build-and-test.yaml
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Produce a build of element-web with this version of react-sdk
|
||||
# and any matching branches of element-web and js-sdk, output it
|
||||
# as an artifact and run integration tests.
|
||||
name: Element Web - Build and Test
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# This must be set for fetchdep.sh to get the right branch
|
||||
PR_NUMBER: ${{github.event.number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: scripts/ci/layered.sh && cd element-web && cp element.io/develop/config.json config.json && CI_PACKAGE=true yarn build
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: previewbuild
|
||||
path: element-web/webapp
|
||||
# We'll only use this in a triggered job, then we're done with it
|
||||
retention-days: 1
|
||||
cypress:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Download build
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: previewbuild
|
||||
path: webapp
|
||||
- name: Run Cypress tests
|
||||
uses: cypress-io/github-action@v2
|
||||
with:
|
||||
# The built in Electron runner seems to grind to a halt trying
|
||||
# to run the tests, so use chrome.
|
||||
browser: chrome
|
||||
start: npx serve -p 8080 webapp
|
||||
- name: Upload Artifact
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: cypress-results
|
||||
path: |
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
cypress/dockerlogs
|
23
.github/workflows/layered-build.yaml
vendored
23
.github/workflows/layered-build.yaml
vendored
|
@ -1,23 +0,0 @@
|
|||
# Produce a 'layered build' (a build of element-web with this version of
|
||||
# react-sdk) and output it as an artifact
|
||||
name: Layered Preview Build
|
||||
on:
|
||||
pull_request:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# This must be set for fetchdep.sh to get the right branch
|
||||
PR_NUMBER: ${{github.event.number}}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build
|
||||
run: scripts/ci/layered.sh && cd element-web && cp element.io/develop/config.json config.json && CI_PACKAGE=true yarn build
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: previewbuild
|
||||
path: element-web/webapp
|
||||
# We'll only use this in a triggered job, then we're done with it
|
||||
retention-days: 1
|
||||
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -19,3 +19,11 @@ package-lock.json
|
|||
|
||||
.vscode
|
||||
.vscode/
|
||||
|
||||
/cypress/videos
|
||||
/cypress/downloads
|
||||
/cypress/screenshots
|
||||
/cypress/synapselogs
|
||||
# These could have files in them but don't currently
|
||||
# Cypress will still auto-create them though...
|
||||
/cypress/fixtures
|
||||
|
|
4
cypress.json
Normal file
4
cypress.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"baseUrl": "http://localhost:8080",
|
||||
"videoUploadOnPasses": false
|
||||
}
|
52
cypress/integration/1-register/register.spec.ts
Normal file
52
cypress/integration/1-register/register.spec.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import { SynapseInstance } from "../../plugins/synapsedocker/index";
|
||||
|
||||
describe("Registration", () => {
|
||||
let synapseId;
|
||||
let synapsePort;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.task<SynapseInstance>("synapseStart", "consent").then(result => {
|
||||
synapseId = result.synapseId;
|
||||
synapsePort = result.port;
|
||||
});
|
||||
cy.visit("/#/register");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cy.task("synapseStop", synapseId);
|
||||
});
|
||||
|
||||
it("registers an account and lands on the home screen", () => {
|
||||
cy.get(".mx_ServerPicker_change", { timeout: 15000 }).click();
|
||||
cy.get(".mx_ServerPickerDialog_otherHomeserver").type(`http://localhost:${synapsePort}`);
|
||||
cy.get(".mx_ServerPickerDialog_continue").click();
|
||||
// wait for the dialog to go away
|
||||
cy.get('.mx_ServerPickerDialog').should('not.exist');
|
||||
cy.get("#mx_RegistrationForm_username").type("alice");
|
||||
cy.get("#mx_RegistrationForm_password").type("totally a great password");
|
||||
cy.get("#mx_RegistrationForm_passwordConfirm").type("totally a great password");
|
||||
cy.get(".mx_Login_submit").click();
|
||||
cy.get(".mx_RegistrationEmailPromptDialog button.mx_Dialog_primary").click();
|
||||
cy.get(".mx_InteractiveAuthEntryComponents_termsPolicy input").click();
|
||||
cy.get(".mx_InteractiveAuthEntryComponents_termsSubmit").click();
|
||||
cy.url().should('contain', '/#/home');
|
||||
});
|
||||
});
|
23
cypress/plugins/index.ts
Normal file
23
cypress/plugins/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import { synapseDocker } from "./synapsedocker/index";
|
||||
|
||||
export default function(on, config) {
|
||||
synapseDocker(on, config);
|
||||
}
|
212
cypress/plugins/synapsedocker/index.ts
Normal file
212
cypress/plugins/synapsedocker/index.ts
Normal file
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import * as crypto from "crypto";
|
||||
import * as childProcess from "child_process";
|
||||
import * as fse from "fs-extra";
|
||||
|
||||
// A cypress plugins to add command to start & stop synapses in
|
||||
// docker with preset templates.
|
||||
|
||||
interface SynapseConfig {
|
||||
configDir: string;
|
||||
registrationSecret: string;
|
||||
}
|
||||
|
||||
export interface SynapseInstance extends SynapseConfig {
|
||||
synapseId: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
const synapses = new Map<string, SynapseInstance>();
|
||||
|
||||
function randB64Bytes(numBytes: number): string {
|
||||
return crypto.randomBytes(numBytes).toString("base64").replace(/=*$/, "");
|
||||
}
|
||||
|
||||
async function cfgDirFromTemplate(template: string): Promise<SynapseConfig> {
|
||||
const templateDir = path.join(__dirname, "templates", template);
|
||||
|
||||
const stats = await fse.stat(templateDir);
|
||||
if (!stats?.isDirectory) {
|
||||
throw new Error(`No such template: ${template}`);
|
||||
}
|
||||
const tempDir = await fse.mkdtemp(path.join(os.tmpdir(), 'react-sdk-synapsedocker-'));
|
||||
|
||||
// change permissions on the temp directory so the docker container can see its contents
|
||||
await fse.chmod(tempDir, 0o777);
|
||||
|
||||
// copy the contents of the template dir, omitting homeserver.yaml as we'll template that
|
||||
console.log(`Copy ${templateDir} -> ${tempDir}`);
|
||||
await fse.copy(templateDir, tempDir, { filter: f => path.basename(f) !== 'homeserver.yaml' });
|
||||
|
||||
const registrationSecret = randB64Bytes(16);
|
||||
const macaroonSecret = randB64Bytes(16);
|
||||
const formSecret = randB64Bytes(16);
|
||||
|
||||
// now copy homeserver.yaml, applying sustitutions
|
||||
console.log(`Gen ${path.join(templateDir, "homeserver.yaml")}`);
|
||||
let hsYaml = await fse.readFile(path.join(templateDir, "homeserver.yaml"), "utf8");
|
||||
hsYaml = hsYaml.replace(/{{REGISTRATION_SECRET}}/g, registrationSecret);
|
||||
hsYaml = hsYaml.replace(/{{MACAROON_SECRET_KEY}}/g, macaroonSecret);
|
||||
hsYaml = hsYaml.replace(/{{FORM_SECRET}}/g, formSecret);
|
||||
await fse.writeFile(path.join(tempDir, "homeserver.yaml"), hsYaml);
|
||||
|
||||
// now generate a signing key (we could use synapse's config generation for
|
||||
// this, or we could just do this...)
|
||||
// NB. This assumes the homeserver.yaml specifies the key in this location
|
||||
const signingKey = randB64Bytes(32);
|
||||
console.log(`Gen ${path.join(templateDir, "localhost.signing.key")}`);
|
||||
await fse.writeFile(path.join(tempDir, "localhost.signing.key"), `ed25519 x ${signingKey}`);
|
||||
|
||||
return {
|
||||
configDir: tempDir,
|
||||
registrationSecret,
|
||||
};
|
||||
}
|
||||
|
||||
// Start a synapse instance: the template must be the name of
|
||||
// one of the templates in the cypress/plugins/synapsedocker/templates
|
||||
// directory
|
||||
async function synapseStart(template: string): Promise<SynapseInstance> {
|
||||
const synCfg = await cfgDirFromTemplate(template);
|
||||
|
||||
console.log(`Starting synapse with config dir ${synCfg.configDir}...`);
|
||||
|
||||
const containerName = `react-sdk-cypress-synapse-${crypto.randomBytes(4).toString("hex")}`;
|
||||
|
||||
const synapseId = await new Promise<string>((resolve, reject) => {
|
||||
childProcess.execFile('docker', [
|
||||
"run",
|
||||
"--name", containerName,
|
||||
"-d",
|
||||
"-v", `${synCfg.configDir}:/data`,
|
||||
"-p", "8008/tcp",
|
||||
"matrixdotorg/synapse:develop",
|
||||
"run",
|
||||
], (err, stdout) => {
|
||||
if (err) reject(err);
|
||||
resolve(stdout.trim());
|
||||
});
|
||||
});
|
||||
|
||||
// Get the port that docker allocated: specifying only one
|
||||
// port above leaves docker to just grab a free one, although
|
||||
// in hindsight we need to put the port in public_baseurl in the
|
||||
// config really, so this will probably need changing to use a fixed
|
||||
// / configured port.
|
||||
const port = await new Promise<number>((resolve, reject) => {
|
||||
childProcess.execFile('docker', [
|
||||
"port", synapseId, "8008",
|
||||
], { encoding: 'utf8' }, (err, stdout) => {
|
||||
if (err) reject(err);
|
||||
resolve(Number(stdout.trim().split(":")[1]));
|
||||
});
|
||||
});
|
||||
|
||||
synapses.set(synapseId, Object.assign({
|
||||
port,
|
||||
synapseId,
|
||||
}, synCfg));
|
||||
|
||||
console.log(`Started synapse with id ${synapseId} on port ${port}.`);
|
||||
return synapses.get(synapseId);
|
||||
}
|
||||
|
||||
async function synapseStop(id) {
|
||||
const synCfg = synapses.get(id);
|
||||
|
||||
if (!synCfg) throw new Error("Unknown synapse ID");
|
||||
|
||||
try {
|
||||
const synapseLogsPath = path.join("cypress", "synapselogs", id);
|
||||
await fse.ensureDir(synapseLogsPath);
|
||||
|
||||
const stdoutFile = await fse.open(path.join(synapseLogsPath, "stdout.log"), "w");
|
||||
const stderrFile = await fse.open(path.join(synapseLogsPath, "stderr.log"), "w");
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.spawn('docker', [
|
||||
"logs",
|
||||
id,
|
||||
], {
|
||||
stdio: ["ignore", stdoutFile, stderrFile],
|
||||
}).once('close', resolve);
|
||||
});
|
||||
await fse.close(stdoutFile);
|
||||
await fse.close(stderrFile);
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.execFile('docker', [
|
||||
"stop",
|
||||
id,
|
||||
], err => {
|
||||
if (err) reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
} finally {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.execFile('docker', [
|
||||
"rm",
|
||||
id,
|
||||
], err => {
|
||||
if (err) reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await fse.remove(synCfg.configDir);
|
||||
|
||||
synapses.delete(id);
|
||||
|
||||
console.log(`Stopped synapse id ${id}.`);
|
||||
// cypres deliberately fails if you return 'undefined', so
|
||||
// return null to signal all is well and we've handled the task.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export function synapseDocker(on, config) {
|
||||
on("task", {
|
||||
synapseStart, synapseStop,
|
||||
});
|
||||
|
||||
on("after:spec", async (spec) => {
|
||||
// Cleans up any remaining synapse instances after a spec run
|
||||
// This is on the theory that we should avoid re-using synapse
|
||||
// instances between spec runs: they should be cheap enough to
|
||||
// start that we can have a separate one for each spec run or even
|
||||
// test. If we accidentally re-use synapses, we could inadvertantly
|
||||
// make our tests depend on each other.
|
||||
for (const synId of synapses.keys()) {
|
||||
console.warn(`Cleaning up synapse ID ${synId} after ${spec.name}`);
|
||||
await synapseStop(synId);
|
||||
}
|
||||
});
|
||||
|
||||
on("before:run", async () => {
|
||||
// tidy up old synapse log files before each run
|
||||
await fse.emptyDir(path.join("cypress", "synapselogs"));
|
||||
});
|
||||
}
|
3
cypress/plugins/synapsedocker/templates/COPYME/README.md
Normal file
3
cypress/plugins/synapsedocker/templates/COPYME/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Meta-template for synapse templates
|
||||
|
||||
To make another template, you can copy this directory
|
|
@ -0,0 +1,72 @@
|
|||
server_name: "localhost"
|
||||
pid_file: /data/homeserver.pid
|
||||
# XXX: This won't actually be right: it lets docker allocate an ephemeral port,
|
||||
# so we have a chicken-and-egg problem
|
||||
public_baseurl: http://localhost:8008/
|
||||
# Listener is always port 8008 (configured in the container)
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
bind_addresses: ['::']
|
||||
type: http
|
||||
x_forwarded: true
|
||||
|
||||
resources:
|
||||
- names: [client, federation, consent]
|
||||
compress: false
|
||||
|
||||
# An sqlite in-memory database is fast & automatically wipes each time
|
||||
database:
|
||||
name: "sqlite3"
|
||||
args:
|
||||
database: ":memory:"
|
||||
|
||||
# Needs to be configured to log to the console like a good docker process
|
||||
log_config: "/data/log.config"
|
||||
|
||||
rc_messages_per_second: 10000
|
||||
rc_message_burst_count: 10000
|
||||
rc_registration:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
|
||||
rc_login:
|
||||
address:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
account:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
failed_attempts:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
|
||||
media_store_path: "/data/media_store"
|
||||
uploads_path: "/data/uploads"
|
||||
enable_registration: true
|
||||
enable_registration_without_verification: true
|
||||
disable_msisdn_registration: false
|
||||
# These placeholders will be be replaced with values generated at start
|
||||
registration_shared_secret: "{{REGISTRATION_SECRET}}"
|
||||
report_stats: false
|
||||
macaroon_secret_key: "{{MACAROON_SECRET_KEY}}"
|
||||
form_secret: "{{FORM_SECRET}}"
|
||||
# Signing key must be here: it will be generated to this file
|
||||
signing_key_path: "/data/localhost.signing.key"
|
||||
email:
|
||||
enable_notifs: false
|
||||
smtp_host: "localhost"
|
||||
smtp_port: 25
|
||||
smtp_user: "exampleusername"
|
||||
smtp_pass: "examplepassword"
|
||||
require_transport_security: False
|
||||
notif_from: "Your Friendly %(app)s homeserver <noreply@example.com>"
|
||||
app_name: Matrix
|
||||
notif_template_html: notif_mail.html
|
||||
notif_template_text: notif_mail.txt
|
||||
notif_for_new_users: True
|
||||
client_base_url: "http://localhost/element"
|
||||
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
suppress_key_server_warning: true
|
50
cypress/plugins/synapsedocker/templates/COPYME/log.config
Normal file
50
cypress/plugins/synapsedocker/templates/COPYME/log.config
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Log configuration for Synapse.
|
||||
#
|
||||
# This is a YAML file containing a standard Python logging configuration
|
||||
# dictionary. See [1] for details on the valid settings.
|
||||
#
|
||||
# Synapse also supports structured logging for machine readable logs which can
|
||||
# be ingested by ELK stacks. See [2] for details.
|
||||
#
|
||||
# [1]: https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema
|
||||
# [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html
|
||||
|
||||
version: 1
|
||||
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
|
||||
handlers:
|
||||
# A handler that writes logs to stderr. Unused by default, but can be used
|
||||
# instead of "buffer" and "file" in the logger handlers.
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
# beware: increasing this to DEBUG will make synapse log sensitive
|
||||
# information such as access tokens.
|
||||
level: INFO
|
||||
|
||||
twisted:
|
||||
# We send the twisted logging directly to the file handler,
|
||||
# to work around https://github.com/matrix-org/synapse/issues/3471
|
||||
# when using "buffer" logger. Use "console" to log to stderr instead.
|
||||
handlers: [console]
|
||||
propagate: false
|
||||
|
||||
root:
|
||||
level: INFO
|
||||
|
||||
# Write logs to the `buffer` handler, which will buffer them together in memory,
|
||||
# then write them to a file.
|
||||
#
|
||||
# Replace "buffer" with "console" to log to stderr instead. (Note that you'll
|
||||
# also need to update the configuration for the `twisted` logger above, in
|
||||
# this case.)
|
||||
#
|
||||
handlers: [console]
|
||||
|
||||
disable_existing_loggers: false
|
|
@ -0,0 +1 @@
|
|||
A synapse configured with user privacy consent enabled
|
|
@ -0,0 +1,84 @@
|
|||
server_name: "localhost"
|
||||
pid_file: /data/homeserver.pid
|
||||
public_baseurl: http://localhost:5005/
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
bind_addresses: ['::']
|
||||
type: http
|
||||
x_forwarded: true
|
||||
|
||||
resources:
|
||||
- names: [client, federation, consent]
|
||||
compress: false
|
||||
|
||||
database:
|
||||
name: "sqlite3"
|
||||
args:
|
||||
database: ":memory:"
|
||||
|
||||
log_config: "/data/log.config"
|
||||
|
||||
rc_messages_per_second: 10000
|
||||
rc_message_burst_count: 10000
|
||||
rc_registration:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
|
||||
rc_login:
|
||||
address:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
account:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
failed_attempts:
|
||||
per_second: 10000
|
||||
burst_count: 10000
|
||||
|
||||
media_store_path: "/data/media_store"
|
||||
uploads_path: "/data/uploads"
|
||||
enable_registration: true
|
||||
enable_registration_without_verification: true
|
||||
disable_msisdn_registration: false
|
||||
registration_shared_secret: "{{REGISTRATION_SECRET}}"
|
||||
report_stats: false
|
||||
macaroon_secret_key: "{{MACAROON_SECRET_KEY}}"
|
||||
form_secret: "{{FORM_SECRET}}"
|
||||
signing_key_path: "/data/localhost.signing.key"
|
||||
email:
|
||||
enable_notifs: false
|
||||
smtp_host: "localhost"
|
||||
smtp_port: 25
|
||||
smtp_user: "exampleusername"
|
||||
smtp_pass: "examplepassword"
|
||||
require_transport_security: False
|
||||
notif_from: "Your Friendly %(app)s homeserver <noreply@example.com>"
|
||||
app_name: Matrix
|
||||
notif_template_html: notif_mail.html
|
||||
notif_template_text: notif_mail.txt
|
||||
notif_for_new_users: True
|
||||
client_base_url: "http://localhost/element"
|
||||
|
||||
user_consent:
|
||||
template_dir: /data/res/templates/privacy
|
||||
version: 1.0
|
||||
server_notice_content:
|
||||
msgtype: m.text
|
||||
body: >-
|
||||
To continue using this homeserver you must review and agree to the
|
||||
terms and conditions at %(consent_uri)s
|
||||
send_server_notice_to_guests: True
|
||||
block_events_error: >-
|
||||
To continue using this homeserver you must review and agree to the
|
||||
terms and conditions at %(consent_uri)s
|
||||
require_at_registration: true
|
||||
|
||||
server_notices:
|
||||
system_mxid_localpart: notices
|
||||
system_mxid_display_name: "Server Notices"
|
||||
system_mxid_avatar_url: "mxc://localhost:5005/oumMVlgDnLYFaPVkExemNVVZ"
|
||||
room_name: "Server Notices"
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
suppress_key_server_warning: true
|
50
cypress/plugins/synapsedocker/templates/consent/log.config
Normal file
50
cypress/plugins/synapsedocker/templates/consent/log.config
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Log configuration for Synapse.
|
||||
#
|
||||
# This is a YAML file containing a standard Python logging configuration
|
||||
# dictionary. See [1] for details on the valid settings.
|
||||
#
|
||||
# Synapse also supports structured logging for machine readable logs which can
|
||||
# be ingested by ELK stacks. See [2] for details.
|
||||
#
|
||||
# [1]: https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema
|
||||
# [2]: https://matrix-org.github.io/synapse/latest/structured_logging.html
|
||||
|
||||
version: 1
|
||||
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
|
||||
handlers:
|
||||
# A handler that writes logs to stderr. Unused by default, but can be used
|
||||
# instead of "buffer" and "file" in the logger handlers.
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
# beware: increasing this to DEBUG will make synapse log sensitive
|
||||
# information such as access tokens.
|
||||
level: INFO
|
||||
|
||||
twisted:
|
||||
# We send the twisted logging directly to the file handler,
|
||||
# to work around https://github.com/matrix-org/synapse/issues/3471
|
||||
# when using "buffer" logger. Use "console" to log to stderr instead.
|
||||
handlers: [console]
|
||||
propagate: false
|
||||
|
||||
root:
|
||||
level: INFO
|
||||
|
||||
# Write logs to the `buffer` handler, which will buffer them together in memory,
|
||||
# then write them to a file.
|
||||
#
|
||||
# Replace "buffer" with "console" to log to stderr instead. (Note that you'll
|
||||
# also need to update the configuration for the `twisted` logger above, in
|
||||
# this case.)
|
||||
#
|
||||
handlers: [console]
|
||||
|
||||
disable_existing_loggers: false
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Test Privacy policy</title>
|
||||
</head>
|
||||
<body>
|
||||
{% if has_consented %}
|
||||
<p>
|
||||
Thank you, you've already accepted the license.
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
Please accept the license!
|
||||
</p>
|
||||
<form method="post" action="consent">
|
||||
<input type="hidden" name="v" value="{{version}}"/>
|
||||
<input type="hidden" name="u" value="{{user}}"/>
|
||||
<input type="hidden" name="h" value="{{userhmac}}"/>
|
||||
<input type="submit" value="Sure thing!"/>
|
||||
</form>
|
||||
{% endif %}
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,9 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Test Privacy policy</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Danke schon</p>
|
||||
</body>
|
||||
</html>
|
3
cypress/support/index.ts
Normal file
3
cypress/support/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Empty file to prevent cypress from recreating a helpful example
|
||||
// file on every run (their example file doesn't use semicolons and
|
||||
// so fails our lint rules).
|
9
cypress/tsconfig.json
Normal file
9
cypress/tsconfig.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"lib": ["es2020", "dom"],
|
||||
"types": ["cypress"],
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
13
package.json
13
package.json
|
@ -44,11 +44,13 @@
|
|||
"start:all": "echo THIS IS FOR LEGACY PURPOSES ONLY. && yarn start:build",
|
||||
"start:build": "babel src -w -s -d lib --verbose --extensions \".ts,.js\"",
|
||||
"lint": "yarn lint:types && yarn lint:js && yarn lint:style",
|
||||
"lint:js": "eslint --max-warnings 0 src test",
|
||||
"lint:js-fix": "eslint --fix src test",
|
||||
"lint:types": "tsc --noEmit --jsx react",
|
||||
"lint:js": "eslint --max-warnings 0 src test cypress",
|
||||
"lint:js-fix": "eslint --fix src test cypress",
|
||||
"lint:types": "tsc --noEmit --jsx react && tsc --noEmit -p cypress",
|
||||
"lint:style": "stylelint \"res/css/**/*.scss\"",
|
||||
"test": "jest",
|
||||
"test:cypress": "cypress run",
|
||||
"test:cypress:open": "cypress open",
|
||||
"test:e2e": "./test/end-to-end-tests/run.sh --app-url http://localhost:8080",
|
||||
"coverage": "yarn test --coverage"
|
||||
},
|
||||
|
@ -132,7 +134,7 @@
|
|||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
|
||||
"@peculiar/webcrypto": "^1.1.4",
|
||||
"@sentry/types": "^6.10.0",
|
||||
"@sinonjs/fake-timers": "^7.0.2",
|
||||
"@sinonjs/fake-timers": "^9.1.2",
|
||||
"@types/classnames": "^2.2.11",
|
||||
"@types/commonmark": "^0.27.4",
|
||||
"@types/counterpart": "^0.18.1",
|
||||
|
@ -142,6 +144,7 @@
|
|||
"@types/escape-html": "^1.0.1",
|
||||
"@types/file-saver": "^2.0.3",
|
||||
"@types/flux": "^3.1.9",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/modernizr": "^3.5.3",
|
||||
|
@ -163,6 +166,7 @@
|
|||
"babel-jest": "^26.6.3",
|
||||
"blob-polyfill": "^6.0.20211015",
|
||||
"chokidar": "^3.5.1",
|
||||
"cypress": "^9.5.4",
|
||||
"enzyme": "^3.11.0",
|
||||
"enzyme-to-json": "^3.6.2",
|
||||
"eslint": "8.9.0",
|
||||
|
@ -172,6 +176,7 @@
|
|||
"eslint-plugin-matrix-org": "^0.4.0",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"eslint-plugin-react-hooks": "^4.3.0",
|
||||
"fs-extra": "^10.0.1",
|
||||
"glob": "^7.1.6",
|
||||
"jest": "^27.4.0",
|
||||
"jest-canvas-mock": "^2.3.0",
|
||||
|
|
|
@ -43,6 +43,7 @@ export async function scenario(createSession: (s: string) => Promise<ElementSess
|
|||
console.log(`running tests on ${await session.browser.version()} ...`);
|
||||
firstUser = false;
|
||||
}
|
||||
// ported to cyprus (registration test)
|
||||
await signup(session, session.username, 'testsarefun!!!', session.hsUrl);
|
||||
return session;
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
|
||||
"@types/node@*":
|
||||
version "11.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-11.12.1.tgz#d90123f6c61fdf2f7cddd286ddae891586dd3488"
|
||||
integrity sha512-sKDlqv6COJrR7ar0+GqqhrXQDzQlMcqMnF2iEU6m9hLo8kxozoAGUazwPyELHlRVmjsbvlnGXjnzyptSXVmceA==
|
||||
version "17.0.23"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da"
|
||||
integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==
|
||||
|
||||
"@types/puppeteer@^5.4.4":
|
||||
version "5.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.4.tgz#e92abeccc4f46207c3e1b38934a1246be080ccd0"
|
||||
integrity sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==
|
||||
version "5.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.5.tgz#154e3850a77bfd3967f036680de8ddc88eb3a12b"
|
||||
integrity sha512-lxCjpDEY+DZ66+W3x5Af4oHnEmUXt0HuaRzkBGE2UZiZEp/V1d3StpLPlmNVu/ea091bdNmVPl44lu8Wy/0ZCA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
|
|
Loading…
Reference in a new issue