fix(app/e2e): fix composer-lock test — mock provider + prompt so lock releases (#739)
* fix(app/e2e): fix composer-lock test — use mock provider + prompt so lock releases
Two bugs in the "composer is locked while new workspace agent is being
created" test:
1. expectComposerDisabled used toBeDisabled() but React Native TextInput
with editable={false} renders as <textarea readonly> on web, not
<textarea disabled>. Fixed to not.toBeEditable().
2. clickNewWorkspaceButton created an agent with no prompt, leaving the
agent permanently "idle". showPendingCreateSubmitLoading only clears
when authoritativeStatus is non-bootstrapping, but "idle" counts as
bootstrapping — so the composer lock never released. Fixed by opening
the new-workspace composer, filling a prompt, then clicking Create so
the mock agent transitions to "running" after agent_created is released.
Also switches buildCreateAgentPreferences to provider "mock" with the
ten-second-stream model so E2E tests exercise app behavior without
depending on real provider availability.
* fix(app): add aria-checked to Switch for E2E toBeChecked() assertions
React Native Web does not map accessibilityState.checked to aria-checked
for role="switch", so Playwright's toBeChecked() always finds the element
unchecked. Adding aria-checked={value} directly to the Pressable sets the
attribute explicitly.
Update the switch.test.tsx mock to accept and pass through the explicit
aria-checked prop, keeping the mock faithful to the fixed component.
This commit is contained in:
@@ -24,9 +24,9 @@ import {
|
|||||||
openGithubWorkspace,
|
openGithubWorkspace,
|
||||||
} from "./helpers/composer";
|
} from "./helpers/composer";
|
||||||
import {
|
import {
|
||||||
clickNewWorkspaceButton,
|
|
||||||
connectNewWorkspaceDaemonClient,
|
connectNewWorkspaceDaemonClient,
|
||||||
delayBrowserAgentCreatedStatus,
|
delayBrowserAgentCreatedStatus,
|
||||||
|
openNewWorkspaceComposer,
|
||||||
openProjectViaDaemon,
|
openProjectViaDaemon,
|
||||||
} from "./helpers/new-workspace";
|
} from "./helpers/new-workspace";
|
||||||
import { gotoAppShell } from "./helpers/app";
|
import { gotoAppShell } from "./helpers/app";
|
||||||
@@ -255,10 +255,16 @@ test.describe("Composer attachments", () => {
|
|||||||
targetWorkspacePath: openedProject.workspaceId,
|
targetWorkspacePath: openedProject.workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await clickNewWorkspaceButton(page, {
|
await openNewWorkspaceComposer(page, {
|
||||||
projectKey: openedProject.projectKey,
|
projectKey: openedProject.projectKey,
|
||||||
projectDisplayName: openedProject.projectDisplayName,
|
projectDisplayName: openedProject.projectDisplayName,
|
||||||
});
|
});
|
||||||
|
await fillComposerDraft(page, "lock test prompt");
|
||||||
|
const createButton = page
|
||||||
|
.getByTestId("message-input-root")
|
||||||
|
.getByRole("button", { name: "Create" });
|
||||||
|
await expect(createButton).toBeVisible({ timeout: 30_000 });
|
||||||
|
await createButton.click();
|
||||||
|
|
||||||
await agentCreatedDelay.waitForCreateRequest();
|
await agentCreatedDelay.waitForCreateRequest();
|
||||||
await agentCreatedDelay.waitForDelayedCreatedStatus();
|
await agentCreatedDelay.waitForDelayedCreatedStatus();
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ export async function expectComposerVisible(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function expectComposerDisabled(page: Page): Promise<void> {
|
export async function expectComposerDisabled(page: Page): Promise<void> {
|
||||||
await expect(composerInput(page)).toBeDisabled({ timeout: 10_000 });
|
// React Native TextInput with editable={false} renders as <textarea readonly> on web,
|
||||||
|
// not <textarea disabled>. Use not.toBeEditable() to match either form.
|
||||||
|
await expect(composerInput(page)).not.toBeEditable({ timeout: 10_000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function expectComposerDraft(page: Page, text: string): Promise<void> {
|
export async function expectComposerDraft(page: Page, text: string): Promise<void> {
|
||||||
|
|||||||
@@ -30,10 +30,15 @@ export function buildSeededHost(input: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const TEST_MOCK_PROVIDER_PREFERENCES = {
|
||||||
|
...TEST_PROVIDER_PREFERENCES,
|
||||||
|
mock: { model: "ten-second-stream" },
|
||||||
|
} as const;
|
||||||
|
|
||||||
export function buildCreateAgentPreferences(serverId: string) {
|
export function buildCreateAgentPreferences(serverId: string) {
|
||||||
return {
|
return {
|
||||||
serverId,
|
serverId,
|
||||||
provider: "codex" as const,
|
provider: "mock" as const,
|
||||||
providerPreferences: TEST_PROVIDER_PREFERENCES,
|
providerPreferences: TEST_MOCK_PROVIDER_PREFERENCES,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ vi.mock("react-native-reanimated", () => ({
|
|||||||
|
|
||||||
vi.mock("react-native", () => ({
|
vi.mock("react-native", () => ({
|
||||||
Pressable: ({
|
Pressable: ({
|
||||||
|
"aria-checked": ariaChecked,
|
||||||
accessibilityLabel,
|
accessibilityLabel,
|
||||||
accessibilityRole,
|
accessibilityRole,
|
||||||
accessibilityState,
|
accessibilityState,
|
||||||
@@ -40,6 +41,7 @@ vi.mock("react-native", () => ({
|
|||||||
onPress,
|
onPress,
|
||||||
testID,
|
testID,
|
||||||
}: {
|
}: {
|
||||||
|
"aria-checked"?: boolean;
|
||||||
accessibilityLabel?: string;
|
accessibilityLabel?: string;
|
||||||
accessibilityRole?: string;
|
accessibilityRole?: string;
|
||||||
accessibilityState?: { checked?: boolean; disabled?: boolean };
|
accessibilityState?: { checked?: boolean; disabled?: boolean };
|
||||||
@@ -51,7 +53,7 @@ vi.mock("react-native", () => ({
|
|||||||
React.createElement(
|
React.createElement(
|
||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
"aria-checked": accessibilityState?.checked,
|
"aria-checked": ariaChecked ?? accessibilityState?.checked,
|
||||||
"aria-disabled": accessibilityState?.disabled,
|
"aria-disabled": accessibilityState?.disabled,
|
||||||
"aria-label": accessibilityLabel,
|
"aria-label": accessibilityLabel,
|
||||||
"data-disabled": disabled,
|
"data-disabled": disabled,
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export function Switch({
|
|||||||
accessibilityRole="switch"
|
accessibilityRole="switch"
|
||||||
accessibilityState={accessibilityState}
|
accessibilityState={accessibilityState}
|
||||||
accessibilityLabel={accessibilityLabel}
|
accessibilityLabel={accessibilityLabel}
|
||||||
|
aria-checked={value}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
style={pressableStyle}
|
style={pressableStyle}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user