A well-designed framework is layered: test layer (scenarios/assertions), business/page layer (Page Objects, workflows), core/utility layer (driver management, waits, config, reporting), and data layer — each with a single responsibility and depending only downward.
Separation of concerns keeps each layer focused: tests express WHAT to verify; page objects encapsulate HOW to interact with each page; a core layer provides cross-cutting services (WebDriverFactory, WaitUtils, ConfigReader, ReportManager, Logger); and a data layer supplies inputs. Tests depend on pages, pages on core utilities, but not the reverse — a clean dependency direction. This makes the framework maintainable (change one layer without breaking others), testable, and onboardable. Mixing concerns (assertions in page objects, driver creation in tests, hard-coded data in scripts) is the hallmark of an unmaintainable framework and a frequent design-review finding.
A framework where tests never touch WebDriver directly (they call page methods), pages never create drivers (a DriverFactory does), and config/reporting live in a core layer — so swapping the reporting tool touches one layer only.
Describe the layers of a maintainable Selenium framework and why the separation matters.