How This Cheat Sheet Is Organised
| Layer | Topics | Where you meet it in a framework |
|---|---|---|
| 1 · Building Blocks | Primitives, wrappers, var, final | Timeouts, counters, flags, constants |
| 2 · Text Handling | String methods, StringBuilder | Assertions, parsing responses, dynamic XPaths |
| 3 · Decisions & Loops | if/else, ternary, switch, loops | Status-code checks, iterating elements |
| 4 · OOP in Frameworks | 4 pillars, access modifiers, interface vs abstract | Screen classes, AwuScreen, BrowserManager |
| 5 · Data & Failures | List/Set/Map, exceptions | Payloads, labels, window ids, recovery |
| 6 · Modern Java | Lambdas, functional interfaces, streams, Optional, I/O, enums | Status-code analysis, settings, JSON, stages |
Layer 1 — Building Blocks
1.1 Primitive types at a glance
| Type | Memory | Field default | Where an SDET writes it |
|---|---|---|---|
| byte | 1 byte | 0 | byte maxRetries = 3; |
| short | 2 bytes | 0 | short mockPort = 9090; |
| int | 4 bytes | 0 | int seatsLeft = 12; |
| long | 8 bytes | 0L | long uploadLimitBytes = 5_242_880L; |
| float | 4 bytes | 0.0f | float gstRate = 0.18f; |
| double | 8 bytes | 0.0d | double batchFee = 4999.00; |
| char | 2 bytes | '\u0000' | char rupee = '₹'; |
| boolean | JVM-dependent (1 bit of information) | false | boolean isHeadless = true; |
Defaults apply only to class fields. A local variable inside a method has no default — the compiler forces you to initialise it.
1.2 Reference types, var and final
String runMode = "headless"; // object, immutable
Integer waitSeconds = 15; // wrapper class (autoboxing from int)
var portalUrl = "https://qa.awu-portal.test"; // Java 10+: inferred as String
final int SEAT_LIMIT = 40; // can never be reassigned
static final String STAGE = "uat"; // class-level constantWrappers (Integer, Boolean…) exist because collections can only store objects — List<int> will not compile, List<Integer> will.
Layer 2 — Text Handling
2.1 String methods you will use daily
| Need | Call | Returns |
|---|---|---|
| Length of text | "Playwright".length() | 10 |
| One character | "Order#77".charAt(5) | '#' |
| Cut a piece | "OrderId:9812".substring(8) | "9812" |
| Contains? | heading.contains("Learner Home") | true/false |
| Prefix / suffix | url.startsWith("https") · file.endsWith(".pdf") | true/false |
| Exact compare | actual.equals(expected) | true/false |
| Ignore case | "ENROLLED".equalsIgnoreCase("enrolled") | true |
| Change case | "uat".toUpperCase() | "UAT" |
| Remove outer spaces | " ₹499 ".trim() · .strip() (Unicode-aware, Java 11+) | "₹499" |
| Replace | "₹1,499".replace(",", "") | "₹1499" |
| Split | "local|qa|uat".split("\\|") | ["local","qa","uat"] |
| Join | String.join(" › ", "Batches", "Playwright") | "Batches › Playwright" |
| Empty / blank | "".isEmpty() · " ".isBlank() | true · true |
| Template | String.format("//h3[text()='%s']", batch) | Dynamic XPath |
| Regex check | "AWU-2026-07".matches("AWU-\\d{4}-\\d{2}") | true |
Never compare Strings with ==. == checks whether two variables point to the same object; equals() checks the content. Tests that use == pass sometimes and fail randomly.
2.2 Real example — cleaning a fee before asserting
String shownFee = driver.findElement(By.id("payable-fee")).getText(); // " ₹4,999.00 "
double fee = Double.parseDouble(shownFee.trim().replace("₹", "").replace(",", ""));
Assert.assertEquals(fee, 4999.00, 0.001);2.3 String vs StringBuilder
String is immutable — every + inside a loop creates a new object. StringBuilder is mutable and fast for building large text such as CSV rows or log lines. (StringBuffer is the older, synchronised version.)
Layer 3 — Decisions & Loops
// if / else-if / else
if (code == 201) { log("Enrolment created"); }
else if (code == 409) { log("Learner already enrolled"); }
else { log("Unexpected: " + code); }
// Ternary
String badge = (attendance >= 75) ? "ELIGIBLE" : "NOT ELIGIBLE";
// Switch expression (Java 14+)
String bucket = switch (code / 100) {
case 2 -> "Success";
case 3 -> "Redirect";
case 4 -> "Client side";
case 5 -> "Server side";
default -> "Unknown";
};
// Loops
for (int row = 1; row <= table.rowCount(); row++) { /* row number needed */ }
for (WebElement tile : batchTiles) { System.out.println(tile.getText()); }
do { refreshStatus(); } while (!isPublished() && ++tries < 4); // demo only — prefer explicit waitsLayer 4 — OOP the Framework Way
4.1 The four pillars mapped to real code
| Pillar | One-line meaning | Where it lives in your framework |
|---|---|---|
| Encapsulation | Hide data, expose behaviour | Locators stay private inside a screen class; tests only call enterPortal() |
| Inheritance | Reuse code from a parent | SignInScreen extends AwuScreen inherits the driver and shared waits |
| Polymorphism | One reference, many behaviours | WebDriver driver = new EdgeDriver(); — swap the object, keep every call |
| Abstraction | Say what, not how | Abstract isOpened() that every screen answers in its own way |
public abstract class AwuScreen {
protected final WebDriver driver;
protected final WebDriverWait wait;
protected AwuScreen(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
public String currentHeading() { return driver.findElement(By.tagName("h1")).getText(); }
public abstract boolean isOpened(); // abstraction
}
public class SignInScreen extends AwuScreen { // inheritance
private final By learnerEmail = By.id("learner-email"); // encapsulation
private final By secretKey = By.id("account-password");
private final By enterBtn = By.cssSelector("[data-qa='enter-portal']");
public SignInScreen(WebDriver driver) { super(driver); }
@Override
public boolean isOpened() {
return wait.until(ExpectedConditions.visibilityOfElementLocated(enterBtn)).isDisplayed();
}
public LearnerHomeScreen enterPortal(String email, String secret) {
driver.findElement(learnerEmail).sendKeys(email);
driver.findElement(secretKey).sendKeys(secret);
driver.findElement(enterBtn).click();
return new LearnerHomeScreen(driver);
}
}4.2 Access modifiers — who can see what
| Modifier | Same class | Same package | Subclass (other pkg) | Everywhere |
|---|---|---|---|---|
| private | Yes | No | No | No |
| (default) | Yes | Yes | No | No |
| protected | Yes | Yes | Yes | No |
| public | Yes | Yes | Yes | Yes |
4.3 Interface vs abstract class, and the small keywords
| Interface | Abstract class | |
|---|---|---|
| Purpose | A contract — what must be done | Partial implementation + shared state |
| Methods | Abstract, plus default and static (Java 8+) | Abstract and concrete |
| Fields | Only public static final constants | Any fields, with state |
| Inheritance | A class can implement many | A class can extend only one |
| Framework example | WebDriver, TakesScreenshot | AwuScreen, AwuBaseTest |
this→ the current object (e.g.this.wait = …).super→ the parent class (call its constructor or overridden method).static→ belongs to the class, shared by all objects (utility methods, constants).final→ constant variable, non-overridable method, non-extendable class.
Layer 5 — Data Structures & Failures
5.1 List, Set, Map in action
// LIST — keeps order, allows repeats
List<String> modules = new ArrayList<>();
modules.add("Locators"); modules.add("Fixtures"); modules.add("Locators");
modules.get(1); // "Fixtures"
modules.size(); // 3
modules.indexOf("Fixtures"); // 1
List<String> stages = List.of("local", "qa", "uat"); // read-only (Java 9+)
// SET — drops repeats
Set<String> windowIds = driver.getWindowHandles(); // every open tab, once
Set<String> labels = new LinkedHashSet<>(List.of("@ui", "@api", "@ui")); // [@ui, @api]
// MAP — key → value
Map<String, Object> enrolPayload = new LinkedHashMap<>();
enrolPayload.put("batch", "PW-TS-Nov");
enrolPayload.put("seats", 1);
enrolPayload.putIfAbsent("mode", "online");
enrolPayload.forEach((k, v) -> System.out.println(k + " → " + v));| Collection | Order kept | Repeats allowed | Thread-safe | Reach for it when… |
|---|---|---|---|---|
| ArrayList | Insertion (index) | Yes | No | Everyday list, fast read by position |
| LinkedList | Insertion (index) | Yes | No | Adding/removing at the ends a lot |
| HashMap | No | Keys no / values yes | No | Plain key-value lookups |
| LinkedHashMap | Insertion | Keys no / values yes | No | JSON payloads, report columns in order |
| ConcurrentHashMap | No | Keys no / values yes | Yes | Shared results across parallel threads |
| HashSet | No | No | No | Only uniqueness matters |
| LinkedHashSet | Insertion | No | No | Unique labels in a fixed order |
| TreeSet | Sorted | No | No | Unique values that must stay sorted |
5.2 Exceptions — failing gracefully
try {
driver.findElement(By.id("festive-offer-dismiss")).click();
} catch (NoSuchElementException e) {
log("Offer banner absent today — moving on"); // narrowest catch first
} catch (WebDriverException e) {
throw new CourseNotFoundException("Python Basics", e); // wrap with context
} finally {
attachLogs("offer-step"); // runs pass or fail
}
// Your own exception = clearer failure messages
public class CourseNotFoundException extends RuntimeException {
public CourseNotFoundException(String course, Throwable cause) {
super("Course card not found: " + course, cause);
}
}| Checked | Unchecked | |
|---|---|---|
| Detected | Compile time — must handle or declare | Runtime |
| Parent | Exception (not Runtime) | RuntimeException |
| Examples | IOException, FileNotFoundException | NullPointerException, NoSuchElementException, TimeoutException |
Layer 6 — Modern Java (8 → 17)
6.1 Lambdas — behaviour in one line
record Course(String name, int fee) {}
// Before Java 8 — a whole anonymous class just to sort by fee
Comparator<Course> byFee = new Comparator<Course>() {
@Override public int compare(Course a, Course b) { return Integer.compare(a.fee(), b.fee()); }
};
// Same logic as a lambda
Comparator<Course> byFeeLambda = (a, b) -> Integer.compare(a.fee(), b.fee());
// Shortest: helper + method reference
courses.sort(Comparator.comparingInt(Course::fee).reversed());
// Lambda shapes
Runnable ping = () -> log("suite ready"); // no input
Function<Integer, Integer> withGst = fee -> fee * 118 / 100; // one input
BinaryOperator<Integer> add = (x, y) -> x + y; // two inputs6.2 Functional interfaces
| Built-in type | Its one method | In → Out | Where an SDET uses it |
|---|---|---|---|
| Supplier<T> | get() | nothing → T | Generate a unique email for each test |
| Predicate<T> | test() | T → boolean | Is this status code in the 2xx range? |
| Function<T,R> | apply() | T → R | Turn a JSON string into a POJO |
| Consumer<T> | accept() | T → nothing | Log every response header |
| UnaryOperator<T> | apply() | T → T | Mask a token before printing it |
| BiFunction<T,U,R> | apply() | T, U → R | Merge default headers with test headers |
6.3 Streams — chaining data like a pipeline
List<Integer> codes = List.of(200, 201, 404, 500, 200, 302, 401);
codes.stream().filter(c -> c >= 400).toList(); // [404, 500, 401]
codes.stream().map(c -> "HTTP " + c).toList(); // [HTTP 200, HTTP 201, ...]
codes.stream().distinct().count(); // 6
codes.stream().sorted(Comparator.reverseOrder()).toList(); // highest first
codes.stream().allMatch(c -> c < 600); // true
codes.stream().mapToInt(Integer::intValue).max().getAsInt(); // 500
Map<Boolean, List<Integer>> okVsFailed =
codes.stream().collect(Collectors.partitioningBy(c -> c < 400));
// Real use: are the batch fees on the page sorted low → high?
List<Integer> fees = driver.findElements(By.cssSelector("[data-qa='batch-fee']")).stream()
.map(WebElement::getText)
.map(t -> Integer.parseInt(t.replaceAll("[^0-9]", "")))
.toList();
Assert.assertEquals(fees, fees.stream().sorted().toList());.toList() is Java 16+. On Java 8–15 use .collect(Collectors.toList()).
6.4 Optional — no more NullPointerException surprises
Optional<String> banner = Optional.ofNullable(learnerHome.findOfferBanner());
banner.isPresent(); // value there?
banner.orElse("No offer running"); // fallback
banner.map(String::strip).orElse(""); // transform safely
banner.ifPresent(text -> log("Offer: " + text));6.5 Files, properties and JSON
// awu-settings.properties → runMode=headless, stage=qa
Properties settings = new Properties();
try (Reader r = Files.newBufferedReader(Path.of("src/test/resources/awu-settings.properties"))) {
settings.load(r);
}
String runMode = settings.getProperty("runMode", "headed");
// java.nio.file helpers (Java 11+)
Path batchFile = Path.of("fixtures/batches.csv");
if (Files.exists(batchFile)) {
try (Stream<String> lines = Files.lines(batchFile)) {
long rows = lines.skip(1).count(); // ignore header row
}
}
Files.writeString(Path.of("run-output/summary.log"), "Suite finished",
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
// Read one field from JSON without a POJO (Jackson tree model)
JsonNode root = new ObjectMapper().readTree(Files.readString(Path.of("fixtures/enrolment.json")));
String batchCode = root.path("batch").path("code").asText();6.6 Enums for stages (local / QA / UAT)
public enum Stage {
LOCAL("http://localhost:3000", "http://localhost:8080/api"),
QA("https://qa.awu-portal.test", "https://qa-api.awu-portal.test"),
UAT("https://uat.awu-portal.test", "https://uat-api.awu-portal.test");
private final String web, api;
Stage(String web, String api) { this.web = web; this.api = api; }
public String web() { return web; }
public String api() { return api; }
}
Stage stage = Stage.valueOf(System.getProperty("stage", "QA").toUpperCase());
driver.get(stage.web());Inside a Real AWU Framework
BrowserManager — one browser per thread
public final class BrowserManager {
private static final ThreadLocal<WebDriver> SESSION = new ThreadLocal<>();
private BrowserManager() {}
public static void open(String name) {
WebDriver d = switch (name) {
case "edge" -> new EdgeDriver();
case "firefox" -> new FirefoxDriver();
default -> new ChromeDriver();
};
SESSION.set(d);
}
public static WebDriver current() { return SESSION.get(); }
public static void close() {
if (SESSION.get() != null) { SESSION.get().quit(); SESSION.remove(); }
}
}Test data: builder + DataProvider
Enrolment e = Enrolment.builder().learner("Priya").batch("PW-TS-Nov").seats(1).build();
@DataProvider(name = "couponCases")
public Object[][] couponCases() {
return new Object[][] {
{ "FESTIVE20", 5000, 4000 }, // coupon, fee, expected payable
{ "EXPIRED10", 5000, 5000 },
{ "", 5000, 5000 },
};
}
@Test(dataProvider = "couponCases")
public void couponIsApplied(String code, int fee, int payable) { /* ... */ }Interview Questions & Answers
Q1. Why does List<int> fail to compile?
Generics work only with objects; use the wrapper Integer — autoboxing converts for you.
Q2. Two strings print the same, yet an == check fails. Why?
== compared two different object references; equals() compares the content.
Q3. Where would you use StringBuilder in a framework?
Building long text in loops — CSV rows, report lines, request bodies — because String creates a new object on every change.
Q4. Which collection keeps unique keys in insertion order?
LinkedHashMap — handy for JSON payloads and report columns.
Q5. What happens if finally contains a return?
It overrides the try/catch result and can swallow exceptions — avoid it.
Q6. How does Selenium itself use polymorphism?
WebDriver is an interface; Chrome, Edge and Firefox drivers implement it, so the same calls work on any browser.
Q7. Why is a static WebDriver risky in parallel runs?
Every thread shares one browser and they close each other's sessions; ThreadLocal gives each thread its own.
Q8. Overloading vs overriding — a framework example?
Overloading: click(By) and click(WebElement) in one helper. Overriding: each screen's own isOpened().
Q9. Checked or unchecked for a custom "element missing" exception?
Unchecked (extends RuntimeException) so tests don't need throws everywhere, with a clear message.
Q10. Which interface fits "give me a fresh test email each time"?
Supplier<String> — no input, returns a value.
Want to learn this live?
Small batches, real projects, mock interviews included. Sit in on a free demo class first.
See all coursesBook a mock interview