mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-07 06:16:06 -10:00
Fix OpenAI subscription waiting labels (#19521)
Show “Waiting for auth…” while OpenAI subscription sign-in completes in onboarding and the shared provider connection screen. Preserve Claude’s code-entry label and align connection previews and existing regression expectations. Verified 246 component tests, workspace typechecks, the full production build, token gates, and all 54 applicable CI checks. Greptile scored the change 5/5 with no unresolved comments. Co-Authored-By: Paperclip <[email protected]>
This commit is contained in:
1 parent
17b4f972bf
commit
b85557a122
7 files changed
+10
-10
No files matched your search
@@ -203,7 +203,7 @@ for (const [provider, label, adapter] of [["anthropic", "Claude", "claude_local"
|
||||
else await expect(page.getByText("ABCD-EFGH", { exact: true })).toBeVisible();
|
||||
await signIn.click();
|
||||
expect(await page.evaluate(() => (window as unknown as { loginDestination: string }).loginDestination)).toBe("https://provider.example/authorize");
|
||||
await expect(page.getByRole("button", { name: "Waiting for code", exact: true })).toBeDisabled();
|
||||
await expect(page.getByRole("button", { name: provider === "openai" ? "Waiting for auth…" : "Waiting for code", exact: true })).toBeDisabled();
|
||||
// The shared footer label animates; capture after it has settled.
|
||||
await page.waitForTimeout(600);
|
||||
await page.screenshot({ path: testInfo.outputPath(`${provider}-onboarding-browser-login.png`), fullPage: true });
|
||||
|
||||
@@ -2908,7 +2908,7 @@ describe("OnboardingWizard restore-gate (stale localStorage across accounts)", (
|
||||
["claude_local", /Claude/, "claude.ai", "button"],
|
||||
["codex_local", /OpenAI/, "auth.openai.com", "link"],
|
||||
["codex_local", /OpenAI/, "auth.openai.com", "button"],
|
||||
] as const)("waits for the code after the %s %s %s %s opens sign-in", async (adapterType, source, host, control) => {
|
||||
] as const)("shows the provider waiting state after the %s %s %s %s opens sign-in", async (adapterType, source, host, control) => {
|
||||
mockAgentsApi.getAdapterAuthSignal.mockResolvedValue({ status: "absent" });
|
||||
const { root } = await openStep4({ adapterType });
|
||||
await pickSource(source);
|
||||
@@ -2922,14 +2922,14 @@ describe("OnboardingWizard restore-gate (stale localStorage across accounts)", (
|
||||
});
|
||||
expect(open).toHaveBeenCalledExactlyOnceWith(link.href, "_blank", "noreferrer,noopener");
|
||||
const primary = [...document.body.querySelectorAll("button")].at(-1)!;
|
||||
expect(primary.textContent?.trim()).toBe("Waiting for code…");
|
||||
expect(primary.textContent?.trim()).toBe(adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code…");
|
||||
expect(primary.disabled).toBe(true);
|
||||
await act(async () => primary.click());
|
||||
await act(async () => document.querySelector('[data-testid="onboarding-wizard"]')!.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", metaKey: true, bubbles: true, cancelable: true })));
|
||||
expect(open).toHaveBeenCalledTimes(1);
|
||||
await act(async () => link.click());
|
||||
expect(open).toHaveBeenNthCalledWith(2, link.href, "_blank", "noreferrer,noopener");
|
||||
expect(primary.textContent?.trim()).toBe("Waiting for code…");
|
||||
expect(primary.textContent?.trim()).toBe(adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code…");
|
||||
expect(primary.disabled).toBe(true);
|
||||
if (adapterType === "claude_local") expect((document.querySelector('input[aria-label="Authorization code"]') as HTMLInputElement).disabled).toBe(false);
|
||||
expect(mockAgentsApi.hire).not.toHaveBeenCalled();
|
||||
|
||||
@@ -1566,7 +1566,7 @@ function OnboardingWizardInner({
|
||||
: (connectPhase === "ready" || connectPhase === "waiting") && submitLoginCode
|
||||
? { label: "Submit code", icon: "arrow", disabled: false }
|
||||
: connectPhase === "waiting"
|
||||
? { label: "Waiting for code…", icon: "spinner", disabled: true }
|
||||
? { label: adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code…", icon: "spinner", disabled: true }
|
||||
: connectPhase === "connecting"
|
||||
? { label: "Connecting", icon: "spinner", disabled: true }
|
||||
: connectPhase === "ready"
|
||||
|
||||
@@ -380,11 +380,11 @@ describe("AgentProviderConnection reuse", () => {
|
||||
flushSync(() => panel().onPromptReady("https://provider.example/authorize"));
|
||||
click(adapterType === "claude_local" ? "Sign in to Claude" : "Sign in to OpenAI");
|
||||
expect(open).toHaveBeenCalledWith("https://provider.example/authorize", "_blank", "noreferrer,noopener");
|
||||
expect(host.textContent).toContain("Waiting for code");
|
||||
expect(host.textContent).toContain(adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code");
|
||||
flushSync(() => panel().onCodeSubmitted());
|
||||
expect(host.textContent).toContain("Connecting");
|
||||
flushSync(() => panel().onSubmitFailed());
|
||||
expect(host.textContent).toContain("Waiting for code");
|
||||
expect(host.textContent).toContain(adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code");
|
||||
flushSync(() => panel().onConnected("session-1"));
|
||||
await vi.waitFor(() => expect(onComplete).toHaveBeenCalledWith({ connectionId: "login-account", grantId: "login-grant", method: "subscription" }));
|
||||
expect(managedApi.loginResult).toHaveBeenCalledWith("c1", "session-1");
|
||||
|
||||
@@ -439,7 +439,7 @@ export function AgentProviderConnection({
|
||||
}}
|
||||
primaryLabel={
|
||||
opened && needsLogin
|
||||
? loginPhase === "waiting" ? "Waiting for code"
|
||||
? loginPhase === "waiting" ? adapterType === "codex_local" ? "Waiting for auth…" : "Waiting for code"
|
||||
: loginPhase === "connecting" ? "Connecting"
|
||||
: `Sign in to ${provider}`
|
||||
: busy
|
||||
|
||||
@@ -285,7 +285,7 @@ function ConnectFlowPreview({
|
||||
: phase === "ready"
|
||||
? { label: signInLabel, icon: "none" as const, disabled: false }
|
||||
: phase === "waiting"
|
||||
? { label: "Waiting for code", icon: "spinner" as const, disabled: true }
|
||||
? { label: selectedId === "codex_local" ? "Waiting for auth…" : "Waiting for code", icon: "spinner" as const, disabled: true }
|
||||
: phase === "connecting"
|
||||
? { label: "Connecting", icon: "spinner" as const, disabled: true }
|
||||
: { label: "Next", icon: "arrow" as const, disabled: true };
|
||||
|
||||
@@ -70,7 +70,7 @@ export function ProviderConnectionPreview({ provider, initialMethod = "subscript
|
||||
</div>}
|
||||
</motion.div>
|
||||
<FooterNav onBack={phase !== "idle" ? cancel : undefined}
|
||||
primaryLabel={connecting ? "Connecting" : phase === "idle" ? "Next" : method === "api" ? "Connect" : value.trim() ? "Connect" : phase === "waiting" ? "Waiting for code" : `Sign in to ${provider}`}
|
||||
primaryLabel={connecting ? "Connecting" : phase === "idle" ? "Next" : method === "api" ? "Connect" : value.trim() ? "Connect" : phase === "waiting" ? provider === "OpenAI" ? "Waiting for auth…" : "Waiting for code" : `Sign in to ${provider}`}
|
||||
primaryDisabled={phase === "idle" || phase === "collapsing" || phase === "opening" || (method === "api" && !value.trim()) || (phase === "waiting" && !value.trim())}
|
||||
loading={connecting} primaryIcon={connecting || phase === "waiting" && !value.trim() ? "spinner" : method === "api" ? "arrow" : "none"}
|
||||
onPrimary={() => method === "api" || value.trim() ? finish() : setPhase("waiting")} />
|
||||
|
||||
Reference in new issue
Block a user