Skip to content

Instantly share code, notes, and snippets.

@minhphong306
Last active September 15, 2025 03:29
Show Gist options
  • Save minhphong306/a950eb6895bae046b3d5d923266a74fb to your computer and use it in GitHub Desktop.
Save minhphong306/a950eb6895bae046b3d5d923266a74fb to your computer and use it in GitHub Desktop.

Câu Hỏi Phỏng Vấn Selenium Java - Từ Cơ Bản Đến Nâng Cao

PHẦN 1: CÂU HỎI CƠ BẢN

1. Selenium WebDriver là gì?

Trả lời: Selenium WebDriver là một công cụ automation testing mã nguồn mở, cho phép tương tác trực tiếp với trình duyệt web thông qua các API native của browser. WebDriver hỗ trợ nhiều ngôn ngữ lập trình như Java, Python, C#, Ruby và JavaScript.

Ví dụ code Java:

// Khởi tạo WebDriver
WebDriver driver = new ChromeDriver();

// Mở một trang web
driver.get("https://www.example.com");

// Đóng trình duyệt
driver.quit();

2. Sự khác nhau giữa driver.get() và driver.navigate().to()?

Trả lời:

  • driver.get(): Đợi trang load hoàn toàn trước khi thực hiện lệnh tiếp theo
  • driver.navigate().to(): Không đợi trang load hoàn toàn và cho phép sử dụng các phương thức navigate khác

Ví dụ:

// Sử dụng get()
driver.get("https://google.com");

// Sử dụng navigate().to()
driver.navigate().to("https://google.com");
driver.navigate().back();    // Quay lại trang trước
driver.navigate().forward(); // Đi tới trang tiếp theo
driver.navigate().refresh(); // Refresh trang

3. Các loại locator trong Selenium là gì?

Trả lời: Selenium hỗ trợ 8 loại locator chính:

// 1. By ID
WebElement element = driver.findElement(By.id("email"));

// 2. By Name
WebElement element = driver.findElement(By.name("username"));

// 3. By ClassName
WebElement element = driver.findElement(By.className("btn-primary"));

// 4. By TagName
WebElement element = driver.findElement(By.tagName("button"));

// 5. By LinkText
WebElement element = driver.findElement(By.linkText("Click Here"));

// 6. By PartialLinkText
WebElement element = driver.findElement(By.partialLinkText("Click"));

// 7. By CSS Selector
WebElement element = driver.findElement(By.cssSelector("#email.form-control"));

// 8. By XPath
WebElement element = driver.findElement(By.xpath("//input[@id='email']"));

4. Sự khác nhau giữa findElement() và findElements()?

Trả lời:

findElement() findElements()
Trả về một WebElement Trả về List
Throw NoSuchElementException nếu không tìm thấy Trả về empty list nếu không tìm thấy
Tìm element đầu tiên match Tìm tất cả elements match

Ví dụ:

// findElement - tìm một element
WebElement button = driver.findElement(By.className("btn"));
button.click();

// findElements - tìm nhiều elements
List<WebElement> buttons = driver.findElements(By.className("btn"));
System.out.println("Số lượng button: " + buttons.size());

for(WebElement btn : buttons) {
    System.out.println(btn.getText());
}

PHẦN 2: CÂU HỎI TRUNG CẤP

5. Explicit Wait, Implicit Wait và Fluent Wait khác nhau như thế nào?

Trả lời:

Implicit Wait:

// Đặt thời gian chờ ngầm định cho toàn bộ session
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

Explicit Wait:

// Chờ cho một điều kiện cụ thể
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.id("submit"))
);

Fluent Wait:

// Chờ với polling interval và ignore exceptions
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(Duration.ofSeconds(30))
    .pollingEvery(Duration.ofSeconds(2))
    .ignoring(NoSuchElementException.class);

WebElement element = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("dynamic-element"));
    }
});

6. Làm thế nào để handle Alert/Popup trong Selenium?

Trả lời:

// Chuyển sang alert
Alert alert = driver.switchTo().alert();

// Lấy text từ alert
String alertText = alert.getText();
System.out.println("Alert message: " + alertText);

// Accept alert (click OK)
alert.accept();

// Dismiss alert (click Cancel)
alert.dismiss();

// Nhập text vào prompt alert
alert.sendKeys("Test input");
alert.accept();

7. Cách handle multiple windows/tabs?

Trả lời:

// Lưu window handle hiện tại
String mainWindow = driver.getWindowHandle();

// Lấy tất cả window handles
Set<String> allWindows = driver.getWindowHandles();

// Switch sang window mới
for(String window : allWindows) {
    if(!window.equals(mainWindow)) {
        driver.switchTo().window(window);
        break;
    }
}

// Thực hiện action trong window mới
driver.findElement(By.id("button")).click();

// Đóng window hiện tại
driver.close();

// Switch về window chính
driver.switchTo().window(mainWindow);

8. Làm thế nào để handle dropdown trong Selenium?

Trả lời:

// Tìm dropdown element
WebElement dropdownElement = driver.findElement(By.id("country"));

// Tạo Select object
Select dropdown = new Select(dropdownElement);

// Chọn theo visible text
dropdown.selectByVisibleText("Vietnam");

// Chọn theo value
dropdown.selectByValue("VN");

// Chọn theo index
dropdown.selectByIndex(2);

// Lấy option đang được chọn
WebElement selectedOption = dropdown.getFirstSelectedOption();
System.out.println("Selected: " + selectedOption.getText());

// Lấy tất cả options
List<WebElement> allOptions = dropdown.getOptions();
for(WebElement option : allOptions) {
    System.out.println(option.getText());
}

PHẦN 3: CÂU HỎI NÂNG CAO

9. Page Object Model (POM) là gì và cách implement?

Trả lời: POM là design pattern tách biệt logic test và page elements, giúp code dễ maintain và reusable.

Ví dụ Page Class:

public class LoginPage {
    private WebDriver driver;
    
    // Locators
    @FindBy(id = "username")
    private WebElement usernameField;
    
    @FindBy(id = "password")
    private WebElement passwordField;
    
    @FindBy(xpath = "//button[@type='submit']")
    private WebElement loginButton;
    
    // Constructor
    public LoginPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }
    
    // Page Methods
    public void enterUsername(String username) {
        usernameField.clear();
        usernameField.sendKeys(username);
    }
    
    public void enterPassword(String password) {
        passwordField.clear();
        passwordField.sendKeys(password);
    }
    
    public HomePage clickLogin() {
        loginButton.click();
        return new HomePage(driver);
    }
    
    // Business Logic Method
    public HomePage login(String username, String password) {
        enterUsername(username);
        enterPassword(password);
        return clickLogin();
    }
}

Test Class:

public class LoginTest {
    private WebDriver driver;
    private LoginPage loginPage;
    
    @BeforeMethod
    public void setup() {
        driver = new ChromeDriver();
        driver.get("https://example.com/login");
        loginPage = new LoginPage(driver);
    }
    
    @Test
    public void testValidLogin() {
        HomePage homePage = loginPage.login("[email protected]", "password123");
        Assert.assertTrue(homePage.isUserLoggedIn());
    }
    
    @AfterMethod
    public void teardown() {
        driver.quit();
    }
}

10. Cách handle AJAX calls trong Selenium?

Trả lời:

// Cách 1: Dùng Explicit Wait với custom condition
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

// Chờ jQuery AJAX hoàn thành
wait.until(new ExpectedCondition<Boolean>() {
    public Boolean apply(WebDriver driver) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        return (Boolean) js.executeScript("return jQuery.active == 0");
    }
});

// Cách 2: Chờ element xuất hiện sau AJAX
wait.until(ExpectedConditions.presenceOfElementLocated(
    By.id("ajax-loaded-content")
));

// Cách 3: Custom wait cho Angular
public void waitForAngular() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    String script = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";
    
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(driver -> js.executeScript(script).equals(true));
}

11. Làm thế nào để take screenshot trong Selenium?

Trả lời:

// Screenshot toàn màn hình
public void takeScreenshot(String fileName) {
    TakesScreenshot screenshot = (TakesScreenshot) driver;
    File srcFile = screenshot.getScreenshotAs(OutputType.FILE);
    
    try {
        FileUtils.copyFile(srcFile, 
            new File("./screenshots/" + fileName + ".png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// Screenshot một element cụ thể (Selenium 4+)
public void takeElementScreenshot(WebElement element, String fileName) {
    File srcFile = element.getScreenshotAs(OutputType.FILE);
    
    try {
        FileUtils.copyFile(srcFile, 
            new File("./screenshots/" + fileName + ".png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

12. Cách handle file upload/download?

Trả lời:

File Upload:

// Cách 1: Send keys trực tiếp
WebElement uploadElement = driver.findElement(By.id("file-upload"));
uploadElement.sendKeys("/path/to/file.pdf");

// Cách 2: Dùng Robot class cho native dialog
Robot robot = new Robot();
robot.setAutoDelay(2000);

// Copy file path to clipboard
StringSelection stringSelection = new StringSelection("/path/to/file.pdf");
Toolkit.getDefaultToolkit().getSystemClipboard()
    .setContents(stringSelection, null);

// Paste và Enter
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);

File Download:

// Configure Chrome để auto download
HashMap<String, Object> chromePrefs = new HashMap<>();
chromePrefs.put("download.default_directory", "/path/to/download");
chromePrefs.put("download.prompt_for_download", false);

ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs", chromePrefs);

WebDriver driver = new ChromeDriver(options);

PHẦN 4: CÂU HỎI VỀ FRAMEWORK & BEST PRACTICES

13. TestNG và JUnit khác nhau như thế nào?

Trả lời:

Feature TestNG JUnit
Annotations @BeforeSuite, @AfterSuite, @BeforeTest, @AfterTest Không có
Parallel Testing Hỗ trợ native Cần configuration thêm
Data Provider @DataProvider @ParameterizedTest (JUnit 5)
Dependency Testing @Test(dependsOnMethods) Không hỗ trợ
Grouping @Test(groups = "smoke") @Tag (JUnit 5)

Ví dụ TestNG:

public class TestNGExample {
    
    @DataProvider(name = "loginData")
    public Object[][] getData() {
        return new Object[][] {
            {"[email protected]", "pass1"},
            {"[email protected]", "pass2"}
        };
    }
    
    @Test(dataProvider = "loginData", groups = "smoke")
    public void testLogin(String email, String password) {
        // Test logic
    }
    
    @Test(dependsOnMethods = "testLogin", groups = "regression")
    public void testDashboard() {
        // Test logic
    }
}

14. Làm thế nào để implement Parallel Testing?

Trả lời:

TestNG XML Configuration:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel Test Suite" parallel="tests" thread-count="3">
    
    <!-- Parallel by methods -->
    <test name="Test1" parallel="methods" thread-count="5">
        <classes>
            <class name="com.test.LoginTest"/>
        </classes>
    </test>
    
    <!-- Parallel by classes -->
    <test name="Test2" parallel="classes" thread-count="3">
        <classes>
            <class name="com.test.HomeTest"/>
            <class name="com.test.ProfileTest"/>
        </classes>
    </test>
</suite>

Thread-Safe WebDriver với ThreadLocal:

public class DriverManager {
    private static ThreadLocal<WebDriver> driverThread = new ThreadLocal<>();
    
    public static void setDriver(String browserName) {
        if(browserName.equals("chrome")) {
            driverThread.set(new ChromeDriver());
        } else if(browserName.equals("firefox")) {
            driverThread.set(new FirefoxDriver());
        }
    }
    
    public static WebDriver getDriver() {
        return driverThread.get();
    }
    
    public static void quitDriver() {
        driverThread.get().quit();
        driverThread.remove();
    }
}

15. Best Practices khi viết Selenium tests?

Trả lời:

  1. Sử dụng Page Object Model
  2. Implement Explicit Waits thay vì Thread.sleep()
  3. Tạo reusable methods
  4. Sử dụng Data-Driven Testing
  5. Implement proper logging
  6. Handle exceptions gracefully
  7. Clean up resources trong @AfterMethod

Ví dụ Best Practice Implementation:

public class BaseTest {
    protected WebDriver driver;
    protected Logger logger = LogManager.getLogger(this.getClass());
    
    @BeforeMethod
    @Parameters({"browser", "url"})
    public void setup(String browser, String url) {
        logger.info("Starting test with browser: " + browser);
        driver = BrowserFactory.getDriver(browser);
        driver.manage().window().maximize();
        driver.get(url);
    }
    
    @AfterMethod
    public void teardown(ITestResult result) {
        if(result.getStatus() == ITestResult.FAILURE) {
            takeScreenshot(result.getName());
            logger.error("Test failed: " + result.getName());
        }
        driver.quit();
    }
    
    protected void takeScreenshot(String testName) {
        // Screenshot logic
    }
}

Tips Chuẩn Bị Phỏng Vấn

  1. Thực hành code: Viết code thực tế, không chỉ học lý thuyết
  2. Chuẩn bị project demo: Có một project automation framework hoàn chỉnh trên GitHub
  3. Hiểu rõ concepts: Không chỉ nhớ syntax mà phải hiểu bản chất
  4. Cập nhật kiến thức: Selenium 4 có nhiều features mới như Relative Locators, Chrome DevTools Protocol
  5. Kể về kinh nghiệm thực tế: Chuẩn bị các tình huống đã gặp và cách giải quyết
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment