☕ Core Java · Free cheat sheet

Java Toolkit for Automation Engineers

The AWU six-layer method — only the Java you will actually type inside a framework

UI Automation · Selenium + Java · Java Toolkit for Frameworks · Beginner → Framework-ready

How This Cheat Sheet Is Organised

LayerTopicsWhere you meet it in a framework
1 · Building BlocksPrimitives, wrappers, var, finalTimeouts, counters, flags, constants
2 · Text HandlingString methods, StringBuilderAssertions, parsing responses, dynamic XPaths
3 · Decisions & Loopsif/else, ternary, switch, loopsStatus-code checks, iterating elements
4 · OOP in Frameworks4 pillars, access modifiers, interface vs abstractScreen classes, AwuScreen, BrowserManager
5 · Data & FailuresList/Set/Map, exceptionsPayloads, labels, window ids, recovery
6 · Modern JavaLambdas, functional interfaces, streams, Optional, I/O, enumsStatus-code analysis, settings, JSON, stages

Layer 1 — Building Blocks

1.1 Primitive types at a glance

TypeMemoryField defaultWhere an SDET writes it
byte1 byte0byte maxRetries = 3;
short2 bytes0short mockPort = 9090;
int4 bytes0int seatsLeft = 12;
long8 bytes0Llong uploadLimitBytes = 5_242_880L;
float4 bytes0.0ffloat gstRate = 0.18f;
double8 bytes0.0ddouble batchFee = 4999.00;
char2 bytes'\u0000'char rupee = '₹';
booleanJVM-dependent (1 bit of information)falseboolean isHeadless = true;
Watch Out

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

BuildingBlocks.java
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 constant
Key Takeaway

Wrappers (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

NeedCallReturns
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 / suffixurl.startsWith("https") · file.endsWith(".pdf")true/false
Exact compareactual.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"]
JoinString.join(" › ", "Batches", "Playwright")"Batches › Playwright"
Empty / blank"".isEmpty() · " ".isBlank()true · true
TemplateString.format("//h3[text()='%s']", batch)Dynamic XPath
Regex check"AWU-2026-07".matches("AWU-\\d{4}-\\d{2}")true
Interview Trap

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

ControlFlow.java
// 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 waits

Layer 4 — OOP the Framework Way

4.1 The four pillars mapped to real code

PillarOne-line meaningWhere it lives in your framework
EncapsulationHide data, expose behaviourLocators stay private inside a screen class; tests only call enterPortal()
InheritanceReuse code from a parentSignInScreen extends AwuScreen inherits the driver and shared waits
PolymorphismOne reference, many behavioursWebDriver driver = new EdgeDriver(); — swap the object, keep every call
AbstractionSay what, not howAbstract isOpened() that every screen answers in its own way
screens/SignInScreen.java
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

ModifierSame classSame packageSubclass (other pkg)Everywhere
privateYesNoNoNo
(default)YesYesNoNo
protectedYesYesYesNo
publicYesYesYesYes

4.3 Interface vs abstract class, and the small keywords

InterfaceAbstract class
PurposeA contract — what must be donePartial implementation + shared state
MethodsAbstract, plus default and static (Java 8+)Abstract and concrete
FieldsOnly public static final constantsAny fields, with state
InheritanceA class can implement manyA class can extend only one
Framework exampleWebDriver, TakesScreenshotAwuScreen, AwuBaseTest

Layer 5 — Data Structures & Failures

5.1 List, Set, Map in action

DataStructures.java
// 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));
CollectionOrder keptRepeats allowedThread-safeReach for it when…
ArrayListInsertion (index)YesNoEveryday list, fast read by position
LinkedListInsertion (index)YesNoAdding/removing at the ends a lot
HashMapNoKeys no / values yesNoPlain key-value lookups
LinkedHashMapInsertionKeys no / values yesNoJSON payloads, report columns in order
ConcurrentHashMapNoKeys no / values yesYesShared results across parallel threads
HashSetNoNoNoOnly uniqueness matters
LinkedHashSetInsertionNoNoUnique labels in a fixed order
TreeSetSortedNoNoUnique values that must stay sorted

5.2 Exceptions — failing gracefully

exceptions
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);
    }
}
CheckedUnchecked
DetectedCompile time — must handle or declareRuntime
ParentException (not Runtime)RuntimeException
ExamplesIOException, FileNotFoundExceptionNullPointerException, NoSuchElementException, TimeoutException

Layer 6 — Modern Java (8 → 17)

6.1 Lambdas — behaviour in one line

Lambdas.java
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 inputs

6.2 Functional interfaces

Built-in typeIts one methodIn → OutWhere an SDET uses it
Supplier<T>get()nothing → TGenerate a unique email for each test
Predicate<T>test()T → booleanIs this status code in the 2xx range?
Function<T,R>apply()T → RTurn a JSON string into a POJO
Consumer<T>accept()T → nothingLog every response header
UnaryOperator<T>apply()T → TMask a token before printing it
BiFunction<T,U,R>apply()T, U → RMerge default headers with test headers

6.3 Streams — chaining data like a pipeline

Streams.java
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());
Version Note

.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

settings & data
// 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)

Stage.java
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

core/BrowserManager.java
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