Skip to content

fix: show whitespace-only error on Create workspace and collection modal#7883

Open
prateek-bruno wants to merge 8 commits intousebruno:mainfrom
prateek-bruno:bugfix/validate-create-workspace-btn
Open

fix: show whitespace-only error on Create workspace and collection modal#7883
prateek-bruno wants to merge 8 commits intousebruno:mainfrom
prateek-bruno:bugfix/validate-create-workspace-btn

Conversation

@prateek-bruno
Copy link
Copy Markdown
Collaborator

@prateek-bruno prateek-bruno commented Apr 29, 2026

Description

Jira

What this does:

  • Validate whitespace-only collection/workspace name input
  • Fix stale formik values, by updating logic of onChange

After:

Create collection modal:

Screen.Recording.2026-05-07.at.3.53.07.PM.mov

Create workspace modal:

Screen.Recording.2026-05-07.at.3.52.07.PM.mov

Before:

Create collection modal:

Screen.Recording.2026-05-07.at.3.54.17.PM.mov

Create workspace modal:

Screen.Recording.2026-01-09.at.5.15.58.PM.mov

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds local submit wrappers that validate and mark touched fields before delegating to Formik, normalizes validation messages to "can't be empty", auto-synchronizes sanitized folder names from workspace/collection names when folder-name editing is inactive, and updates Playwright tests to assert whitespace-only name validation.

Changes

CreateWorkspace component

Layer / File(s) Summary
Validation message
packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js
Changed workspace name validation text to “Workspace name can’t be empty”.
Submit handler (core)
packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js
Added handleSubmit(e) that prevents default, calls formik.validateForm(), touches workspaceName, workspaceFolderName, and workspaceLocation on errors, otherwise calls formik.handleSubmit().
Modal wiring
packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js
Modal confirm and form onSubmit wired to handleSubmit; confirm button remains disabled based on isSubmitting.
Name → Folder auto-sync
packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js
workspaceName onChange auto-updates workspaceFolderName with sanitizeName(workspaceName) when not in folder-name edit mode; preserves manual edits when edit mode is active.
Tests — create workspace modal
tests/workspace/create-workspace/create-workspace.spec.ts
Replaced empty-name advanced modal test with a whitespace-only name test that asserts modal remains visible and shows “Workspace name can’t be empty”.

CreateCollection component

Layer / File(s) Summary
Validation message
packages/bruno-app/src/components/Sidebar/CreateCollection/index.js
Changed collection name minimum-length validation text to “Collection name can’t be empty”.
Submit handler (core)
packages/bruno-app/src/components/Sidebar/CreateCollection/index.js
Added handleSubmit(e) that prevents default, calls formik.validateForm(), touches collectionName on errors, and otherwise calls formik.handleSubmit(); form onSubmit switched to wrapper.
Name → Folder auto-sync
packages/bruno-app/src/components/Sidebar/CreateCollection/index.js
collectionName onChange now updates collectionFolderName via sanitizeName(collectionName) when not editing folder name; preserves manual edits when edit mode is active.
Tests — create collection modal
tests/collection/create/create-collection.spec.ts
Added Playwright test asserting whitespace-only collection name keeps modal open and shows “Collection name can’t be empty”.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • usebruno/bruno#6481 — Modifies CreateWorkspace folder-name behavior and sanitization wiring.
  • usebruno/bruno#7324 — Overlaps with create-flow submit and name/folder synchronization changes.

Suggested labels

size/M

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno
  • sid-bruno

Poem

✨ Type a name, spaces won't sneak through,
The submit checks, marks fields, then validates true.
Folder names trimmed unless edits remain,
Tests keep modals open when blanks try in vain. 🛠️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing validation error display for whitespace-only input in Create workspace and collection modals.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js`:
- Around line 122-126: The current snapshot-based call to formik.setValues({
...formik.values, workspaceName, workspaceFolderName:
sanitizeName(workspaceName) }) can overwrite async updates (e.g.,
browseDirectory setting workspaceLocation); change it to use a functional
updater so you merge into the latest state: call formik.setValues(prev => ({
...prev, workspaceName, workspaceFolderName: sanitizeName(workspaceName) })) to
avoid losing workspaceLocation or other concurrent changes from async operations
like browseDirectory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c8c7e82b-19b5-4fdc-94a8-8d082df2ead2

📥 Commits

Reviewing files that changed from the base of the PR and between 13a9f9b and fb96ddc.

📒 Files selected for processing (1)
  • packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js

Comment thread packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js Outdated
@prateek-bruno prateek-bruno force-pushed the bugfix/validate-create-workspace-btn branch from cb81f05 to 40261e9 Compare May 7, 2026 10:05
@pull-request-size pull-request-size Bot added size/M and removed size/S labels May 7, 2026
@prateek-bruno prateek-bruno changed the title fix: disable "Create workspace" button if validation fails fix: show error if validation fails on "Create workspace" May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/workspace/create-workspace/create-workspace.spec.ts (1)

391-391: 💤 Low value

submitButton locator is duplicated across two test.step blocks.

Lines 382 and 391 each create the same locator. Since Playwright locators are lazy, you can hoist it above both steps.

♻️ Suggested refactor
+      const modal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Workspace' });
+      const submitButton = modal.getByRole('button', { name: 'Create Workspace' });
+
       await test.step('Enter whitespace-only name and submit', async () => {
-        const modal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Workspace' });
         await modal.waitFor({ state: 'visible', timeout: 5000 });
-        const submitButton = modal.getByRole('button', { name: 'Create Workspace' });
         await modal.locator('#workspace-name').fill('   ');
         await expect(submitButton).toBeEnabled();
         await submitButton.click();
       });

       await test.step('Verify validation error appears and modal stays open', async () => {
-        const modal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Workspace' });
-        const submitButton = modal.getByRole('button', { name: 'Create Workspace' });
         await expect(modal).toBeVisible();
         await expect(submitButton).toBeEnabled();
         await expect(modal.getByText("Workspace name can't be empty")).toBeVisible({ timeout: 2000 });
       });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/workspace/create-workspace/create-workspace.spec.ts` at line 391, The
locator submitButton is created twice inside separate test.step blocks; hoist
its creation to a shared scope above both steps by moving const submitButton =
modal.getByRole('button', { name: 'Create Workspace' }); out of the individual
test.step blocks so both steps reuse the same Playwright locator (referencing
modal and submitButton) to avoid duplication and keep the lazy locator
semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/workspace/create-workspace/create-workspace.spec.ts`:
- Around line 385-386: The test's assertions on submitButton contradict the PR
intent: with a whitespace-only name the form is invalid yet the test uses
submitButton.toBeEnabled() (and again at the later check), so either change both
assertions that reference submitButton (the ones around the initial click and
the post-submit check) to toBeDisabled() to reflect a live-disabled button on
validation failure, or if the intended behavior is validate-on-submit (button
remains enabled), remove the redundant post-submit toBeEnabled() check and
update the PR description to state validate-on-submit; locate the submitButton
assertions in this spec (the expectations currently calling toBeEnabled() at the
two places noted) and apply the corresponding assertion/removal based on the
chosen design.

---

Nitpick comments:
In `@tests/workspace/create-workspace/create-workspace.spec.ts`:
- Line 391: The locator submitButton is created twice inside separate test.step
blocks; hoist its creation to a shared scope above both steps by moving const
submitButton = modal.getByRole('button', { name: 'Create Workspace' }); out of
the individual test.step blocks so both steps reuse the same Playwright locator
(referencing modal and submitButton) to avoid duplication and keep the lazy
locator semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 21cbd270-c502-4ce9-a392-5db217f45919

📥 Commits

Reviewing files that changed from the base of the PR and between cb81f05 and 40261e9.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js
  • tests/workspace/create-workspace/create-workspace.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js

Comment thread tests/workspace/create-workspace/create-workspace.spec.ts
Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
@prateek-bruno prateek-bruno changed the title fix: show error if validation fails on "Create workspace" fix: show whitespace-only error on Create workspace and collection modal May 7, 2026
Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
@pull-request-size pull-request-size Bot added size/L and removed size/M labels May 7, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
packages/bruno-app/src/components/Sidebar/CreateCollection/index.js (1)

78-93: 💤 Low value

handleSubmit wrapper is redundant — consider simplifying.

Formik v2's SUBMIT_ATTEMPT reducer already sets touched: setNestedObjectValues(state.values, true) across all fields, and Formik skips calling onSubmit when validateForm returns errors. The custom wrapper reproduces this behavior and also triggers a double validateForm call (line 81 + Formik's internal run inside handleSubmit on line 92). With .trim() in the Yup schema as the actual fix, the wrapper is purely additive.

♻️ Simplified approach (drops the wrapper entirely)
-  const handleSubmit = async (e) => {
-    e?.preventDefault?.();
-
-    const errors = await formik.validateForm();
-    if (Object.keys(errors).length > 0) {
-      formik.setTouched({
-        collectionName: true,
-        collectionFolderName: true,
-        collectionLocation: true,
-        format: true
-      });
-      return;
-    }
-
-    formik.handleSubmit();
-  };

   // ...

-  <form className="bruno-form" onSubmit={handleSubmit}>
+  <form className="bruno-form" onSubmit={formik.handleSubmit}>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-app/src/components/Sidebar/CreateCollection/index.js` around
lines 78 - 93, The custom handleSubmit wrapper is redundant and causes duplicate
validation; remove the wrapper and wire the form submit directly to
formik.handleSubmit (drop the async handleSubmit function that calls
formik.validateForm and formik.setTouched), since Formik's SUBMIT_ATTEMPT
already sets touched across values and Formik itself will skip onSubmit if
validateForm returns errors; ensure any submit handlers or JSX that referenced
handleSubmit now call formik.handleSubmit directly.
tests/collection/create/create-collection.spec.ts (2)

10-31: ⚡ Quick win

Add test.step blocks — required per coding guidelines.

The test has three distinct phases (open modal → submit invalid input → close), each of which maps cleanly to a named step. Without them, failed runs in Playwright reports produce a flat stack with no phase context.

♻️ Proposed refactor with `test.step`
  test('should show validation error for whitespace-only name in modal and keep modal open', async ({ page }) => {
+   const createCollectionModal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Collection' });
+
+   await test.step('Open Create Collection modal', async () => {
      await page.getByTestId('collections-header-add-menu').click();
      await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();

      const inlineCreator = page.locator('.inline-collection-creator');
      await inlineCreator.waitFor({ state: 'visible', timeout: 5000 });
      await inlineCreator.locator('.cog-btn').click();

-     const createCollectionModal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Collection' });
      await createCollectionModal.waitFor({ state: 'visible', timeout: 5000 });
+   });

+   await test.step('Submit whitespace-only name and verify validation error', async () => {
      const submitButton = createCollectionModal.getByRole('button', { name: 'Create', exact: true });
      await createCollectionModal.getByLabel('Name').fill('   ');
      await expect(submitButton).toBeEnabled();
      await submitButton.click();

      await expect(createCollectionModal).toBeVisible();
      await expect(submitButton).toBeEnabled();
      await expect(createCollectionModal.getByText('Collection name can\'t be empty')).toBeVisible({ timeout: 2000 });
+   });

+   await test.step('Close the modal', async () => {
      await createCollectionModal.getByRole('button', { name: 'Cancel' }).click();
+   });
  });

As per coding guidelines: "Promote the use of test.step as much as possible so the generated reports are easier to read."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/collection/create/create-collection.spec.ts` around lines 10 - 31, Wrap
the three logical phases of the test ("open modal", "submit invalid input",
"close modal") in Playwright test.step calls with descriptive names to improve
report readability: surround the initial flow that clicks the add menu, selects
"Create collection", waits for inlineCreator and clicks the cog (referencing
inlineCreator), then a step for filling the Name with whitespace, asserting
submitButton state and clicking it (referencing submitButton and
createCollectionModal), and finally a step for asserting the validation message
and clicking the Cancel button (referencing createCollectionModal); keep
existing awaits and assertions but move them into these test.step blocks so each
phase appears as a named step in test reports.

12-19: ⚖️ Poor tradeoff

CSS class selectors are fragile — prefer data-testid for Playwright locators.

Lines 12–19 use .tippy-box .dropdown-item, .inline-collection-creator, .cog-btn, and .bruno-modal-card — all of which break silently on CSS renames. The guideline prescribes data-testid for testable elements. collections-header-add-menu on line 11 already follows this pattern correctly.

Adding data-testid attributes to the corresponding component files (inline creator, cog button, modal card) would allow these locators to be migrated to getByTestId(...) calls, making the test resilient to style changes.

As per coding guidelines: "Add data-testid to testable elements for Playwright."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/collection/create/create-collection.spec.ts` around lines 12 - 19,
Replace fragile CSS class locators with stable data-testid locators: add
data-testid attributes to the inline collection creator component, its cog
button, and the modal card (the elements currently targeted by the selectors
'.inline-collection-creator', '.cog-btn', and '.bruno-modal-card') and update
the test to use Playwright's getByTestId (or page.getByTestId) calls instead of
'.tippy-box .dropdown-item' / '.inline-collection-creator' / '.cog-btn' /
'.bruno-modal-card'; keep the existing 'collections-header-add-menu' testid
pattern as a reference when naming the new testids so the test becomes resilient
to CSS renames.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/bruno-app/src/components/Sidebar/CreateCollection/index.js`:
- Around line 78-93: The custom handleSubmit wrapper is redundant and causes
duplicate validation; remove the wrapper and wire the form submit directly to
formik.handleSubmit (drop the async handleSubmit function that calls
formik.validateForm and formik.setTouched), since Formik's SUBMIT_ATTEMPT
already sets touched across values and Formik itself will skip onSubmit if
validateForm returns errors; ensure any submit handlers or JSX that referenced
handleSubmit now call formik.handleSubmit directly.

In `@tests/collection/create/create-collection.spec.ts`:
- Around line 10-31: Wrap the three logical phases of the test ("open modal",
"submit invalid input", "close modal") in Playwright test.step calls with
descriptive names to improve report readability: surround the initial flow that
clicks the add menu, selects "Create collection", waits for inlineCreator and
clicks the cog (referencing inlineCreator), then a step for filling the Name
with whitespace, asserting submitButton state and clicking it (referencing
submitButton and createCollectionModal), and finally a step for asserting the
validation message and clicking the Cancel button (referencing
createCollectionModal); keep existing awaits and assertions but move them into
these test.step blocks so each phase appears as a named step in test reports.
- Around line 12-19: Replace fragile CSS class locators with stable data-testid
locators: add data-testid attributes to the inline collection creator component,
its cog button, and the modal card (the elements currently targeted by the
selectors '.inline-collection-creator', '.cog-btn', and '.bruno-modal-card') and
update the test to use Playwright's getByTestId (or page.getByTestId) calls
instead of '.tippy-box .dropdown-item' / '.inline-collection-creator' /
'.cog-btn' / '.bruno-modal-card'; keep the existing
'collections-header-add-menu' testid pattern as a reference when naming the new
testids so the test becomes resilient to CSS renames.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 70eca5eb-8ddf-4790-a0c2-d000601c57ab

📥 Commits

Reviewing files that changed from the base of the PR and between 40261e9 and bcb457f.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/Sidebar/CreateCollection/index.js
  • tests/collection/create/create-collection.spec.ts

Comment thread packages/bruno-app/src/components/Sidebar/CreateCollection/index.js Outdated
Comment thread packages/bruno-app/src/components/Sidebar/CreateCollection/index.js Outdated
prateek-bruno and others added 2 commits May 7, 2026 19:19
Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
@pull-request-size pull-request-size Bot added size/M and removed size/L labels May 7, 2026
Copy link
Copy Markdown
Collaborator

@gopu-bruno gopu-bruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to have the original empty name test alongside the new whitespace one. Rest LGTM

Co-authored-by: Prateek Sunal <prtksunal@gmail.com>
@pull-request-size pull-request-size Bot removed the size/M label May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants