Cucumber orchestrates scenarios; Selenium performs browser actions inside the step definitions. Together they form a BDD UI-automation framework, with hooks managing the WebDriver lifecycle and Page Objects encapsulating UI.
The integration pattern: feature files describe behavior, step definitions call Page Object methods that use Selenium WebDriver, and @Before/@After hooks create and quit the driver (often shared via DI). Declarative steps map to high-level Page Object actions (loginPage.loginAs(admin)). WebDriver is shared across step classes through a DI context, not static globals, so scenarios stay isolated and parallel-safe. Reporting attaches screenshots on failure. This layered design (Gherkin → steps → Page Objects → Selenium) keeps each concern separate and is a canonical framework-design interview topic.
Given/When/Then steps call LoginPage/DashboardPage methods that use Selenium; a @Before hook starts ChromeDriver and injects it into the Page Objects via the shared context, and @After quits it and screenshots on failure.
How do you structure a Cucumber + Selenium framework so scenarios stay readable and the WebDriver is managed correctly?