Think of project structure like a well-organized kitchen. Spices in one shelf, utensils in another, raw ingredients in the fridge. If everything is dumped in one drawer, cooking becomes a nightmare. Same with test automation. Every package has a specific purpose.
selenium-practice/
├── pom.xml # Maven config: dependencies + plugins
├── testng.xml # Master test suite definition
├── testng-smoke.xml # Smoke suite (quick health check)
├── testng-regression.xml # Full regression suite
├── src/
│ └── test/
│ ├── java/
│ │ └── com/testerrank/
│ │ ├── base/
│ │ │ ├── BaseTest.java # WebDriver setup/teardown
│ │ │ └── BasePage.java # Common page actions
│ │ ├── pages/
│ │ │ ├── banking/
│ │ │ │ ├── LoginPage.java
│ │ │ │ ├── DashboardPage.java
│ │ │ │ └── TransferPage.java
│ │ │ ├── shopping/
│ │ │ │ ├── ShopHomePage.java
│ │ │ │ ├── CatalogPage.java
│ │ │ │ ├── CartPage.java
│ │ │ │ └── CheckoutPage.java
│ │ │ ├── insurance/
│ │ │ │ ├── InsuranceHomePage.java
│ │ │ │ └── QuotePage.java
│ │ │ └── components/
│ │ │ ├── HeaderComponent.java
│ │ │ └── SidebarComponent.java
│ │ ├── tests/
│ │ │ ├── banking/
│ │ │ │ ├── LoginTests.java
│ │ │ │ ├── DashboardTests.java
│ │ │ │ └── TransferTests.java
│ │ │ ├── shopping/
│ │ │ │ ├── CatalogTests.java
│ │ │ │ ├── CartTests.java
│ │ │ │ └── CheckoutTests.java
│ │ │ └── insurance/
│ │ │ └── QuoteTests.java
│ │ ├── utils/
│ │ │ ├── ConfigReader.java # Properties loader
│ │ │ ├── ExcelUtils.java # Apache POI reader
│ │ │ ├── CsvUtils.java # CSV reader
│ │ │ ├── JsonUtils.java # JSON reader
│ │ │ ├── ScreenshotUtils.java # Screenshot capture
│ │ │ └── DataProviders.java # Centralized DataProviders
│ │ ├── listeners/
│ │ │ ├── TestListener.java # ITestListener
│ │ │ └── RetryAnalyzer.java # IRetryAnalyzer
│ │ └── config/
│ │ └── DriverFactory.java # Browser creation factory
│ └── resources/
│ ├── config.properties # Base config
│ ├── config-staging.properties # Staging overrides
│ ├── config-prod.properties # Prod overrides
│ ├── log4j2.xml # Logging config
│ └── test-data/
│ ├── login-data.csv
│ ├── search-terms.csv
│ ├── transfer-data.xlsx
│ └── insurance-quotes.json
├── logs/ # Generated logs (gitignored)
├── screenshots/ # Failure screenshots (gitignored)
├── test-output/ # TestNG reports (gitignored)
└── target/ # Maven build output (gitignored)Q: How is your automation framework structured? Walk me through the packages.
A: Our framework follows Maven standard layout under src/test/java. We have five main packages: base (BaseTest for driver lifecycle, BasePage for common page actions), pages (page objects organized by module — banking, shopping, insurance — each with private locators and public methods), tests (test classes mirroring the pages structure, each extending BaseTest), utils (ConfigReader, ExcelUtils, CsvUtils, ScreenshotUtils, DataProviders), and listeners (TestListener for screenshot-on-failure and RetryAnalyzer for flaky tests). Under src/test/resources, we have config.properties for environment settings and a test-data folder with CSV, Excel, and JSON files.
Mirror your pages/ package structure in your tests/ package. If you have pages/banking/LoginPage.java, you should have tests/banking/LoginTests.java. When someone looks at a test file, they instantly know which page it tests.
Never put page objects and test classes in the same package. Interviewers check for this. Mixing them means you do not understand separation of concerns — and that is a red flag for any senior QA role.
These folders are generated during test execution. Never commit them to Git.
# .gitignore for test automation project
target/
logs/
screenshots/
test-output/
*.class
*.log
.idea/
*.iml
.DS_Store
# Never commit real credentials
config-local.propertiesKey Point: Every folder in a professional framework has exactly one purpose. If you cannot explain why a package exists in one sentence, rethink your structure.