Reuse files on disk for outgoing messages

This commit is contained in:
trevor-signal
2026-02-23 15:35:11 -05:00
committed by GitHub
parent 491de86ad3
commit 2b243bb457
12 changed files with 410 additions and 111 deletions

View File

@@ -1,6 +1,6 @@
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import pTimeout from 'p-timeout';
import createDebug from 'debug';
import {
type Device,
@@ -15,6 +15,7 @@ import type { Locator, Page } from 'playwright';
import { expect } from 'playwright/test';
import type { SignalService } from '../protobuf/index.std.js';
import { strictAssert } from '../util/assert.std.js';
import { SECOND } from '../util/durations/constants.std.js';
const debug = createDebug('mock:test:helpers');
@@ -351,7 +352,7 @@ export function getTimelineMessageWithText(page: Page, text: string): Locator {
return getTimeline(page).locator('.module-message').filter({ hasText: text });
}
export async function composerAttachImages(
export async function composerAttachFiles(
page: Page,
filePaths: ReadonlyArray<string>
): Promise<void> {
@@ -363,6 +364,12 @@ export async function composerAttachImages(
);
debug('setting input files');
await page
.getByRole('button', {
name: 'Add attachment or poll',
})
.click();
await page.getByRole('menuitem', { name: 'File' }).click();
await AttachmentInput.setInputFiles(filePaths);
debug(`waiting for ${filePaths.length} items`);
@@ -383,9 +390,11 @@ export async function sendMessageWithAttachments(
receiver: PrimaryDevice,
text: string,
filePaths: Array<string>
): Promise<Array<SignalService.IAttachmentPointer>> {
await composerAttachImages(page, filePaths);
): Promise<{
attachments: Array<SignalService.IAttachmentPointer>;
timestamp: number;
}> {
await composerAttachFiles(page, filePaths);
debug('sending message');
const input = await waitForEnabledComposer(page);
await typeIntoInput(input, text, '');
@@ -406,14 +415,32 @@ export async function sendMessageWithAttachments(
);
debug('get received message data');
const receivedMessage = await receiver.waitForMessage();
const attachments = receivedMessage.dataMessage.attachments ?? [];
strictAssert(
attachments.length === filePaths.length,
'attachments must exist'
);
return attachments;
return pTimeout(
(async () => {
// eslint-disable-next-line no-constant-condition
while (true) {
// eslint-disable-next-line no-await-in-loop
const receivedMessage = await receiver.waitForMessage();
const attachments = receivedMessage.dataMessage.attachments ?? [];
if (
attachments.length === filePaths.length &&
receivedMessage.body === text
) {
strictAssert(
receivedMessage.dataMessage.timestamp,
'timestamp exists'
);
return {
attachments,
timestamp: receivedMessage.dataMessage.timestamp.toNumber(),
};
}
}
})(),
10 * SECOND,
'Timed out waiting to detect message send with attached files'
);
}
export async function waitForEnabledComposer(page: Page): Promise<Locator> {