Files
webmail/integration/tests/05-shared-identity.spec.ts
T
Stefan Hildebrandt b39f4b714a test(integration): renumber specs to drop the duplicate 04 prefix
Both 04-all-mail and 04-shared-identity shared the same 04 prefix. Shift
shared-identity and everything after it up by one (05-shared-identity …
12-cross-view-retain), leaving 04-all-mail as the sole 04 spec. Pure file
renames; no content changes.
2026-08-09 22:50:07 +02:00

77 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
import { ACCOUNTS, GROUP } from './helpers/config';
import { JmapClient } from './helpers/jmap';
import {
login,
forceSync,
openComposer,
composerFromOptions,
selectComposerFrom,
selectedComposerFrom,
} from './helpers/app';
/**
* Issue #569 — the composer's "From" dropdown should include identities from
* shared/group accounts, not only the logged-in (connected) accounts.
*
* Scenario under test (the one expected to already work): a Stalwart *group*
* mailbox `team@example.org` is provisioned and `carol` is made a member of it
* *before her first login* (integration/stalwart/plan-accounts.ndjson.tpl +
* entrypoint.sh). As a member she gets the group's shared folders (shown under
* "Shared") and — per Stalwart — a `team@` send-as identity (Stalwart returns
* it among the member's own account identities). The composer should therefore
* offer `team@example.org` as a sender alongside her own address.
*/
const member = ACCOUNTS[GROUP.team.memberOf];
const { team } = GROUP;
test.describe('Composer From: shared/group identities (issue #569)', () => {
test('the pre-provisioned group account is reachable in the member’s JMAP session', async () => {
// Server-side guard for the UI expectation below: if this fails, the
// bootstrap group provisioning is broken (not the app). The member must see
// the group account in her session, and it must expose a team@ identity she
// can send as.
const memberClient = await JmapClient.connect(member.email, member.password);
expect(memberClient.sharedAccountNames()).toContain(team.email);
const groupAccountId = Object.entries(memberClient.accounts).find(
([, name]) => name === team.email,
)?.[0];
expect(groupAccountId).toBeTruthy();
const res = await memberClient.request([
['Identity/get', { accountId: groupAccountId! }, '0'],
]);
const groupIdentityEmails = (res.methodResponses[0][1].list as { email: string }[]).map(
(i) => i.email,
);
expect(groupIdentityEmails).toContain(team.email);
});
test('the composer From selector offers and can select the group address', async ({ page }) => {
await login(page, member);
// Shared accounts/identities are discovered from the JMAP session; give the
// client a beat to settle them after the first render.
await forceSync(page);
await openComposer(page);
// The group address the member can send as should be one of the From
// choices. If #569 were unaddressed the control would collapse to her own
// address only and this poll would time out — which is the point: it pins
// the expected behaviour.
await expect
.poll(async () => (await composerFromOptions(page)).join(' | '), { timeout: 15000 })
.toContain(team.email);
// Pick the group address as the sender and confirm it becomes the selected
// From identity (not just a listed option).
await selectComposerFrom(page, team.email);
await expect.poll(() => selectedComposerFrom(page), { timeout: 5000 }).toContain(team.email);
// Hold on the composer so the final video frames clearly show the group
// address selected in the From field.
await page.waitForTimeout(2000);
});
});