Gherkin Form Decision Checklist
Write BDD Gherkin scenarios that stakeholders and developers agree on before coding -- using a Cloud Architect Profile form as the realistic example project.
note: The below is an example, there are various valid ways to implement the form. The key is to use Gherkin to lock in the expected behavior before writing any component code.
Keep a balanced level of detail in the scenarios -- enough to specify expected behavior without dictating exact implementation.
The scenarios should be readable by non-technical stakeholders while still providing clear guidance for developers.
Why Gherkin Before Code?
Gherkin scenarios are executable specifications written in plain English (Given/When/Then). They bridge the gap between business requirements and test code:
- Stakeholders read them as acceptance criteria
- Developers implement them as automated tests
- QA uses them as the source-of-truth test plan
- Everyone agrees on behavior before a single line of component code is written
The Example Project: Cloud Architect Profile Form
A multi-step form where Cloud Architects enter their professional profile:
| Step | Fields | Types |
|---|---|---|
| 1. Personal Info | Full name, email, phone, LinkedIn URL | text, email, tel, url |
| 2. Experience | Years of experience, current role, certifications (multi-select), bio | number, select, checkbox, textarea |
| 3. Job History | Company name, role, start/end dates, description (repeatable group) | text, select, date, textarea |
| 4. Skills | Cloud platforms (AWS/Azure/GCP), specialties (multi-select), proficiency rating | checkbox, select, radio |
| 5. Uploads | Profile photo, architecture diagrams, site screenshots | file (image), file (multiple) |
| 6. Review & Submit | Summary of all steps, edit links, final submit | read-only, button |
Tech stack: Next.js 15, TypeScript, react-hook-form, zod, shadcn/ui, Tailwind CSS v4
Decision Checklist with Gherkin Scenarios
Each decision below is answered for the Cloud Architect Profile form, followed by the Gherkin scenarios that lock in the expected behavior.
1. What is the purpose of the form?
Decision: Professional profile creation for Cloud Architects -- captures identity, experience, job history, skills, and portfolio uploads for a talent platform.
Why this matters for Gherkin: The purpose drives which fields are required, what validation is critical, and what the post-submit flow looks like.
Feature: Cloud Architect Profile Creation
Background:
Given the architect is logged in
And they navigate to "/profile/create"
Scenario: New architect sees empty profile form
Then they should see a multi-step form with 6 steps
And step 1 "Personal Info" should be active
And a progress indicator should show "Step 1 of 6"
Scenario: Completed profile is visible on the platform
Given the architect has submitted a valid profile
When a recruiter searches for "AWS Solutions Architect"
Then the architect's profile should appear in resultsSuggested approach: Customize fields, validation, and post-submit flow to match the exact use case. This ensures the form solves the real business need instead of building generic fields that may need heavy rework later.
2. How many fields and what types are needed?
Decision: 20+ fields across 6 steps -- text, email, tel, url, number, select, multi-select (checkbox group), radio, date, textarea, and file upload.
Feature: Field Types and Input Behavior
Scenario: Personal Info step has correct field types
Given the architect is on step 1 "Personal Info"
Then the "Full Name" field should be a text input
And the "Email" field should be an email input
And the "Phone" field should be a tel input
And the "LinkedIn URL" field should be a url input
Scenario: Experience step supports multi-select certifications
Given the architect is on step 2 "Experience"
When they check "AWS Solutions Architect Professional"
And they check "Google Cloud Professional Architect"
Then both certifications should be selected
And the selected count should show "2 selected"
Scenario: Job History supports repeatable entries
Given the architect is on step 3 "Job History"
When they click "Add Another Position"
Then a new empty job entry group should appear
And they should be able to add up to 10 positions
Scenario: Skills step uses radio buttons for proficiency
Given the architect is on step 4 "Skills"
When they select "Expert" for AWS proficiency
Then "Expert" should be selected
And "Intermediate" and "Beginner" should not be selectedSuggested approach: Use react-hook-form (uncontrolled under the hood) for this complex form with dynamic field arrays. Prefer useFieldArray for the repeatable Job History entries.
3. Single-page or multi-step form?
Decision: Multi-step with 6 steps. 20+ fields would overwhelm users on a single page.
Feature: Multi-Step Navigation
Scenario: Architect progresses through steps
Given the architect is on step 1 "Personal Info"
And they have filled in all required fields
When they click "Next"
Then step 2 "Experience" should be active
And the progress indicator should show "Step 2 of 6"
Scenario: Architect navigates back without losing data
Given the architect is on step 3 "Job History"
And they have entered "Acme Corp" as company name
When they click "Back"
And they click "Next"
Then the company name field should still contain "Acme Corp"
Scenario: Architect cannot skip ahead past invalid steps
Given the architect is on step 1 "Personal Info"
And the "Full Name" field is empty
When they click step 3 in the progress indicator
Then step 1 should remain active
And a validation error should appear on the "Full Name" field
Scenario: Architect can click completed steps to edit
Given the architect has completed steps 1 through 4
And they are on step 5 "Uploads"
When they click step 2 in the progress indicator
Then step 2 "Experience" should be active
And all previously entered data should be preserved
Scenario: Progress indicator shows completion status
Given the architect has completed steps 1 and 2
And they are on step 3
Then step 1 should show a checkmark icon
And step 2 should show a checkmark icon
And step 3 should show as "current"
And steps 4 through 6 should show as "upcoming"Suggested approach: Use multi-step with a stepper component and react-hook-form. Multi-step reduces cognitive load and improves completion rates. Use a single useForm instance across all steps to preserve state.
4. What validation rules are required?
Decision: Schema-based validation with zod -- required fields, format validation, conditional rules, and cross-field validation.
Feature: Form Validation
Scenario: Required fields show errors when empty
Given the architect is on step 1 "Personal Info"
And they have not filled in any fields
When they click "Next"
Then they should see "Full name is required"
And they should see "Email is required"
And the form should not advance to step 2
Scenario: Email format is validated
Given the architect is on step 1 "Personal Info"
When they type "not-an-email" in the "Email" field
And they click "Next"
Then they should see "Please enter a valid email address"
Scenario: LinkedIn URL must be a valid LinkedIn profile
Given the architect is on step 1 "Personal Info"
When they type "https://twitter.com/someone" in the "LinkedIn URL" field
And they click "Next"
Then they should see "Please enter a valid LinkedIn profile URL"
Scenario: Years of experience must be a positive number
Given the architect is on step 2 "Experience"
When they type "-3" in the "Years of Experience" field
And they click "Next"
Then they should see "Years of experience must be 0 or greater"
Scenario: At least one cloud platform must be selected
Given the architect is on step 4 "Skills"
And no cloud platforms are checked
When they click "Next"
Then they should see "Select at least one cloud platform"
Scenario: Job history dates must be logically valid
Given the architect is on step 3 "Job History"
When they set start date to "2025-06-01"
And they set end date to "2024-01-01"
And they click "Next"
Then they should see "End date must be after start date"
Scenario: Bio has a maximum character limit
Given the architect is on step 2 "Experience"
When they type 1001 characters in the "Bio" field
Then they should see "Bio must be 1000 characters or fewer"
And a character counter should show "1001 / 1000"
Scenario: Real-time validation feedback on email
Given the architect is on step 1 "Personal Info"
When they type "alice@" in the "Email" field
And they move focus to the next field
Then they should see "Please enter a valid email address"
When they go back and type "alice@example.com"
Then the error message should disappearSuggested approach: Use react-hook-form with zod for schema-based validation. Use mode: "onBlur" for real-time feedback on focus loss. Define one zod schema per step and a combined schema for final submission.
5. Where should the data go on submit?
Decision: Server Action with useActionState -- the form submits to the platform's own backend.
Feature: Form Submission
Scenario: Successful profile submission
Given the architect has completed all 6 steps with valid data
When they click "Submit Profile" on the review step
Then a loading spinner should appear on the submit button
And the button should be disabled
And after submission completes they should see "Profile created successfully!"
And they should be redirected to "/profile/me"
Scenario: Server returns validation errors
Given the architect submits a profile with a duplicate email
When the server responds with an error
Then they should see "This email is already registered"
And the form should navigate back to step 1
And the "Email" field should be highlighted
Scenario: Network failure during submission
Given the architect clicks "Submit Profile"
And the network request fails
Then they should see "Something went wrong. Please try again."
And the submit button should be re-enabled
And no data should be lost
Scenario: Form data is sent as multipart/form-data
Given the architect has uploaded a profile photo
And they have filled all required fields
When they submit the form
Then the request should include the photo as a file upload
And all text fields should be included in the payloadSuggested approach: Use server actions with useActionState for the own backend. Handle pending state, errors, and progressive enhancement out of the box. Use FormData for file uploads.
6. Any special UI/UX or styling requirements?
Decision: shadcn/ui with Tailwind CSS v4, dark mode support, and animated step transitions.
Feature: UI/UX Requirements
Scenario: Form renders with shadcn/ui components
Given the architect opens the profile form
Then all inputs should use shadcn/ui styled components
And buttons should follow the design system
And the form should have consistent spacing and typography
Scenario: Dark mode support
Given the system is in dark mode
When the architect opens the profile form
Then all form elements should render with dark theme colors
And contrast ratios should meet WCAG AA standards
Scenario: Step transitions are animated
Given the architect is on step 1
When they click "Next"
Then step 1 should slide out to the left
And step 2 should slide in from the right
And the transition should complete within 300ms
Scenario: Form is visually organized with sections
Given the architect is on step 2 "Experience"
Then the certifications should be grouped in a card
And the bio field should span the full width
And help text should appear below complex fieldsSuggested approach: Use shadcn/ui with Tailwind as the most accessible option. shadcn/ui offers fully customizable, accessible components without the bundle size overhead of larger UI libraries.
7. Accessibility and mobile requirements?
Decision: Full WCAG 2.1 AA compliance, keyboard navigation, screen reader support, responsive design.
Feature: Accessibility
Scenario: All fields have accessible labels
Given the architect is on any form step
Then every input should have an associated label element
And every required field should have aria-required="true"
Scenario: Keyboard navigation through form
Given the architect is on step 1
When they press Tab
Then focus should move to the first input field
And they should be able to Tab through all fields in order
And they should be able to submit using Enter
Scenario: Screen reader announces validation errors
Given the architect submits step 1 with empty required fields
Then each error message should have role="alert"
And the screen reader should announce the first error
Scenario: Screen reader announces step changes
Given the architect completes step 1 and moves to step 2
Then the screen reader should announce "Step 2 of 6: Experience"
Scenario: Mobile responsive layout
Given the architect is using a mobile device (viewport 375px)
Then the form should stack fields vertically
And the progress indicator should be compact
And touch targets should be at least 44x44 pixels
And the "Next" and "Back" buttons should be full-widthSuggested approach: Use semantic HTML, react-hook-form built-in accessibility, and Tailwind responsive classes. Proper accessibility from the start avoids costly fixes later and ensures WCAG compliance.
8. Should the form support file uploads?
Decision: Yes -- profile photo (single image), architecture diagrams (multiple images), and site screenshots (multiple images).
Feature: File Uploads
Scenario: Architect uploads a profile photo
Given the architect is on step 5 "Uploads"
When they select a JPEG file under 5MB for "Profile Photo"
Then a thumbnail preview should appear
And the file name and size should be displayed
Scenario: Profile photo validates file type
Given the architect is on step 5 "Uploads"
When they select a .exe file for "Profile Photo"
Then they should see "Only JPEG, PNG, and WebP files are accepted"
And the file should not be uploaded
Scenario: Profile photo validates file size
Given the architect is on step 5 "Uploads"
When they select a 15MB image for "Profile Photo"
Then they should see "File must be under 5MB"
Scenario: Architect uploads multiple architecture diagrams
Given the architect is on step 5 "Uploads"
When they select 3 PNG files for "Architecture Diagrams"
Then 3 thumbnail previews should appear
And each should show a remove button
And the upload count should show "3 files selected"
Scenario: Architect removes an uploaded file
Given the architect has uploaded 3 architecture diagrams
When they click the remove button on the second diagram
Then only 2 thumbnails should remain
And the removed file should no longer be in the form data
Scenario: Drag and drop file upload
Given the architect is on step 5 "Uploads"
When they drag a PNG file into the "Architecture Diagrams" drop zone
Then the drop zone should highlight
And when they drop the file a thumbnail preview should appear
Scenario: Maximum file count is enforced
Given the architect has uploaded 10 architecture diagrams
When they try to add another file
Then they should see "Maximum 10 files allowed"
And the file input should be disabledSuggested approach: Use input type="file" with react-hook-form and handle with FormData for the API. Use URL.createObjectURL for client-side previews. Validate type and size on the client before upload.
9. Do you prefer TypeScript or JavaScript? Any state management preferences?
Decision: TypeScript with react-hook-form and zod. Form state lives in react-hook-form; no external state manager needed.
Feature: Type Safety and State Management
Scenario: Form schema is defined with zod
Given the developer creates the form schema
Then each step should have its own zod schema
And a combined schema should validate the full profile
And TypeScript types should be inferred from the schema
Scenario: Form state persists across steps
Given the architect fills in step 1 and moves to step 3
When they navigate back to step 1
Then all fields should retain their values
And no external state store should be required
Scenario: Type errors are caught at compile time
Given the developer passes incorrect field types
Then the TypeScript compiler should report an error
And the build should fail before runtimeSuggested approach: TypeScript with react-hook-form and zod is the strongly recommended default. TypeScript catches errors early and zod provides runtime validation that matches compile-time types.
10. Any tech stack constraints or preferred libraries?
Decision: Next.js 15 with App Router, TypeScript, react-hook-form, zod, shadcn/ui, and Tailwind CSS v4.
Feature: Tech Stack Integration
Scenario: Form works with App Router server actions
Given the form component is a Client Component
When the architect submits the form
Then data should be processed by a Server Action
And the page should not require a full reload
Scenario: Form works without JavaScript (progressive enhancement)
Given JavaScript is disabled in the browser
When the architect submits the form
Then the form should still submit via native HTML form submission
And server-side validation should catch any errors
Scenario: Form loads performantly
Given the architect navigates to the profile form
Then the initial bundle should not exceed 50KB gzipped for the form
And code splitting should load step components lazily
And the Largest Contentful Paint should be under 2.5 secondsSuggested approach: Use Next.js 15 with App Router, TypeScript, react-hook-form, zod, and shadcn/ui unless specified otherwise. This modern stack delivers great performance, SEO benefits, and a smooth development experience.
Putting It All Together: The Full Gherkin Suite
Once all 10 decisions are made, the complete Gherkin feature files become the contract between stakeholders and developers:
features/
profile-form/
01-purpose.feature # What the form does
02-field-types.feature # Input types and behavior
03-multi-step.feature # Navigation and progress
04-validation.feature # All validation rules
05-submission.feature # Submit flow and error handling
06-ui-ux.feature # Styling and interactions
07-accessibility.feature # WCAG compliance
08-file-uploads.feature # Upload behavior
09-type-safety.feature # TypeScript/schema guarantees
10-tech-stack.feature # Performance and integration
Running Gherkins as Automated Tests
These Gherkin scenarios translate directly into Playwright + cucumber tests:
// features/step-definitions/multi-step.steps.ts
import { Given, When, Then } from "@cucumber/cucumber";
import { expect } from "@playwright/test";
Given("the architect is on step {int} {string}", async function (step, name) {
await this.page.goto("/profile/create");
for (let i = 1; i < step; i++) {
await fillStepWithValidData(this.page, i);
await this.page.getByRole("button", { name: "Next" }).click();
}
await expect(this.page.getByText(`Step ${step} of 6`)).toBeVisible();
});
When("they click {string}", async function (buttonText) {
await this.page.getByRole("button", { name: buttonText }).click();
});
Then("step {int} {string} should be active", async function (step, name) {
await expect(this.page.getByRole("heading", { name })).toBeVisible();
await expect(this.page.getByText(`Step ${step} of 6`)).toBeVisible();
});Recipe
Quick-reference recipe card -- copy-paste ready.
# Template: Gherkin scenario for any form decision
Feature: [Decision Area] -- [Form Name]
Background:
Given the user is logged in
And they navigate to "[form URL]"
Scenario: Happy path -- [what should happen]
Given [precondition]
When [user action]
Then [expected outcome]
Scenario: Validation -- [what should be rejected]
Given [precondition]
When [invalid action]
Then [error message or blocked behavior]
Scenario: Edge case -- [boundary condition]
Given [precondition]
When [edge case action]
Then [expected handling]When to reach for this: Before writing any form component code. Run through the 10-question checklist with stakeholders, write the Gherkin scenarios, get sign-off, then implement.
Gotchas
-
Writing Gherkins after the code -- defeats the purpose. Write them first so stakeholders can review behavior before implementation begins.
-
Too much implementation detail in scenarios -- Gherkin should describe what happens, not how. Write
Then they should see "Email is required"notThen the zod schema should return an error object with path email. -
Skipping the Background block -- repeated Given steps bloat every scenario. Extract common preconditions into Background.
-
One giant feature file -- split by decision area (validation, navigation, uploads) so different team members can own different files.
-
Not mapping scenarios to test code -- Gherkins without automation become stale documentation. Use Playwright + Cucumber or similar to keep them executable.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| User Stories only | Simple forms with few stakeholders | Complex forms needing precise behavior specs |
| Acceptance criteria in Jira/Linear | Team prefers issue trackers over feature files | You want executable specifications |
| Storybook interaction tests | Visual testing is the priority | You need stakeholder-readable specs |
| Plain Playwright tests | Dev team writes tests without stakeholder review | Business and dev need a shared language |
Related
- Testing Forms -- unit testing form components with Testing Library
- Playwright Setup -- configuring Playwright for E2E tests
- Playwright Patterns -- common Playwright testing patterns
- Forms & Validation section -- building forms with react-hook-form and zod