Build your profile
Add a name and avatar. They’ll show up on your messages,
@@ -468,66 +497,76 @@ export function CommunityOnboardingFlow({
Meet your starter team
Buzz lets you bring multiple agents into the same workspace.
- This team will help you get started using Buzz.
+ Your team will help you get started using Buzz.
- {starterPersonas.length > 0 ? (
-
- {starterPersonas.map((persona) => {
- const animationUrl =
- STARTER_PERSONA_ANIMATIONS[persona.displayName];
- return (
-
- {animationUrl ? (
-
- ) : (
-
- )}
-
- {persona.displayName}
-
-
- );
- })}
-
- ) : null}
+
+ {starterPersonas.length > 0 ? (
+
+ {starterPersonas.map((persona) => {
+ const animationUrl =
+ STARTER_PERSONA_ANIMATIONS[persona.displayName];
+ return (
+
+ {animationUrl ? (
+
+ ) : (
+
+ )}
+
+ {persona.displayName}
+
+
+ );
+ })}
+
+ ) : null}
+
{transaction.error ? (
-
+
{transaction.error}
+ {starterChannelFailureCount === 1 ? " Try again." : null}
) : null}
void finalize()}
+ onClick={() =>
+ void (starterChannelFailureCount >= 2
+ ? finish()
+ : finalize())
+ }
>
- {transaction.stage === "finalizing" ||
- transaction.stage === "entering"
- ? "Preparing Welcome…"
- : `Enter ${transaction.communityName}`}
+ {isPending || transaction.stage === "entering" ? (
+
+ ) : starterChannelFailureCount >= 2 ? (
+ "Skip for now"
+ ) : (
+ "Take me to Buzz"
+ )}
+
+
+ Back
- {transaction.error ? (
- void finish()}
- variant="ghost"
- >
- Skip for now
-
- ) : null}
>
)}
diff --git a/desktop/tests/e2e/deep-link-invite.spec.ts b/desktop/tests/e2e/deep-link-invite.spec.ts
index efd3d9337..1ca8475cc 100644
--- a/desktop/tests/e2e/deep-link-invite.spec.ts
+++ b/desktop/tests/e2e/deep-link-invite.spec.ts
@@ -243,7 +243,7 @@ test("queued add-community links open and acknowledge one at a time", async ({
]);
});
-test("Welcome failure can be skipped without abandoning community onboarding", async ({
+test("Welcome failure retries once before allowing starter channel setup to be skipped", async ({
page,
}) => {
const welcomeError = "Channel creation is not permitted.";
@@ -277,7 +277,7 @@ test("Welcome failure can be skipped without abandoning community onboarding", a
);
await installMockBridge(
page,
- { ensureStarterChannelsErrors: [welcomeError, welcomeError] },
+ { ensureStarterChannelsErrors: [welcomeError, welcomeError, welcomeError] },
{ relayWsUrl: COMMUNITY_RELAY_URL, skipOnboardingSeed: true },
);
await page.goto("/");
@@ -291,30 +291,59 @@ test("Welcome failure can be skipped without abandoning community onboarding", a
);
}
- await page.getByRole("button", { name: "Enter hive" }).click();
+ const enterButton = page.getByRole("button", { name: "Take me to Buzz" });
+ await enterButton.click();
+
+ await expect(page.getByText(`${welcomeError} Try again.`)).toBeVisible();
+ await expect(enterButton).toBeEnabled();
+ const backButton = page.getByRole("button", { name: "Back" });
+ await expect(backButton).toBeVisible();
+ await backButton.click();
- await expect(page.getByText(welcomeError)).toBeVisible();
await expect(
- page.getByRole("button", { name: "Preparing Welcome…" }),
- ).toBeEnabled();
- const skip = page.getByRole("button", { name: "Skip for now" });
- await expect(skip).toBeVisible();
- await skip.click();
+ page.getByRole("heading", { name: "Build your profile" }),
+ ).toBeVisible();
+ await page.getByLabel("Community display name").fill("Tyler");
+ await page.getByTestId("community-profile-next").click();
+
+ await enterButton.click();
+ await expect(page.getByText(`${welcomeError} Try again.`)).toBeVisible();
+ await expect(enterButton).toBeEnabled();
+
+ await enterButton.click();
+
+ const skipButton = page.getByRole("button", { name: "Skip for now" });
+ await expect(page.getByText(welcomeError, { exact: true })).toBeVisible();
+ await expect(skipButton).toBeEnabled();
+ await expect(page.getByRole("button", { name: "Back" })).toBeVisible();
+
+ const starterChannelAttempts = await page.evaluate(
+ () =>
+ window.__BUZZ_E2E_COMMANDS__?.filter(
+ (command) => command === "ensure_starter_channels",
+ ).length ?? 0,
+ );
+ expect(starterChannelAttempts).toBe(3);
+
+ await skipButton.click();
- const completionKey = `buzz-community-onboarding-complete.v1:${encodeURIComponent(COMMUNITY_RELAY_URL)}:${WELCOME_FAILURE_PUBKEY}`;
+ await expect(page.getByTestId("community-onboarding-flow")).toHaveCount(0);
+ expect(
+ await page.evaluate(
+ () =>
+ window.__BUZZ_E2E_COMMANDS__?.filter(
+ (command) => command === "ensure_starter_channels",
+ ).length ?? 0,
+ ),
+ ).toBe(3);
await expect
.poll(() =>
page.evaluate(
- ({ completion, transaction }) => ({
- completion: window.localStorage.getItem(completion),
- transaction: window.localStorage.getItem(transaction),
- }),
- { completion: completionKey, transaction: TRANSACTION_STORAGE_KEY },
+ (transaction) => window.localStorage.getItem(transaction),
+ TRANSACTION_STORAGE_KEY,
),
)
- .toEqual({ completion: "true", transaction: null });
- await expect(page.getByTestId("community-onboarding-flow")).toHaveCount(0);
- await expect(page.getByTestId("app-sidebar")).toBeVisible();
+ .toBeNull();
});
test("persisted deep-link invite hands off to Joining after machine onboarding", async ({
diff --git a/desktop/tests/e2e/onboarding.spec.ts b/desktop/tests/e2e/onboarding.spec.ts
index 947e55c7a..28f1865c5 100644
--- a/desktop/tests/e2e/onboarding.spec.ts
+++ b/desktop/tests/e2e/onboarding.spec.ts
@@ -987,18 +987,15 @@ test("connected first-community profile step cannot discard resumable onboarding
await expect(
page.getByRole("heading", { name: "Build your profile" }),
).toBeVisible();
- const profileMain = page.getByTestId("community-profile-main");
- const profileMainBox = await profileMain.boundingBox();
- const viewport = page.viewportSize();
- if (!profileMainBox || !viewport) {
- throw new Error("Could not measure community profile body position");
+ const profileHeading = page.getByRole("heading", {
+ name: "Build your profile",
+ });
+ await expect(profileHeading).toBeVisible();
+ const profileHeadingBox = await profileHeading.boundingBox();
+ if (!profileHeadingBox) {
+ throw new Error("Could not measure community profile heading position");
}
- const chromeOffset = 106;
- const footerOffset = 144;
- const profileMainCenterY = profileMainBox.y + profileMainBox.height / 2;
- const centeredInUsableLaneY =
- chromeOffset + (viewport.height - chromeOffset - footerOffset) / 2;
- expect(Math.abs(profileMainCenterY - centeredInUsableLaneY)).toBeLessThan(32);
+ expect(Math.abs(profileHeadingBox.y - 106)).toBeLessThan(8);
const nameKey = page.getByTestId("community-profile-name-key");
const avatarButton = page.getByTestId("community-avatar-open");
await expect(nameKey).toBeVisible();