This is the make-or-break round. When the interviewer says "Describe your framework," they are assessing whether you are a script writer or a framework builder. Prepare a 5-minute walkthrough of your framework architecture, covering every layer from test to config. Practice it until it flows naturally.
Q: Describe the architecture of your automation framework.
A: My framework follows a layered architecture with clear separation of concerns. (1) Test Layer — TestNG test classes extending BaseTest. Each @Test method contains test steps and assertions. Tests are organized by module: LoginTest, DashboardTest, CartTest. (2) Page Object Layer — page classes extending BasePage. Private locators, public action methods. BasePage has common methods: waitForVisible(), click(), type(), getText(). (3) Utility Layer — reusable utilities: ExcelReader (Apache POI), ScreenshotUtil, ConfigReader (Singleton), BrowserFactory (Factory Pattern), WaitUtil. (4) Configuration Layer — config.properties for URLs, browser, timeouts. testng.xml for suite configuration. (5) Test Data Layer — Excel files in src/test/resources/testdata, managed through DataProvider. (6) Reporting Layer — Allure reports integrated via ITestListener for step logging and screenshot attachment on failure. Project structure follows Maven: src/main/java for framework code, src/test/java for tests, src/test/resources for configs and data.
Q: What design patterns do you use in your framework?
A: Five patterns: (1) Page Object Model — each page is a class with encapsulated locators and public methods. (2) Singleton — ConfigReader loads config.properties once: private static ConfigReader instance; public static ConfigReader getInstance() { if (instance == null) instance = new ConfigReader(); return instance; }. Avoids repeated file I/O. (3) Factory Pattern — BrowserFactory.createDriver("chrome") returns the appropriate WebDriver without tests knowing creation details. Adding a new browser means adding one case in the factory. (4) Strategy Pattern — WebDriver interface is a strategy. ChromeDriver, FirefoxDriver, EdgeDriver are interchangeable implementations. My tests work with any browser because they code to the WebDriver interface, not to a specific implementation. (5) Builder Pattern — for constructing complex test data objects when simple maps are not enough.
Q: What is the Singleton pattern? Show your ConfigReader implementation.
A: Singleton ensures only one instance of a class exists. My ConfigReader: private static ConfigReader instance; private Properties properties; private ConfigReader() { properties = new Properties(); properties.load(new FileInputStream("config.properties")); }. public static ConfigReader getInstance() { if (instance == null) { instance = new ConfigReader(); } return instance; }. public String getProperty(String key) { String sysProperty = System.getProperty(key); return sysProperty != null ? sysProperty : properties.getProperty(key); }. Used everywhere: ConfigReader.getInstance().getBaseUrl(). Why Singleton: (1) Load the file once, not in every test. (2) Single source of truth for configuration. (3) System property override lets CI change values without touching the file. Thread-safety note: in parallel execution, I use synchronized or initialize the instance in a static block to prevent race conditions.
Q: What is the Factory pattern? Show your BrowserFactory.
A: Factory creates objects without exposing creation logic. My BrowserFactory: public static WebDriver createDriver(String browser) { switch (browser.toLowerCase()) { case "chrome": ChromeOptions opts = new ChromeOptions(); if (isHeadless()) opts.addArguments("--headless=new"); return new ChromeDriver(opts); case "firefox": FirefoxOptions ffOpts = new FirefoxOptions(); if (isHeadless()) ffOpts.addArguments("--headless"); return new FirefoxDriver(ffOpts); case "edge": return new EdgeDriver(new EdgeOptions()); default: throw new IllegalArgumentException("Unsupported: " + browser); } }. BaseTest calls: driver = BrowserFactory.createDriver(ConfigReader.getInstance().getBrowser()). Benefits: (1) Tests never create WebDriver directly — all creation logic is centralized. (2) Adding a new browser means adding one case — zero test changes. (3) Common configuration (headless, window size, SSL bypass) is applied consistently. (4) Easy to extend for RemoteWebDriver by adding a "remote" case that creates RemoteWebDriver with the Grid hub URL.
Q: What is the role of BaseTest and BasePage in your framework?
A: BaseTest — parent of all test classes. Contains: @BeforeMethod that launches browser via BrowserFactory, navigates to base URL, and maximizes window. @AfterMethod that captures screenshot on failure and calls driver.quit(). ThreadLocal<WebDriver> for parallel execution safety. Helper methods: getDriver(), takeScreenshot(String name). All test classes extend BaseTest and inherit this lifecycle without writing a single line of setup/teardown code. BasePage — parent of all page objects. Contains: constructor accepting WebDriver, initializing WebDriverWait. Protected methods: waitForVisible(By), waitForClickable(By), type(By, String), getText(By), isDisplayed(By), scrollToElement(WebElement). Abstract method: isPageLoaded(). Every page object inherits these, so interaction logic is consistent and centralized. Change the wait strategy once in BasePage, and every page object benefits.
Q: How do you handle logging in your framework?
A: I use Log4j2 with a log4j2.xml configuration. Log levels: ERROR for failures and exceptions, WARN for unexpected but non-fatal issues, INFO for test steps (most used), DEBUG for detailed state during troubleshooting. In BasePage, every action logs at INFO: public void click(By locator) { logger.info("Clicking: " + locator); wait.until(EC.elementToBeClickable(locator)).click(); }. In listeners: test start, pass, fail, and skip are logged. Logs go to both console and file (logs/test-execution.log) with timestamps and thread names. Thread names are critical for debugging parallel execution — I can filter logs by thread to trace a specific test. For CI, logs are archived as Jenkins build artifacts so I can investigate failures even after the workspace is cleaned.
Q: How do you generate and share test reports?
A: Primary: Allure Reports. Integration: add allure-testng dependency and allure-maven plugin. Implement ITestListener to capture results. Use @Step on page object methods for step-level detail. Attach screenshots on failure with @Attachment. Add @Description and @Severity to test methods. Generate: mvn allure:serve opens the report in a browser. The report shows: dashboard with pass/fail/skip, step-by-step breakdown per test, attached screenshots, execution timeline, and history trends across builds. In Jenkins: Allure Jenkins Plugin generates and publishes the report automatically. I include the report link in Slack notifications. For quick sharing: TestNG also generates test-output/index.html — a simpler report for quick glances. Artifacts: screenshots and logs are archived as Jenkins build artifacts.
Q: How do you handle cross-browser testing?
A: Three layers: (1) BrowserFactory — creates the right WebDriver based on the browser parameter. (2) config.properties — sets the default browser for local development. (3) testng.xml — for cross-browser parallel execution with multiple <test> tags, each with a different browser parameter: <test name="Chrome"><parameter name="browser" value="chrome"/><classes>...</classes></test> <test name="Firefox"><parameter name="browser" value="firefox"/><classes>...</classes></test>. With parallel="tests", Chrome and Firefox run simultaneously. My BaseTest reads the parameter: @Parameters({"browser"}) @BeforeMethod public void setup(@Optional("chrome") String browser) { driver = BrowserFactory.createDriver(browser); }. For larger scale, I use Selenium Grid or Docker containers with selenium/standalone-chrome and selenium/standalone-firefox images.
Q: What is the project folder structure of your framework?
A: Maven standard: src/main/java/ has com.project.pages (page objects), com.project.base (BasePage), com.project.utils (ConfigReader, ExcelReader, ScreenshotUtil), com.project.factory (BrowserFactory). src/test/java/ has com.project.tests (test classes), com.project.base (BaseTest), com.project.listeners (TestListener, RetryAnalyzer, AnnotationTransformer). src/test/resources/ has config.properties, config-qa.properties, testdata/ folder with Excel/JSON, log4j2.xml. Root: pom.xml, testng-smoke.xml, testng-regression.xml, testng-crossbrowser.xml, .gitignore (ignoring logs/, screenshots/, test-output/, target/). This structure separates framework code (main) from test code (test), follows Maven conventions, and is immediately familiar to any Java developer joining the team.
Q: How would you design an automation framework from scratch?
A: Step-by-step: (1) Assess the application — SPA vs multi-page, tech stack, browser requirements. (2) Choose tools — Java + Selenium + TestNG + Maven for most projects. (3) Create Maven project with standard structure. (4) Build the foundation first — BasePage with wait wrappers, BaseTest with browser lifecycle, ConfigReader for properties, BrowserFactory for driver creation. (5) Create page objects for the first module. Write one end-to-end test to prove the architecture works. (6) Add utilities — ExcelReader, ScreenshotUtil, custom waits. (7) Add TestNG listeners — ITestListener for reporting, IRetryAnalyzer for flaky test handling. (8) Set up Allure reporting. (9) Configure testng.xml with groups. (10) Set up CI — Jenkinsfile or GitHub Actions workflow. (11) Add Log4j2. (12) Onboard the team — code review the first PR from each team member. Start simple. Add complexity only when needed. Over-engineering on day one kills more frameworks than technical debt.
Key Point: The framework walkthrough question separates juniors from seniors. Practice explaining your architecture in 5 minutes — layers, patterns, tools, and WHY you chose each one.