</>

Technology

Cucumber

Difficulty

Advanced

Interview Question

A developer changes a UI element locator and breaks 50 Cucumber scenarios. How do you prevent this from recurring?

Answer

Preventing Locator-Based Cucumber Test Breakage

Why 50 Tests Broke

Root cause: Locators were scattered in step definitions:

Java
// BAD — locator in step definition
@When("the user clicks the login button")
public void clickLogin() {
    driver.findElement(By.css(".btn-primary")).click();  // if this changes → 1 test breaks
}

// If the SAME locator is copy-pasted in 50 step methods:
// Developer changes class "btn-primary" → "btn-login-submit"
// → 50 tests break at once

Fix 1: Single Source of Truth — Locators Only in Page Objects

Java
// LoginPage.java — ONE place for all login locators
public class LoginPage extends BasePage {

    // Define locators ONCE
    private static final By USERNAME_FIELD = By.id("username");
    private static final By PASSWORD_FIELD = By.id("password");
    private static final By LOGIN_BUTTON   = By.css("[data-testid='login-submit']");
    private static final By ERROR_MESSAGE  = By.css(".error-banner");

    public void enterUsername(String u) {
        waitForClickable(USERNAME_FIELD).clear();
        waitForClickable(USERNAME_FIELD).sendKeys(u);
    }

    public void clickLogin() {
        waitForClickable(LOGIN_BUTTON).click();
    }
}

// Step definition — ZERO locators, only page object calls
@When("the user clicks the Login button")
public void clickLogin() {
    ctx.loginPage.clickLogin();  // if locator changes → fix in ONE place
}

Fix 2: data-testid Agreement with Developers

Negotiate with the dev team:

HTML
<!-- Developers add stable test attributes -->
<button data-testid="login-submit">Login</button>
<input  data-testid="username-field" />
<div    data-testid="error-banner" />
Java
// Locator uses data-testid — never changes even if CSS class changes
private static final By LOGIN_BUTTON = By.cssSelector("[data-testid='login-submit']");

Why data-testid is better:

  • CSS classes change for design reasons
  • IDs get reused across pages
  • data-testid is explicitly for testing → developers know not to rename it casually

Fix 3: PR Checks — Run @smoke in CI Before Merge

GROOVY
// Jenkinsfile (PR validation pipeline)
stage('Smoke Tests') {
    when { changeRequest() }  // runs on every PR
    steps {
        sh 'mvn test -Dcucumber.filter.tags="@smoke" -Dheadless=true'
    }
    post {
        failure {
            // PR cannot be merged if smoke fails
            error 'Smoke tests failed — locator may have broken. Fix before merge.'
        }
    }
}

This catches locator breaks before the developer''s change reaches main.

Fix 4: Page Object Registry (Centralized Locator Map)

Java
public class LoginPageLocators {
    public static final By USERNAME     = By.id("username");
    public static final By PASSWORD     = By.id("password");
    public static final By SUBMIT       = By.cssSelector("[data-testid='login-btn']");
    public static final By ERROR        = By.cssSelector(".alert-error");
    public static final By FORGOT_PASS  = By.linkText("Forgot Password?");
}

// Page Object uses the registry
public class LoginPage extends BasePage {
    public void clickLogin() {
        waitForClickable(LoginPageLocators.SUBMIT).click();
    }
}

Fix 5: Immediate Recovery Protocol

CODE
When 50 tests break:
1. grep for the broken locator across all Page Objects: grep -rn "btn-primary" src/
2. Fix in Page Object only — step defs unchanged
3. Re-run: mvn test -Dcucumber.filter.tags="@regression"
4. 5-minute fix instead of 2-day crisis

Summary: Prevention Checklist

CODE
✅ Locators ONLY in Page Objects — never in step definitions
✅ data-testid attributes on all interactable elements
✅ @smoke runs on every PR via CI gating
✅ Page Object per page/component (not one huge class)
✅ Grep-check before changing any UI element attribute names

Follow AutomateQA

Related Topics