QA Labs
QA Labs
Phase 5

Kata 26: KYC Onboarding Flow

Kata 26: KYC Onboarding Flow

What You Will Learn

  • How to test multi-step wizard/onboarding flows end-to-end
  • How to verify progress indicators update correctly per step
  • How to navigate back and forth between steps without losing data
  • How to simulate file uploads in Playwright and Cypress
  • How to verify review/summary pages reflect previously entered data
  • How to validate required fields at each step before advancing
  • How to test both success and failure outcomes of a form submission

Prerequisites

  • Completed Katas 1-25 (especially form and navigation katas)
  • Understanding of multi-step form patterns
  • Familiarity with file input handling in browser tests

Concepts Explained

Multi-Step Onboarding Flows

KYC (Know Your Customer) onboarding is a common fintech pattern
where users complete identity verification in a guided, multi-step flow.

Typical steps:
  1. Welcome / introduction page
  2. Personal information form (name, email, DOB, country)
  3. Document upload (passport, driver's license, etc.)
  4. Review summary — user confirms all entered data
  5. Submission result — success or failure

Testing challenges:
  - Each step has its own validation rules
  - Data entered in step 2 must appear correctly in step 4
  - Navigation backward should preserve previously entered data
  - Progress indicators must reflect the current step
  - The final submission may succeed or fail

Simulating File Uploads

Playwright:
  // setInputFiles() sets files on a file input element.
  // This simulates the user selecting a file in the file picker dialog.
  await page.getByTestId('file-input').setInputFiles({
    name: 'passport.pdf',
    mimeType: 'application/pdf',
    buffer: Buffer.from('fake-pdf-content')
  });

Cypress:
  // selectFile() is a Cypress command that simulates file selection.
  // It creates a File object and triggers the change event on the input.
  cy.get('[data-testid="file-input"]').selectFile({
    contents: Cypress.Buffer.from('fake-pdf-content'),
    fileName: 'passport.pdf',
    mimeType: 'application/pdf'
  }, { force: true });

Testing Data Flow Across Steps

A key testing concern in multi-step flows: does data entered in
earlier steps appear correctly on the review page?

Pattern:
  1. Fill in fields on step 2 with known values
  2. Proceed to step 3 (document upload)
  3. Proceed to step 4 (review)
  4. Assert that each review field matches what was entered

This catches bugs where:
  - Field values are not carried forward
  - Field values are swapped or truncated
  - Select dropdown shows the value code instead of the display text

Playground

The playground is a complete KYC onboarding application with five steps:

  1. Welcome — introduction page with a "Get Started" button
  2. Personal Info — form with first name, last name, email, DOB, country
  3. Document Upload — document type selector and file upload area
  4. Review — summary table showing all entered data
  5. Result — success or failure message after submission

Features:

  • Progress bar with 5 numbered steps (completed / active / pending states)
  • Validation errors shown per step when required fields are empty
  • Upload area that shows the selected filename
  • Review table that auto-populates from entered data
  • Success result with random reference number
  • Failure result triggered by email containing "fail"

Exercises

Exercise 1: Complete Happy Path End-to-End

Walk through all 5 steps: click Get Started, fill personal info, upload a document, review, and submit. Verify the success result page appears.

Exercise 2: Verify Each Step Content

Navigate through each step and verify its heading and key content elements are visible.

Exercise 3: Navigate Back and Forth

Go to step 2, fill data, go to step 3, then navigate back to step 2. Verify the previously entered data is still present.

Exercise 4: Verify Review Page Data

Fill in personal info and upload a document, then verify the review page shows every field value correctly.

Exercise 5: Submit and Verify Success

Complete the flow and verify the success icon, title, message, and reference number appear.

Exercise 6: Validate Required Fields Per Step

Try to advance from step 2 without filling fields. Verify validation errors appear. Try to advance from step 3 without uploading. Verify the upload error appears.

Exercise 7: Verify Progress Indicator

At each step, verify the progress bar highlights the correct step as "active" and marks previous steps as "completed".

Exercise 8: Test With Different Applicant Data

Run the flow twice with different data sets (different names, emails, countries). Verify the review page reflects each data set correctly. Use an email containing "fail" to trigger the failure result.

Solutions

Playwright Solution

See playwright/kyc-onboarding-flow.spec.ts

Cypress Solution

See cypress/kyc-onboarding-flow.cy.ts

Common Mistakes

MistakeWhy it's wrongFix
Not waiting for step transitionSteps change via CSS class toggle; asserting too early may target the wrong stepWait for the target step's data-testid to be visible
Using fill() on a hidden file inputThe file input is hidden; fill() doesn't work for file inputsUse setInputFiles() (Playwright) or selectFile() (Cypress)
Checking review data before navigating to step 4Review table is populated only when step 4 becomes activeNavigate to step 4 first, then assert review values
Not resetting state between testsEach test should start fresh; leftover data from a previous test can cause false passesNavigate to the playground URL at the start of each test
Forgetting the submit delaySubmission has a 1-second simulated delayWait for the result step to be visible before asserting

Quick Reference

Playwright Multi-Step Flow Testing

ActionMethodExample
Click buttonlocator.click()await page.getByTestId('btn-start').click()
Fill inputlocator.fill()await page.getByTestId('input-first-name').fill('John')
Select optionlocator.selectOption()await page.getByTestId('select-country').selectOption('US')
Upload filelocator.setInputFiles()await page.getByTestId('file-input').setInputFiles(...)
Check visibilityexpect(locator).toBeVisible()await expect(page.getByTestId('step-review')).toBeVisible()
Check textexpect(locator).toHaveText()await expect(page.getByTestId('review-email')).toHaveText('a@b.com')
Check classexpect(locator).toHaveClass()await expect(step).toHaveClass(/active/)

Cypress Multi-Step Flow Testing

ActionMethodExample
Click buttoncy.get().click()cy.get('[data-testid="btn-start"]').click()
Fill inputcy.get().type()cy.get('[data-testid="input-first-name"]').type('John')
Select optioncy.get().select()cy.get('[data-testid="select-country"]').select('US')
Upload filecy.get().selectFile()cy.get('[data-testid="file-input"]').selectFile(...)
Check visibility.should('be.visible')cy.get('[data-testid="step-review"]').should('be.visible')
Check text.should('have.text')cy.get('[data-testid="review-email"]').should('have.text', 'a@b.com')
Check class.should('have.class')cy.get('[data-testid="progress-step-2"]').should('have.class', 'active')