2025-07-02 19:11:41 -04:00
|
|
|
// Copyright 2025 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { StorageState } from '@signalapp/mock-server';
|
|
|
|
import * as durations from '../../util/durations';
|
|
|
|
import type { App } from '../playwright';
|
|
|
|
import { Bootstrap } from '../bootstrap';
|
|
|
|
import { typeIntoInput, waitForEnabledComposer } from '../helpers';
|
|
|
|
|
2025-07-11 11:48:31 -04:00
|
|
|
describe('twoClients', function twoClients(this: Mocha.Suite) {
|
2025-07-02 19:11:41 -04:00
|
|
|
this.timeout(durations.MINUTE);
|
|
|
|
|
|
|
|
let bootstrap1: Bootstrap;
|
|
|
|
let bootstrap2: Bootstrap;
|
|
|
|
let app1: App;
|
|
|
|
let app2: App;
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
bootstrap1 = new Bootstrap();
|
|
|
|
await bootstrap1.init();
|
|
|
|
|
|
|
|
bootstrap2 = new Bootstrap({ server: bootstrap1.server });
|
|
|
|
await bootstrap2.init();
|
|
|
|
|
|
|
|
let state1 = StorageState.getEmpty();
|
|
|
|
state1 = state1.updateAccount({
|
|
|
|
profileKey: bootstrap1.phone.profileKey.serialize(),
|
|
|
|
});
|
|
|
|
|
|
|
|
state1 = state1.addContact(bootstrap2.phone, {
|
|
|
|
whitelisted: true,
|
|
|
|
profileKey: bootstrap2.phone.profileKey.serialize(),
|
|
|
|
givenName: 'Contact2',
|
|
|
|
});
|
|
|
|
|
|
|
|
state1 = state1.pin(bootstrap2.phone);
|
|
|
|
|
|
|
|
await bootstrap1.phone.setStorageState(state1);
|
|
|
|
|
|
|
|
app1 = await bootstrap1.link();
|
|
|
|
|
|
|
|
let state2 = StorageState.getEmpty();
|
|
|
|
state2 = state2.updateAccount({
|
|
|
|
profileKey: bootstrap2.phone.profileKey.serialize(),
|
|
|
|
});
|
|
|
|
|
|
|
|
state2 = state2.addContact(bootstrap1.phone, {
|
|
|
|
whitelisted: true,
|
|
|
|
profileKey: bootstrap1.phone.profileKey.serialize(),
|
|
|
|
givenName: 'Contact1',
|
|
|
|
});
|
|
|
|
|
|
|
|
state2 = state2.pin(bootstrap1.phone);
|
|
|
|
await bootstrap2.phone.setStorageState(state2);
|
|
|
|
|
|
|
|
app2 = await bootstrap2.link();
|
|
|
|
});
|
|
|
|
|
2025-07-11 11:48:31 -04:00
|
|
|
afterEach(async function after(this: Mocha.Context) {
|
2025-07-02 19:11:41 -04:00
|
|
|
if (!bootstrap1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
await bootstrap1.maybeSaveLogs(this.currentTest, app1);
|
2025-07-11 11:48:31 -04:00
|
|
|
await bootstrap2.maybeSaveLogs(this.currentTest, app2);
|
2025-07-02 19:11:41 -04:00
|
|
|
|
|
|
|
await app2.close();
|
|
|
|
await app1.close();
|
|
|
|
|
|
|
|
await bootstrap2.teardown();
|
|
|
|
await bootstrap1.teardown();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('can send a message from one client to another', async () => {
|
|
|
|
const window1 = await app1.getWindow();
|
|
|
|
const leftPane1 = window1.locator('#LeftPane');
|
|
|
|
|
|
|
|
await leftPane1
|
|
|
|
.locator(`[data-testid="${bootstrap2.phone.device.aci}"]`)
|
|
|
|
.click();
|
|
|
|
const window2 = await app2.getWindow();
|
|
|
|
|
|
|
|
const messageBody = 'Hello world';
|
|
|
|
const compositionInput = await waitForEnabledComposer(window1);
|
|
|
|
await typeIntoInput(compositionInput, messageBody, '');
|
|
|
|
await compositionInput.press('Enter');
|
|
|
|
|
|
|
|
const leftPane = window2.locator('#LeftPane');
|
|
|
|
await leftPane
|
|
|
|
.locator(`[data-testid="${bootstrap1.phone.device.aci}"]`)
|
|
|
|
.click();
|
|
|
|
|
|
|
|
await window2
|
|
|
|
.locator(`.module-message__text >> "${messageBody}"`)
|
|
|
|
.waitFor();
|
|
|
|
});
|
|
|
|
});
|