test(integration): select the group From address in the #569 spec
Extend 04-shared-identity's UI test to not just assert team@example.org is offered but to actually select it as the sender and confirm it becomes the active From identity, then hold on the composer so the selected group address is visible in the recorded video. Adds selectComposerFrom / selectedComposerFrom helpers.
This commit is contained in:
committed by
Linus Rath
parent
60b9ae66ea
commit
2f791318df
@@ -1,7 +1,14 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { ACCOUNTS, GROUP } from './helpers/config';
|
||||
import { JmapClient } from './helpers/jmap';
|
||||
import { login, forceSync, openComposer, composerFromOptions } from './helpers/app';
|
||||
import {
|
||||
login,
|
||||
forceSync,
|
||||
openComposer,
|
||||
composerFromOptions,
|
||||
selectComposerFrom,
|
||||
selectedComposerFrom,
|
||||
} from './helpers/app';
|
||||
|
||||
/**
|
||||
* Issue #569 — the composer's "From" dropdown should include identities from
|
||||
@@ -41,7 +48,7 @@ test.describe('Composer From: shared/group identities (issue #569)', () => {
|
||||
expect(groupIdentityEmails).toContain(team.email);
|
||||
});
|
||||
|
||||
test('the composer From selector offers the group address', async ({ page }) => {
|
||||
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.
|
||||
@@ -49,11 +56,21 @@ test.describe('Composer From: shared/group identities (issue #569)', () => {
|
||||
|
||||
await openComposer(page);
|
||||
|
||||
// The group address alice can send as should be one of the From choices.
|
||||
// If #569 is unaddressed the control collapses to her own address only and
|
||||
// this poll times out — which is the point: it pins the expected behaviour.
|
||||
// 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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -322,6 +322,24 @@ export async function openFolder(page: Page, sel: FolderSelector): Promise<void>
|
||||
await folderRow(page, sel).first().click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the composer's From sender whose option text contains `emailNeedle`
|
||||
* (e.g. a shared/group address). Requires the multi-identity <select> to be
|
||||
* rendered. Scrolls it into view first so the change is captured on video.
|
||||
*/
|
||||
export async function selectComposerFrom(page: Page, emailNeedle: string): Promise<void> {
|
||||
const from = page.locator('[data-testid="composer-from"]').first();
|
||||
await from.scrollIntoViewIfNeeded();
|
||||
const value = await from.locator('option', { hasText: emailNeedle }).first().getAttribute('value');
|
||||
if (!value) throw new Error(`No composer From option matching "${emailNeedle}"`);
|
||||
await from.selectOption(value);
|
||||
}
|
||||
|
||||
/** The display text of the currently selected From sender. */
|
||||
export async function selectedComposerFrom(page: Page): Promise<string> {
|
||||
const from = page.locator('[data-testid="composer-from"]').first();
|
||||
return (await from.locator('option:checked').first().textContent())?.trim() ?? '';
|
||||
}
|
||||
/** Locator for an email row by (exact) subject. */
|
||||
export function emailItem(page: Page, subject: string): Locator {
|
||||
return page.locator(`[data-testid="email-list-item"][data-subject="${subject}"]`);
|
||||
|
||||
Reference in New Issue
Block a user