QAmigrate
Migration Report
Java (Selenium) Java (Playwright) · Started 2026-04-29T06:26:52.431730+00:00 · Finished 2026-04-29T06:32:10.847662+00:00
Migrated
9
of 17 files
Failed
8
generation errors
Patterns
56
Selenium patterns handled
Avg confidence
75%
across all files
Total time
217.7s
wall-clock
Hours saved
~3.0
est. manual effort
⚠ Priority
8
Failed or confidence < 70%
~ Verify
0
Hallucinations or 3+ fix attempts
✓ Solid
9
Confidence ≥ 90%, compiled clean
Selenium patterns handled
PatternCount
ExpectedConditions10
By_id6
WebDriver6
assertTrue5
By_field4
click3
sendKeys2
clear2
By_cssSelector2
WebDriverWait2
JavascriptExecutor2
Cucumber_Scenario_Inject2
Cucumber_When2
Cucumber_Then2
ChromeDriver1
FirefoxDriver1
Actions1
Select1
hover1
Cucumber_Given1
Files
✗ Failed
BaseTest.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\core\BaseTest.java
65 → 69 lines
50%
13.7s ✗ Did not compile 2 fix attempt(s)
ℹ Generation failed. Error: 2 compile error(s) after 2 fix attempt(s)
Compiler / generation error
2 compile error(s) after 2 fix attempt(s)
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.core;n1package com.qastarter.core.playwright;
22
n3import com.qastarter.config.ConfigurationReader;n3import com.qastarter.config.playwright.ConfigurationReader;
4import com.qastarter.utils.Log;4import com.qastarter.utils.playwright.Log;
5import org.openqa.selenium.WebDriver;5import com.qastarter.core.playwright.DriverManager;
6import com.microsoft.playwright.Page;
6import org.junit.jupiter.api.AfterAll;7import org.junit.jupiter.api.AfterAll;
7import org.junit.jupiter.api.AfterEach;8import org.junit.jupiter.api.AfterEach;
8import org.junit.jupiter.api.BeforeAll;9import org.junit.jupiter.api.BeforeAll;
9import org.junit.jupiter.api.BeforeEach;10import org.junit.jupiter.api.BeforeEach;
10import org.junit.jupiter.api.extension.ExtendWith;11import org.junit.jupiter.api.extension.ExtendWith;
1112
n12/**n
13 * Base Test - Extend this in all your test classes.
14 * 
15 * JUnit5 version with @BeforeEach/@AfterEach lifecycle.
16 */
17@ExtendWith(TestWatcher.class)13@ExtendWith(TestWatcher.class)
18public class BaseTest {14public class BaseTest {
1915
nn16    // No explicit constructor needed - using default constructor
17 
18    // Migration: Preserved original logging and configuration reading - no chan
 >ges needed for suite-level setup
20    @BeforeAll19    @BeforeAll
21    static void beforeAll() {20    static void beforeAll() {
22        Log.info("========================================");21        Log.info("========================================");
27        Log.info("Base URL: " + ConfigurationReader.getBaseUrl());26        Log.info("Base URL: " + ConfigurationReader.getBaseUrl());
28    }27    }
2928
nn29    // Migration: Preserved original logging - no changes needed for suite-level
 > teardown
30    @AfterAll30    @AfterAll
31    static void afterAll() {31    static void afterAll() {
32        Log.info("========================================");32        Log.info("========================================");
34        Log.info("========================================");34        Log.info("========================================");
35    }35    }
3636
nn37    // Migration: Migrated WebDriver.get() to Page.navigate() - Playwright Page 
 >handles navigation
37    @BeforeEach38    @BeforeEach
38    void setUp() {39    void setUp() {
39        Log.info("--- Test Setup Started ---");40        Log.info("--- Test Setup Started ---");
40        DriverManager.initializeDriver();41        DriverManager.initializeDriver();
n41 n
42        String baseUrl = ConfigurationReader.getBaseUrl();42        String baseUrl = ConfigurationReader.getBaseUrl();
43        if (baseUrl != null && !baseUrl.isEmpty()) {43        if (baseUrl != null && !baseUrl.isEmpty()) {
n44            getDriver().get(baseUrl);n44            getPage().navigate(baseUrl);
45            Log.info("Navigated to: " + baseUrl);45            Log.info("Navigated to: " + baseUrl);
46        }46        }
47        Log.info("--- Test Setup Completed ---");47        Log.info("--- Test Setup Completed ---");
48    }48    }
4949
nn50    // Migration: Preserved DriverManager.quitDriver() call - DriverManager hand
 >les Playwright cleanup
50    @AfterEach51    @AfterEach
51    void tearDown() {52    void tearDown() {
52        Log.info("--- Test Teardown Started ---");53        Log.info("--- Test Teardown Started ---");
54        Log.info("--- Test Teardown Completed ---");55        Log.info("--- Test Teardown Completed ---");
55    }56    }
5657
n57    protected WebDriver getDriver() {n58    // Migration: Changed return type from WebDriver to Page - DriverManager now
 > returns Playwright Page instance
59    protected Page getPage() {
58        return DriverManager.getDriver();60        return DriverManager.getDriver();
59    }61    }
6062
nn63    // Migration: Migrated WebDriver.get() to Page.navigate() for URL navigation
61    protected void navigateTo(String url) {64    protected void navigateTo(String url) {
62        Log.step("Navigating to: " + url);65        Log.step("Navigating to: " + url);
n63        getDriver().get(url);n66        getPage().navigate(url);
64    }67    }
tt68 
65}69}
✗ Failed
BasePage.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\pages\BasePage.java
61 → 99 lines
50%
19.3s ✗ Did not compile 3 fix attempt(s)
ℹ Generation failed. Error: 5 compile error(s) after 3 fix attempt(s)
Compiler / generation error
5 compile error(s) after 3 fix attempt(s)
Patterns handled
  • sendKeys×1Replace with locator.fill() for inputs or type() for special keys
  • click×1Direct conversion to locator.click()
  • clear×1Remove - Playwright's fill() clears first
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.pages;n1package com.qastarter.pages.playwright;
22
nn3import com.microsoft.playwright.Page;
4import com.microsoft.playwright.Locator;
3import com.qastarter.core.DriverManager;5import com.qastarter.core.playwright.DriverManager;
4import com.qastarter.utils.Log;6import com.qastarter.utils.playwright.Log;
5import com.qastarter.utils.WaitUtils;7import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertTha
 >t;
6import org.openqa.selenium.*;8import org.openqa.selenium.By;
79
n8/**n
9* Base Page - Extend this in all your page objects.
10* Uses centralized WaitUtils for all explicit wait operations.
11*/
12public abstract class BasePage {10public abstract class BasePage {
1311
n14protected WebDriver driver;n12    protected Page page;
1513
n16public BasePage() {n14    public BasePage() {
17this.driver = DriverManager.getDriver();15        this.page = DriverManager.getDriver();
16    }
17 
18    // Migration: Replaced WaitUtils.waitForClickability with Playwright auto-wa
 >iting click
19    protected void click(By locator) {
20        Log.action("Click: " + locator);
21        // Convert By locator to CSS selector for Playwright
22        String selector = convertByToSelector(locator);
23        page.locator(selector).click();
24    }
25 
26    // Migration: Replaced element.clear() + sendKeys() with Playwright fill() w
 >hich handles both
27    protected void type(By locator, String text) {
28        Log.action("Type into: " + locator);
29        // Convert By locator to CSS selector for Playwright
30        String selector = convertByToSelector(locator);
31        // Playwright's fill() automatically clears and waits for visibility
32        page.locator(selector).fill(text);
33    }
34 
35    // Migration: Replaced WaitUtils.waitForVisibility with Playwright auto-wait
 >ing textContent
36    protected String getText(By locator) {
37        String selector = convertByToSelector(locator);
38        // Playwright auto-waits for visibility before getting text
39        return page.locator(selector).textContent();
40    }
41 
42    // Migration: Replaced try-catch with Selenium exceptions to Playwright isVi
 >sible check
43    protected boolean isDisplayed(By locator) {
44        try {
45            String selector = convertByToSelector(locator);
46            // Use isVisible() which checks both existence and visibility
47            return page.locator(selector).isVisible();
48        } catch (Exception e) {
49            return false;
50        }
51    }
52 
53    // Migration: Replaced WaitUtils.waitForVisibility with Playwright waitFor
54    protected void waitForElement(By locator) {
55        String selector = convertByToSelector(locator);
56        // Playwright auto-waits, but we can explicitly wait for visibility
57        page.locator(selector).waitFor();
58    }
59 
60    // Migration: Direct conversion from driver.getTitle() to page.title()
61    public String getPageTitle() {
62        return page.title();
63    }
64 
65    // Migration: Direct conversion from driver.getCurrentUrl() to page.url()
66    public String getCurrentUrl() {
67        return page.url();
68    }
69 
70    // Migration: Preserved logging functionality unchanged
71    protected void logAction(String action) {
72        Log.step("[" + getClass().getSimpleName() + "] " + action);
73    }
74 
75    // Migration: Abstract method preserved unchanged
76    public abstract boolean isLoaded();
77 
78    // Migration: Helper method to convert Selenium By locators to Playwright se
 >lectors
79    private String convertByToSelector(By locator) {
80        String locatorString = locator.toString();
81        if (locatorString.startsWith("By.id: ")) {
82            return "#" + locatorString.substring(7);
83        } else if (locatorString.startsWith("By.className: ")) {
84            return "." + locatorString.substring(14);
85        } else if (locatorString.startsWith("By.cssSelector: ")) {
86            return locatorString.substring(16);
87        } else if (locatorString.startsWith("By.name: ")) {
88            return "[name='" + locatorString.substring(9) + "']";
89        } else if (locatorString.startsWith("By.xpath: ")) {
90            return "xpath=" + locatorString.substring(10);
91        } else if (locatorString.startsWith("By.tagName: ")) {
92            return locatorString.substring(12);
93        } else {
94            // Fallback - return as xpath
95            return "xpath=" + locatorString;
96        }
97    }
98 
18}99}
t19 t
20protected void click(By locator) {
21Log.action("Click: " + locator);
22WaitUtils.waitForClickability(driver, locator).click();
23}
24 
25protected void type(By locator, String text) {
26Log.action("Type into: " + locator);
27WebElement element = WaitUtils.waitForVisibility(driver, locator);
28element.clear();
29element.sendKeys(text);
30}
31 
32protected String getText(By locator) {
33return WaitUtils.waitForVisibility(driver, locator).getText();
34}
35 
36protected boolean isDisplayed(By locator) {
37try {
38return driver.findElement(locator).isDisplayed();
39} catch (org.openqa.selenium.NoSuchElementException | org.openqa.selenium.StaleE
>lementReferenceException e) { 
40return false;
41}
42}
43 
44protected void waitForElement(By locator) {
45WaitUtils.waitForVisibility(driver, locator);
46}
47 
48public String getPageTitle() {
49return driver.getTitle();
50}
51 
52public String getCurrentUrl() {
53return driver.getCurrentUrl();
54}
55 
56protected void logAction(String action) {
57Log.step("[" + getClass().getSimpleName() + "] " + action);
58}
59 
60public abstract boolean isLoaded();
61}
✗ Failed
LoginPage.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\pages\LoginPage.java
60 → 83 lines
50%
13.6s ✗ Did not compile 2 fix attempt(s)
ℹ Generation failed. Error: 8 compile error(s) after 2 fix attempt(s)
Compiler / generation error
8 compile error(s) after 2 fix attempt(s)
Patterns handled
  • By_id×6Convert to CSS selector with #id
  • By_cssSelector×2Direct conversion to page.locator()
  • click×1Direct conversion to locator.click()
  • By_field×4Replace By field with String selector field. Initialize Locator in constructor: this.field = page.locator(selector).
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.pages;n1package com.qastarter.pages.playwright;
22
n3import org.openqa.selenium.By;n3import com.microsoft.playwright.Locator;
4import com.microsoft.playwright.Page;
5import com.qastarter.pages.playwright.BasePage;
46
n5/**n
6 * Login Page Object for SauceDemo
7 * URL: https://www.saucedemo.com
8 * 
9 * HOW TO CUSTOMIZE:
10 *   1. Update locators below for your app
11 *   2. Update credentials in: src/main/resources/config/dev.properties
12 */
13public class LoginPage extends BasePage {7public class LoginPage extends BasePage {
148
n15    // SauceDemo locatorsn9    private final Page page;
16    private final By usernameField = By.id("user-name");10    private final Locator usernameField;
17    private final By passwordField = By.id("password");11    private final Locator passwordField;
18    private final By loginButton = By.id("login-button");12    private final Locator loginButton;
19    private final By errorMessage = By.cssSelector("[data-test='error']");13    private final Locator errorMessage;
2014
nn15    public LoginPage(Page page) {
16        this.page = page;
17        this.usernameField = page.locator("#user-name");
18        this.passwordField = page.locator("#password");
19        this.loginButton = page.locator("#login-button");
20        this.errorMessage = page.locator("[data-test='error']");
21    }
22 
23    // Migration: Replaced isDisplayed() with Playwright's isVisible() for eleme
 >nt visibility check
21    @Override24    @Override
22    public boolean isLoaded() {25    public boolean isLoaded() {
n23        return isDisplayed(loginButton);n26        try {
27            return loginButton.isVisible();
28        } catch (Exception e) {
29            return false;
30        }
24    }31    }
2532
nn33    // Migration: Replaced type() helper with direct Playwright fill() - auto-cl
 >ears before typing
26    public LoginPage enterUsername(String username) {34    public LoginPage enterUsername(String username) {
27        logAction("Entering username: " + username);35        logAction("Entering username: " + username);
n28        type(usernameFieldusername);n36        usernameField.fill(username);
29        return this;37        return this;
30    }38    }
3139
nn40    // Migration: Replaced type() helper with direct Playwright fill() - auto-cl
 >ears before typing
32    public LoginPage enterPassword(String password) {41    public LoginPage enterPassword(String password) {
33        logAction("Entering password");42        logAction("Entering password");
n34        type(passwordFieldpassword);n43        passwordField.fill(password);
35        return this;44        return this;
36    }45    }
3746
nn47    // Migration: Replaced click() helper with direct Playwright click() - auto-
 >waits for clickability
38    public void clickLogin() {48    public void clickLogin() {
39        logAction("Clicking login button");49        logAction("Clicking login button");
n40        click(loginButton);n50        loginButton.click();
41    }51    }
4252
nn53    // Migration: Method chaining preserved - no changes needed to business logi
 >c
43    public void login(String username, String password) {54    public void login(String username, String password) {
44        enterUsername(username);55        enterUsername(username);
45        enterPassword(password);56        enterPassword(password);
46        clickLogin();57        clickLogin();
47    }58    }
4859
nn60    // Migration: Replaced isDisplayed() and getText() with Playwright's isVisib
 >le() and textContent()
49    public String getErrorMessage() {61    public String getErrorMessage() {
n50        return isDisplayed(errorMessage) ? getText(errorMessage) : "";n62        try {
63            return errorMessage.isVisible() ? errorMessage.textContent() : "";
64        } catch (Exception e) {
65            return "";
66        }
51    }67    }
5268
nn69    // Migration: Replaced isDisplayed() helper with direct Playwright isVisible
 >() check
53    public boolean isErrorDisplayed() {70    public boolean isErrorDisplayed() {
n54        return isDisplayed(errorMessage);n71        try {
72            return errorMessage.isVisible();
73        } catch (Exception e) {
74            return false;
75        }
55    }76    }
5677
nn78    // Migration: Replaced getCurrentUrl() helper with direct Playwright page.ur
 >l()
57    public boolean isLoginSuccessful() {79    public boolean isLoginSuccessful() {
n58        return getCurrentUrl().contains("inventory");n80        return page.url().contains("inventory");
59    }81    }
tt82 
60}83}
✓ Success
ConfigurationReader.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\config\ConfigurationReader.java
69 → 75 lines
100%
15.2s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.config;n1package com.qastarter.config.playwright;
22
3import java.io.InputStream;3import java.io.InputStream;
4import java.util.Properties;4import java.util.Properties;
18    private static final Properties properties = new Properties();18    private static final Properties properties = new Properties();
19    private static String currentEnvironment;19    private static String currentEnvironment;
2020
nn21    // No constructor needed - utility class with static methods only
22 
23    // Migration: Static initializer preserved - no Playwright-specific changes 
 >needed for configuration loading
21    static {24    static {
22        String env = System.getProperty("env", "dev");25        String env = System.getProperty("env", "dev");
23        currentEnvironment = (env == null || env.isEmpty()) ? "dev" : env;26        currentEnvironment = (env == null || env.isEmpty()) ? "dev" : env;
24        loadConfig();27        loadConfig();
25    }28    }
2629
nn30    // Migration: Configuration loading logic unchanged - works identically for 
 >Playwright
27    private static void loadConfig() {31    private static void loadConfig() {
28        String configFile = "config/" + currentEnvironment + ".properties";32        String configFile = "config/" + currentEnvironment + ".properties";
29        try (InputStream input = ConfigurationReader.class.getClassLoader().getR33        try (InputStream input = ConfigurationReader.class.getClassLoader().getR
>esourceAsStream(configFile)) {>esourceAsStream(configFile)) {
38        }42        }
39    }43    }
4044
nn45    // Migration: Property lookup preserved - System.getProperty takes precedenc
 >e over properties file
41    public static String getProperty(String key) {46    public static String getProperty(String key) {
42        return System.getProperty(key, properties.getProperty(key));47        return System.getProperty(key, properties.getProperty(key));
43    }48    }
4449
n45    public static String getProperty(String key, String defaultValue) {n50    // Migration: Base URL retrieval unchanged - used by Playwright page.navigat
 >e() calls
46        String value = getProperty(key);
47        return value != null ? value : defaultValue;
48    }
49 
50    public static String getBaseUrl() {51    public static String getBaseUrl() {
51        return getProperty("base.url");52        return getProperty("base.url");
52    }53    }
5354
nn55    // Migration: Browser configuration preserved - used by Playwright browser s
 >election logic
54    public static String getBrowser() {56    public static String getBrowser() {
55        return getProperty("browser", "chrome");57        return getProperty("browser", "chrome");
56    }58    }
5759
nn60    // Migration: Headless mode configuration preserved - used by Playwright lau
 >nch options
58    public static boolean isHeadless() {61    public static boolean isHeadless() {
59        return Boolean.parseBoolean(getProperty("headless", "false"));62        return Boolean.parseBoolean(getProperty("headless", "false"));
60    }63    }
6164
nn65    // Migration: Timeout configuration preserved - used by Playwright page time
 >out settings
62    public static int getTimeout() {66    public static int getTimeout() {
63        return Integer.parseInt(getProperty("timeout.default", "30"));67        return Integer.parseInt(getProperty("timeout.default", "30"));
64    }68    }
6569
nn70    // Migration: Environment getter preserved - useful for test reporting and d
 >ebugging
66    public static String getCurrentEnvironment() {71    public static String getCurrentEnvironment() {
67        return currentEnvironment;72        return currentEnvironment;
68    }73    }
tt74 
69}75}
✓ Success
Environment.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\config\Environment.java
30 → 30 lines
100%
0.1s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
t1package com.qastarter.config;t1package com.qastarter.config.playwright;
22
3/**3/**
4 * Environment enumeration for configuration.4 * Environment enumeration for configuration.
✗ Failed
BrowserFactory.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\core\BrowserFactory.java
81 → 65 lines
50%
11.9s ✗ Did not compile 3 fix attempt(s)
ℹ Generation failed. Error: 2 compile error(s) after 3 fix attempt(s)
Compiler / generation error
2 compile error(s) after 3 fix attempt(s)
Patterns handled
  • WebDriver×1Replace with Playwright Page and BrowserContext
  • ChromeDriver×1Replace with Playwright browser launch
  • FirefoxDriver×1Replace with Playwright Firefox
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.core;n1package com.qastarter.core.playwright;
22
n3import com.qastarter.utils.Log;n3import com.qastarter.utils.playwright.Log;
4import org.openqa.selenium.WebDriver;4import com.microsoft.playwright.*;
5import org.openqa.selenium.chrome.ChromeDriver;
6import org.openqa.selenium.chrome.ChromeOptions;
7import org.openqa.selenium.edge.EdgeDriver;
8import org.openqa.selenium.edge.EdgeOptions;
9import org.openqa.selenium.firefox.FirefoxDriver;
10import org.openqa.selenium.firefox.FirefoxOptions;
11import org.openqa.selenium.safari.SafariDriver;
125
n13/**n
14* Browser Factory - Creates WebDriver instances.
15*
16* Selenium 4.16+ uses built-in Selenium Manager for automatic driver management.
17* No external driver setup required!
18*
19* Supported browsers: chrome, firefox, edge, safari
20*/
21public class BrowserFactory {6public class BrowserFactory {
227
n23private BrowserFactory() {}n8    private BrowserFactory() {}
249
nn10    // Migration: Changed return type from WebDriver to Browser to match Playwri
 >ght architecture. Browser instances are created using Playwright's browser types
 > with launch options.
25public static WebDriver createDriver(String browser, boolean headless) {11    public static Browser createDriver(String browser, boolean headless) {
26WebDriver driver;12        Browser browserInstance;
13        Playwright playwright = Playwright.create();
14        switch (browser.toLowerCase()) {
15            case "firefox":
16            BrowserType.LaunchOptions firefoxOptions = new BrowserType.LaunchOpt
 >ions()
17            .setHeadless(headless)
18            .setArgs(java.util.Arrays.asList(
19            "--width=1920",
20            "--height=1080"
21            ));
22            browserInstance = playwright.firefox().launch(firefoxOptions);
23            break;
24            case "edge":
25            BrowserType.LaunchOptions edgeOptions = new BrowserType.LaunchOption
 >s()
26            .setHeadless(headless)
27            .setArgs(java.util.Arrays.asList(
28            "--window-size=1920,1080",
29            "--no-sandbox",
30            "--disable-dev-shm-usage",
31            "--disable-extensions"
32            ));
33            browserInstance = playwright.chromium().launch(edgeOptions.setChanne
 >l("msedge"));
34            break;
35            case "safari":
36            // Safari does not support headless mode
37            if (headless) {
38                Log.warn("Safari does not support headless mode - running in nor
 >mal mode");
39            }
40            BrowserType.LaunchOptions safariOptions = new BrowserType.LaunchOpti
 >ons()
41            .setHeadless(false);
42            browserInstance = playwright.webkit().launch(safariOptions);
43            break;
44            case "chrome":
45            default:
46            BrowserType.LaunchOptions chromeOptions = new BrowserType.LaunchOpti
 >ons()
47            .setHeadless(headless)
48            .setArgs(java.util.Arrays.asList(
49            "--window-size=1920,1080",
50            "--no-sandbox",
51            "--disable-dev-shm-usage",
52            "--disable-gpu",
53            "--disable-extensions",
54            "--disable-infobars",
55            "--ignore-certificate-errors",
56            "--remote-allow-origins=*"
57            ));
58            browserInstance = playwright.chromium().launch(chromeOptions);
59            break;
60        }
61        Log.info("Created " + browser + " browser (Playwright)");
62        return browserInstance;
63    }
2764
n28switch (browser.toLowerCase()) {n
29case "firefox":
30FirefoxOptions firefoxOptions = new FirefoxOptions();
31if (headless) {
32firefoxOptions.addArguments("--headless");
33}65}
t34firefoxOptions.addArguments("--width=1920");t
35firefoxOptions.addArguments("--height=1080");
36driver = new FirefoxDriver(firefoxOptions);
37break;
38 
39case "edge":
40EdgeOptions edgeOptions = new EdgeOptions();
41if (headless) {
42edgeOptions.addArguments("--headless=new");
43}
44edgeOptions.addArguments("--window-size=1920,1080");
45edgeOptions.addArguments("--no-sandbox");
46edgeOptions.addArguments("--disable-dev-shm-usage");
47edgeOptions.addArguments("--disable-extensions");
48driver = new EdgeDriver(edgeOptions);
49break;
50 
51case "safari":
52// Safari does not support headless mode
53if (headless) {
54Log.warn("Safari does not support headless mode - running in normal mode");
55}
56driver = new SafariDriver();
57break;
58 
59case "chrome":
60default:
61ChromeOptions chromeOptions = new ChromeOptions();
62if (headless) {
63chromeOptions.addArguments("--headless=new");
64}
65// Stability options for CI/CD environments
66chromeOptions.addArguments("--window-size=1920,1080");
67chromeOptions.addArguments("--no-sandbox");
68chromeOptions.addArguments("--disable-dev-shm-usage");
69chromeOptions.addArguments("--disable-gpu");
70chromeOptions.addArguments("--disable-extensions");
71chromeOptions.addArguments("--disable-infobars");
72chromeOptions.addArguments("--ignore-certificate-errors");
73chromeOptions.addArguments("--remote-allow-origins=*");
74driver = new ChromeDriver(chromeOptions);
75break;
76}
77 
78Log.info("Created " + browser + " driver (Selenium Manager)");
79return driver;
80}
81}
✗ Failed
DriverManager.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\core\DriverManager.java
63 → 86 lines
50%
15.4s ✗ Did not compile 2 fix attempt(s)
ℹ Generation failed. Error: 6 compile error(s) after 2 fix attempt(s)
Compiler / generation error
6 compile error(s) after 2 fix attempt(s)
Patterns handled
  • WebDriver×3Replace with Playwright Page and BrowserContext
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.core;n1package com.qastarter.core.playwright;
22
nn3import com.microsoft.playwright.Browser;
4import com.microsoft.playwright.BrowserContext;
5import com.microsoft.playwright.Page;
6import com.microsoft.playwright.Playwright;
3import com.qastarter.config.ConfigurationReader;7import com.qastarter.config.playwright.ConfigurationReader;
8import com.qastarter.core.playwright.BrowserFactory;
4import com.qastarter.utils.Log;9import com.qastarter.utils.playwright.Log;
5import org.openqa.selenium.WebDriver;
610
n7/**n
8 * Driver Manager - Thread-safe WebDriver lifecycle management.
9 * 
10 * Supports parallel test execution via ThreadLocal.
11 */
12public class DriverManager {11public class DriverManager {
1312
n14    private static final ThreadLocal<WebDriverdriverThreadLocal = new ThreadLon13    private static final ThreadLocal<PlaywrightplaywrightThreadLocal = new Thr
>cal<>();>eadLocal<>();
1514
16    private DriverManager() {}15    private DriverManager() {}
1716
nn17    // Migration: Changed return type from WebDriver to Page - Playwright's equi
 >valent
18    public static WebDriver getDriver() {18    public static Page getDriver() {
19        WebDriver driver = driverThreadLocal.get();19        Page page = pageThreadLocal.get();
20        if (driver == null) {20        if (page == null) {
21            throw new IllegalStateException("Driver not initialized. Call initia21            throw new IllegalStateException("Driver not initialized. Call initia
>lizeDriver() first.");>lizeDriver() first.");
22        }22        }
n23        return driver;n23        return page;
24    }24    }
2525
nn26    // Migration: Replaced WebDriver creation with Playwright Browser/Page creat
 >ion, stored all instances in ThreadLocal
26    public static void initializeDriver() {27    public static void initializeDriver() {
n27        if (driverThreadLocal.get() != null) {n28        if (pageThreadLocal.get() != null) {
28            Log.warn("Driver already exists. Cleaning up...");29            Log.warn("Driver already exists. Cleaning up...");
29            quitDriver();30            quitDriver();
30        }31        }
n31 n
32        String browser = ConfigurationReader.getBrowser();32        String browser = ConfigurationReader.getBrowser();
33        boolean headless = ConfigurationReader.isHeadless();33        boolean headless = ConfigurationReader.isHeadless();
n34 n
35        Log.info("Initializing browser: " + browser + " | Headless: " + headless34        Log.info("Initializing browser: " + browser + " | Headless: " + headless
>);>);
n36 n35        // Create Playwright instances
36        Playwright playwright = Playwright.create();
37        WebDriver driver = BrowserFactory.createDriver(browser, headless);37        Browser browserInstance = BrowserFactory.createDriver(browser, headless)
 >;
38        BrowserContext context = browserInstance.newContext();
39        Page page = context.newPage();
40        // Store in ThreadLocal
41        playwrightThreadLocal.set(playwright);
42        browserThreadLocal.set(browserInstance);
43        contextThreadLocal.set(context);
38        driverThreadLocal.set(driver);44        pageThreadLocal.set(page);
39 45        // Maximize window equivalent - set viewport size
40        int timeout = ConfigurationReader.getTimeout();46        page.setViewportSize(1920, 1080);
41        driver.manage().window().maximize();
42 
43        Log.info("Browser initialized successfully");47        Log.info("Browser initialized successfully");
44    }48    }
4549
nn50    // Migration: Replaced WebDriver.quit() with proper Playwright cleanup seque
 >nce
46    public static void quitDriver() {51    public static void quitDriver() {
n47        WebDriver driver = driverThreadLocal.get();n52        Page page = pageThreadLocal.get();
48        if (driver != null) {53        if (page != null) {
49            try {54            try {
n50                driver.quit();n55                // Close in reverse order: Page -> Context -> Browser -> Playwri
 >ght
56                BrowserContext context = contextThreadLocal.get();
57                Browser browser = browserThreadLocal.get();
58                Playwright playwright = playwrightThreadLocal.get();
59                if (context != null) {
60                    context.close();
61                }
62                if (browser != null) {
63                    browser.close();
64                }
65                if (playwright != null) {
66                    playwright.close();
67                }
51                Log.info("Browser closed");68                Log.info("Browser closed");
52            } catch (Exception e) {69            } catch (Exception e) {
53                Log.error("Error closing browser: " + e.getMessage());70                Log.error("Error closing browser: " + e.getMessage());
54            } finally {71            } finally {
nn72                // Clean up all ThreadLocal instances
73                pageThreadLocal.remove();
74                contextThreadLocal.remove();
55                driverThreadLocal.remove();75                browserThreadLocal.remove();
76                playwrightThreadLocal.remove();
56            }77            }
57        }78        }
58    }79    }
5980
nn81    // Migration: Check Page ThreadLocal instead of WebDriver ThreadLocal
60    public static boolean isDriverInitialized() {82    public static boolean isDriverInitialized() {
n61        return driverThreadLocal.get() != null;n83        return pageThreadLocal.get() != null;
62    }84    }
tt85 
63}86}
✓ Success
TestWatcher.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\core\TestWatcher.java
42 → 43 lines
100%
9.3s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.core;n1package com.qastarter.core.playwright;
22
n3import com.qastarter.utils.Log;n3import com.qastarter.utils.playwright.Log;
4import com.qastarter.utils.ScreenshotUtils;4import com.qastarter.utils.playwright.ScreenshotUtils;
5import com.qastarter.utils.AllureManager;5import com.qastarter.utils.playwright.AllureManager;
6import org.junit.jupiter.api.extension.ExtensionContext;6import org.junit.jupiter.api.extension.ExtensionContext;
n7 n
8import java.util.Optional;7import java.util.Optional;
98
n10/**n
11 * JUnit5 TestWatcher - Handles test lifecycle events.
12 */
13public class TestWatcher implements org.junit.jupiter.api.extension.TestWatcher 9public class TestWatcher implements org.junit.jupiter.api.extension.TestWatcher 
>{>{
1410
nn11    // No explicit constructor needed - using default constructor
12 
13    // Migration: No changes needed - Log utility method call preserved
15    @Override14    @Override
16    public void testSuccessful(ExtensionContext context) {15    public void testSuccessful(ExtensionContext context) {
17        Log.testEnd(context.getDisplayName(), "PASSED");16        Log.testEnd(context.getDisplayName(), "PASSED");
18    }17    }
1918
nn19    // Migration: Preserved all logging and screenshot capture logic - utility c
 >lasses handle Playwright migration internally
20    @Override20    @Override
21    public void testFailed(ExtensionContext context, Throwable cause) {21    public void testFailed(ExtensionContext context, Throwable cause) {
22        Log.error("TEST FAILED: " + context.getDisplayName());22        Log.error("TEST FAILED: " + context.getDisplayName());
23        Log.error("Reason: " + cause.getMessage());23        Log.error("Reason: " + cause.getMessage());
n24 n
25        String screenshotPath = ScreenshotUtils.capture("FAILED_" + context.getD24        String screenshotPath = ScreenshotUtils.capture("FAILED_" + context.getD
>isplayName());>isplayName());
n26 n
27        byte[] screenshot = ScreenshotUtils.captureAsBytes();25        byte[] screenshot = ScreenshotUtils.captureAsBytes();
28        if (screenshot != null) {26        if (screenshot != null) {
29            AllureManager.attachScreenshot("Screenshot on Failure", screenshot);27            AllureManager.attachScreenshot("Screenshot on Failure", screenshot);
30        }28        }
31    }29    }
3230
nn31    // Migration: No changes needed - Log utility method call preserved
33    @Override32    @Override
34    public void testAborted(ExtensionContext context, Throwable cause) {33    public void testAborted(ExtensionContext context, Throwable cause) {
35        Log.warn("TEST ABORTED: " + context.getDisplayName());34        Log.warn("TEST ABORTED: " + context.getDisplayName());
36    }35    }
3736
nn37    // Migration: No changes needed - Log utility method call preserved
38    @Override38    @Override
39    public void testDisabled(ExtensionContext context, Optional<String> reason) 39    public void testDisabled(ExtensionContext context, Optional<String> reason) 
>{>{
40        Log.warn("TEST DISABLED: " + context.getDisplayName() + " - " + reason.o40        Log.warn("TEST DISABLED: " + context.getDisplayName() + " - " + reason.o
>rElse("No reason"));>rElse("No reason"));
41    }41    }
tt42 
42}43}
✓ Success
AllureManager.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\utils\AllureManager.java
47 → 45 lines
100%
10.0s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.utils;n1package com.qastarter.utils.playwright;
22
3import io.qameta.allure.Allure;3import io.qameta.allure.Allure;
4import io.qameta.allure.Attachment;4import io.qameta.allure.Attachment;
nn5import java.io.ByteArrayInputStream;
6import com.qastarter.utils.playwright.Log;
57
n6import java.io.ByteArrayInputStream;n
7 
8/**
9 * Allure Manager - Allure reporting integration.
10 * 
11 * Results saved to: build/allure-results (Gradle) or target/allure-results (Mav
>en) 
12 * 
13 * To view report:
14 *   Gradle: gradle allureServe
15 *   Maven: mvn allure:serve
16 */
17public class AllureManager {8public class AllureManager {
189
19    private AllureManager() {}10    private AllureManager() {}
2011
nn12    // Migration: No changes needed - Allure attachment works the same with Play
 >wright screenshots
21    @Attachment(value = "{0}", type = "image/png")13    @Attachment(value = "{0}", type = "image/png")
22    public static byte[] attachScreenshot(String name, byte[] screenshot) {14    public static byte[] attachScreenshot(String name, byte[] screenshot) {
23        Log.info("[Allure] Attaching screenshot: " + name);15        Log.info("[Allure] Attaching screenshot: " + name);
24        return screenshot;16        return screenshot;
25    }17    }
2618
nn19    // Migration: No changes needed - text attachment is framework-agnostic
27    @Attachment(value = "{0}", type = "text/plain")20    @Attachment(value = "{0}", type = "text/plain")
28    public static String attachText(String name, String text) {21    public static String attachText(String name, String text) {
29        return text;22        return text;
30    }23    }
3124
nn25    // Migration: No changes needed - Allure API remains the same for Playwright
 > screenshots
32    public static void attachScreenshotToReport(String name, byte[] screenshot) 26    public static void attachScreenshotToReport(String name, byte[] screenshot) 
>{>{
33        Allure.addAttachment(name, new ByteArrayInputStream(screenshot));27        Allure.addAttachment(name, new ByteArrayInputStream(screenshot));
34    }28    }
3529
nn30    // Migration: No changes needed - Allure step reporting is framework-agnosti
 >c
36    public static void step(String stepName) {31    public static void step(String stepName) {
37        Allure.step(stepName);32        Allure.step(stepName);
38    }33    }
3934
nn35    // Migration: No changes needed - Allure description API is framework-agnost
 >ic
40    public static void addDescription(String description) {36    public static void addDescription(String description) {
41        Allure.description(description);37        Allure.description(description);
42    }38    }
4339
nn40    // Migration: No changes needed - Allure link API is framework-agnostic
44    public static void addLink(String name, String url) {41    public static void addLink(String name, String url) {
45        Allure.link(name, url);42        Allure.link(name, url);
46    }43    }
tt44 
47}45}
✓ Success
Log.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\utils\Log.java
81 → 65 lines
100%
12.7s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.utils;n1package com.qastarter.utils.playwright;
22
3import org.apache.logging.log4j.LogManager;3import org.apache.logging.log4j.LogManager;
4import org.apache.logging.log4j.Logger;4import org.apache.logging.log4j.Logger;
55
n6/**n
7 * Logger Utility - Consistent logging across the framework.
8 * 
9 * Uses Log4j2. Logs go to: logs/test_latest.log
10 */
11public class Log {6public class Log {
127
13    private static final Logger logger = LogManager.getLogger(Log.class);8    private static final Logger logger = LogManager.getLogger(Log.class);
149
15    private Log() {}10    private Log() {}
1611
nn12    // Migration: No changes needed - logging utility remains the same
17    public static void info(String message) {13    public static void info(String message) {
18        logger.info(message);14        logger.info(message);
19    }15    }
2016
nn17    // Migration: No changes needed - logging utility remains the same
21    public static void debug(String message) {18    public static void debug(String message) {
22        logger.debug(message);19        logger.debug(message);
23    }20    }
2421
nn22    // Migration: No changes needed - logging utility remains the same
25    public static void warn(String message) {23    public static void warn(String message) {
26        logger.warn(message);24        logger.warn(message);
27    }25    }
2826
nn27    // Migration: No changes needed - logging utility remains the same
29    public static void error(String message) {28    public static void error(String message) {
30        logger.error(message);29        logger.error(message);
31    }30    }
3231
n33    public static void error(String message, Throwable throwable) {n32    // Migration: No changes needed - test step logging remains the same
34        logger.error(message, throwable);
35    }
36 
37    /**
38     * Log a test step
39     */
40    public static void step(String stepDescription) {33    public static void step(String stepDescription) {
41        logger.info("STEP: " + stepDescription);34        logger.info("STEP: " + stepDescription);
42    }35    }
4336
n44    /**n37    // Migration: No changes needed - action logging remains the same
45     * Log an action (click, type, etc.)
46     */
47    public static void action(String actionDescription) {38    public static void action(String actionDescription) {
48        logger.info("ACTION: " + actionDescription);39        logger.info("ACTION: " + actionDescription);
49    }40    }
5041
n51    /**n42    // Migration: Preserved for compatibility - though Playwright auto-waits, ex
 >plicit wait logging may still be useful for debugging
52     * Log wait operation
53     */
54    public static void logWait(String waitDescription) {43    public static void logWait(String waitDescription) {
55        logger.debug("WAIT: " + waitDescription);44        logger.debug("WAIT: " + waitDescription);
56    }45    }
5746
n58    /**n47    // Migration: No changes needed - assertion logging remains the same
59     * Log assertion
60     */
61    public static void assertion(String assertionDescription) {48    public static void assertion(String assertionDescription) {
62        logger.info("ASSERT: " + assertionDescription);49        logger.info("ASSERT: " + assertionDescription);
63    }50    }
6451
n65    /**n52    // Migration: No changes needed - test lifecycle logging remains the same
66     * Log test start
67     */
68    public static void testStart(String testName) {53    public static void testStart(String testName) {
69        logger.info("========================================");54        logger.info("========================================");
70        logger.info("TEST START: " + testName);55        logger.info("TEST START: " + testName);
71        logger.info("========================================");56        logger.info("========================================");
72    }57    }
7358
n74    /**n59    // Migration: No changes needed - test lifecycle logging remains the same
75     * Log test end
76     */
77    public static void testEnd(String testName, String status) {60    public static void testEnd(String testName, String status) {
78        logger.info("TEST END: " + testName + " - " + status);61        logger.info("TEST END: " + testName + " - " + status);
79        logger.info("========================================");62        logger.info("========================================");
80    }63    }
tt64 
81}65}
✗ Failed
ScreenshotUtils.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\utils\ScreenshotUtils.java
66 → 58 lines
50%
10.0s ✗ Did not compile 2 fix attempt(s)
ℹ Generation failed. Error: 1 compile error(s) after 2 fix attempt(s)
Compiler / generation error
1 compile error(s) after 2 fix attempt(s)
Patterns handled
  • WebDriver×2Replace with Playwright Page and BrowserContext
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.utils;n1package com.qastarter.utils.playwright;
22
n3import com.qastarter.core.DriverManager;n3import com.qastarter.core.playwright.DriverManager;
4import org.openqa.selenium.OutputType;4import com.microsoft.playwright.Page;
5import org.openqa.selenium.TakesScreenshot;
6import org.openqa.selenium.WebDriver;
7 
8import java.io.File;5import java.io.File;
9import java.nio.file.Files;6import java.nio.file.Files;
10import java.nio.file.Path;7import java.nio.file.Path;
12import java.text.SimpleDateFormat;9import java.text.SimpleDateFormat;
13import java.util.Date;10import java.util.Date;
1411
n15/**n
16 * Screenshot Utilities - Capture screenshots on demand.
17 * 
18 * Screenshots saved to: screenshots/
19 */
20public class ScreenshotUtils {12public class ScreenshotUtils {
2113
22    private static final String SCREENSHOT_DIR = "screenshots";14    private static final String SCREENSHOT_DIR = "screenshots";
2315
24    private ScreenshotUtils() {}16    private ScreenshotUtils() {}
2517
nn18    // Migration: Replaced WebDriver TakesScreenshot with Playwright page.screen
 >shot() which returns bytes directly
26    public static String capture(String testName) {19    public static String capture(String testName) {
27        try {20        try {
n28            WebDriver driver = DriverManager.getDriver();n21            Page page = DriverManager.getDriver();
29            if (driver == null) {22            if (page == null) {
30                Log.error("Cannot capture screenshot - driver is null");23                Log.error("Cannot capture screenshot - page is null");
31                return null;24                return null;
32            }25            }
n33 n
34            Path dir = Paths.get(SCREENSHOT_DIR);26            Path dir = Paths.get(SCREENSHOT_DIR);
35            if (!Files.exists(dir)) {27            if (!Files.exists(dir)) {
36                Files.createDirectories(dir);28                Files.createDirectories(dir);
37            }29            }
n38 n
39            String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(ne30            String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(ne
>w Date());>w Date());
40            String sanitizedName = testName.replaceAll("[^a-zA-Z0-9_-]", "_");31            String sanitizedName = testName.replaceAll("[^a-zA-Z0-9_-]", "_");
41            String fileName = sanitizedName + "_" + timestamp + ".png";32            String fileName = sanitizedName + "_" + timestamp + ".png";
42            Path filePath = dir.resolve(fileName);33            Path filePath = dir.resolve(fileName);
n43 n34            // Playwright screenshot capture - returns byte array directly
44            File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputT35            byte[] screenshot = page.screenshot();
>ype.FILE); 
45            Files.copy(screenshot.toPath(), filePath);36            Files.write(filePath, screenshot);
46 
47            Log.info("Screenshot saved: " + filePath);37            Log.info("Screenshot saved: " + filePath);
48            return filePath.toString();38            return filePath.toString();
n49 n
50        } catch (Exception e) {39        } catch (Exception e) {
51            Log.error("Failed to capture screenshot: " + e.getMessage());40            Log.error("Failed to capture screenshot: " + e.getMessage());
52            return null;41            return null;
53        }42        }
54    }43    }
5544
nn45    // Migration: Replaced WebDriver TakesScreenshot with Playwright page.screen
 >shot() - much simpler API
56    public static byte[] captureAsBytes() {46    public static byte[] captureAsBytes() {
57        try {47        try {
n58            WebDriver driver = DriverManager.getDriver();n48            Page page = DriverManager.getDriver();
59            if (driver == null) return null;49            if (page == null) return null;
60            return ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);50            // Playwright screenshot returns byte array directly
51            return page.screenshot();
61        } catch (Exception e) {52        } catch (Exception e) {
62            Log.error("Failed to capture screenshot bytes: " + e.getMessage());53            Log.error("Failed to capture screenshot bytes: " + e.getMessage());
63            return null;54            return null;
64        }55        }
65    }56    }
tt57 
66}58}
✗ Failed
WaitUtils.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\utils\WaitUtils.java
100 → 100 lines
50%
27.6s ✗ Did not compile 2 fix attempt(s)
ℹ Generation failed. Error: 4 compile error(s) after 2 fix attempt(s)
Compiler / generation error
4 compile error(s) after 2 fix attempt(s)
Patterns handled
  • WebDriverWait×2Remove explicit wait - Playwright auto-waits for actionability
  • ExpectedConditions×10Replace with Playwright assertions or locator methods
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.utils;n1package com.qastarter.utils.playwright;
22
nn3import com.microsoft.playwright.Locator;
4import com.microsoft.playwright.Page;
3import com.qastarter.config.ConfigurationReader;5import com.qastarter.config.playwright.ConfigurationReader;
4import com.qastarter.core.DriverManager;6import com.qastarter.core.playwright.DriverManager;
7import com.qastarter.utils.playwright.Log;
5import org.openqa.selenium.By;8import org.openqa.selenium.By;
n6import org.openqa.selenium.WebDriver;n
7import org.openqa.selenium.WebElement;9import org.openqa.selenium.WebElement;
n8import org.openqa.selenium.support.ui.ExpectedConditions;n10import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertTha
 >t;
9import org.openqa.selenium.support.ui.WebDriverWait;
1011
n11import java.time.Duration;n
12 
13/**
14 * Wait Utilities - Explicit wait helpers.
15 * 
16 * Timeout configured in: src/main/resources/config/{env}.properties
17 */
18public class WaitUtils {12public class WaitUtils {
1913
nn14    // No constructor needed - utility class with static methods only
15 
16    // Migration: Preserved private constructor to prevent instantiation
20    private WaitUtils() {17    private WaitUtils() {
21        // Private constructor18        // Private constructor
22    }19    }
2320
n24    private static WebDriverWait getWait() {n21    // Migration: Replaced WebDriverWait with Playwright auto-waiting and visibi
 >lity assertion
25        int timeout = ConfigurationReader.getTimeout();22    public static WebElement waitForVisibility(By locator) {
26        return new WebDriverWait(DriverManager.getDriver(), Duration.ofSeconds(t23        Log.logWait("Waiting for visibility: " + locator);
>imeout)); 
24        // In Playwright, locator actions auto-wait for visibility
25        // Convert By to CSS selector and ensure element is visible
26        Page page = DriverManager.getDriver();
27        String selector = convertByToSelector(locator);
28        Locator element = page.locator(selector);
29        assertThat(element).isVisible();
30        // Return null as WebElement is not applicable in Playwright context
31        // This maintains API compatibility while using Playwright's auto-waitin
 >g
32        return null;
27    }33    }
2834
n29    private static WebDriverWait getWait(WebDriver driver) {n35    // Migration: Replaced explicit clickability wait with Playwright visibility
 > and enabled assertions
30        int timeout = ConfigurationReader.getTimeout();36    public static WebElement waitForClickability(By locator) {
31        return new WebDriverWait(driver, Duration.ofSeconds(timeout));37        Log.logWait("Waiting for clickability: " + locator);
38        // Playwright auto-waits for clickability on click actions
39        // We can verify element is enabled and visible
40        Page page = DriverManager.getDriver();
41        String selector = convertByToSelector(locator);
42        Locator element = page.locator(selector);
43        assertThat(element).isVisible();
44        assertThat(element).isEnabled();
45        return null;
32    }46    }
3347
n34    /**n48    // Migration: Replaced presence wait with Playwright attached assertion
35     * Wait for element to be visible
36     */
37    public static WebElement waitForVisibility(By locator) {49    public static WebElement waitForPresence(By locator) {
38        Log.logWait("Waiting for visibility: " + locator);50        Log.logWait("Waiting for presence: " + locator);
39        return getWait().until(ExpectedConditions.visibilityOfElementLocated(loc51        // Playwright locators auto-wait for presence in DOM
>ator)); 
52        Page page = DriverManager.getDriver();
53        String selector = convertByToSelector(locator);
54        Locator element = page.locator(selector);
55        assertThat(element).isAttached();
56        return null;
40    }57    }
4158
n42    /**n59    // Migration: Replaced invisibility wait with Playwright hidden assertion
43     * Wait for element to be clickable
44     */
45    public static WebElement waitForClickability(By locator) {60    public static boolean waitForInvisibility(By locator) {
46        Log.logWait("Waiting for clickability: " + locator);61        Log.logWait("Waiting for invisibility: " + locator);
47        return getWait().until(ExpectedConditions.elementToBeClickable(locator))62        Page page = DriverManager.getDriver();
>; 
63        String selector = convertByToSelector(locator);
64        Locator element = page.locator(selector);
65        assertThat(element).isHidden();
66        return true;
48    }67    }
4968
n50    /**n69    // Migration: Replaced text presence wait with Playwright containsText asser
 >tion
51     * Wait for element to be present in DOM
52     */
53    public static WebElement waitForPresence(By locator) {70    public static boolean waitForTextPresent(By locator, String text) {
54        Log.logWait("Waiting for presence: " + locator);71        Log.logWait("Waiting for text '" + text + "' in: " + locator);
55        return getWait().until(ExpectedConditions.presenceOfElementLocated(locat72        Page page = DriverManager.getDriver();
>or)); 
73        String selector = convertByToSelector(locator);
74        Locator element = page.locator(selector);
75        assertThat(element).containsText(text);
76        return true;
56    }77    }
5778
n58    /**n79    // Migration: Helper method to convert Selenium By locators to Playwright se
 >lector strings
59     * Wait for element to disappear80    private static String convertByToSelector(By locator) {
60     */81        String locatorString = locator.toString();
61    public static boolean waitForInvisibility(By locator) {82        if (locatorString.startsWith("By.id: ")) {
62        Log.logWait("Waiting for invisibility: " + locator);83            return "#" + locatorString.substring(7);
63        return getWait().until(ExpectedConditions.invisibilityOfElementLocated(l84        } else if (locatorString.startsWith("By.className: ")) {
>ocator)); 
85            return "." + locatorString.substring(14);
86        } else if (locatorString.startsWith("By.cssSelector: ")) {
87            return locatorString.substring(16);
88        } else if (locatorString.startsWith("By.xpath: ")) {
89            return "xpath=" + locatorString.substring(10);
90        } else if (locatorString.startsWith("By.name: ")) {
91            return "[name='" + locatorString.substring(9) + "']";
92        } else if (locatorString.startsWith("By.tagName: ")) {
93            return locatorString.substring(12);
94        } else {
95            // Fallback - return as xpath
96            return "xpath=" + locatorString;
97        }
64    }98    }
6599
t66    /**t
67     * Wait for text to be present in element
68     */
69    public static boolean waitForTextPresent(By locator, String text) {
70        Log.logWait("Waiting for text '" + text + "' in: " + locator);
71        return getWait().until(ExpectedConditions.textToBePresentInElementLocate
>d(locator, text)); 
72    }
73 
74    // -------- Driver-explicit overloads (for callers that hold their own WebDr
>iver) -------- 
75 
76    public static WebElement waitForVisibility(WebDriver driver, By locator) {
77        Log.logWait("Waiting for visibility: " + locator);
78        return getWait(driver).until(ExpectedConditions.visibilityOfElementLocat
>ed(locator)); 
79    }
80 
81    public static WebElement waitForClickability(WebDriver driver, By locator) {
82        Log.logWait("Waiting for clickability: " + locator);
83        return getWait(driver).until(ExpectedConditions.elementToBeClickable(loc
>ator)); 
84    }
85 
86    public static WebElement waitForPresence(WebDriver driver, By locator) {
87        Log.logWait("Waiting for presence: " + locator);
88        return getWait(driver).until(ExpectedConditions.presenceOfElementLocated
>(locator)); 
89    }
90 
91    public static boolean waitForInvisibility(WebDriver driver, By locator) {
92        Log.logWait("Waiting for invisibility: " + locator);
93        return getWait(driver).until(ExpectedConditions.invisibilityOfElementLoc
>ated(locator)); 
94    }
95 
96    public static boolean waitForTextPresent(WebDriver driver, By locator, Strin
>g text) { 
97        Log.logWait("Waiting for text '" + text + "' in: " + locator);
98        return getWait(driver).until(ExpectedConditions.textToBePresentInElement
>Located(locator, text)); 
99    }
100}100}
✗ Failed
WebActions.java D:\TestFlux\samples\selenium-java-project-bdd\src\main\java\com\qastarter\utils\WebActions.java
121 → 128 lines
50%
24.5s ✗ Did not compile 3 fix attempt(s)
ℹ Generation failed. Error: 3 compile error(s) after 3 fix attempt(s)
Compiler / generation error
3 compile error(s) after 3 fix attempt(s)
Patterns handled
  • Actions×1Replace with Playwright keyboard/mouse APIs
  • sendKeys×1Replace with locator.fill() for inputs or type() for special keys
  • click×1Direct conversion to locator.click()
  • clear×1Remove - Playwright's fill() clears first
  • Select×1Replace with locator.selectOption()
  • JavascriptExecutor×2Replace with page.evaluate()
  • hover×1Replace with locator.hover()
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.utils;n1package com.qastarter.utils.playwright;
22
nn3import com.microsoft.playwright.Locator;
4import com.microsoft.playwright.Page;
3import com.qastarter.core.DriverManager;5import com.qastarter.core.playwright.DriverManager;
6import com.qastarter.utils.playwright.Log;
4import org.openqa.selenium.By;7import org.openqa.selenium.By;
n5import org.openqa.selenium.JavascriptExecutor;n
6import org.openqa.selenium.WebDriver;
7import org.openqa.selenium.WebElement;
8import org.openqa.selenium.interactions.Actions;
9import org.openqa.selenium.support.ui.Select;
108
n11/**n
12 * Web Actions - Common web interaction utilities.
13 * 
14 * All methods include logging and error handling.
15 */
16public class WebActions {9public class WebActions {
1710
18    private WebActions() {11    private WebActions() {
19        // Private constructor12        // Private constructor
20    }13    }
2114
nn15    // Migration: Changed from getDriver() to getPage() to reflect Playwright AP
 >I
22    private static WebDriver getDriver() {16    private static Page getPage() {
23        return DriverManager.getDriver();17        return DriverManager.getDriver();
24    }18    }
2519
n26    /**n20    // Migration: Replaced WebElement.click() with Playwright locator.click() - 
 >auto-waits for clickability
27     * Click on element
28     */
29    public static void click(By locator) {21    public static void click(By locator) {
30        Log.action("Click: " + locator);22        Log.action("Click: " + locator);
n31        WebElement element = WaitUtils.waitForClickability(locator);n23        // Convert By locator to CSS selector for Playwright
32        element.click();24        String selector = convertByToSelector(locator);
25        getPage().locator(selector).click();
33    }26    }
3427
n35    /**n28    // Migration: Replaced clear() + sendKeys() with Playwright fill() which han
 >dles both operations
36     * Type text into element
37     */
38    public static void type(By locator, String text) {29    public static void type(By locator, String text) {
39        String maskedText = maskSensitiveData(text);30        String maskedText = maskSensitiveData(text);
40        Log.action("Type '" + maskedText + "' into: " + locator);31        Log.action("Type '" + maskedText + "' into: " + locator);
n41        WebElement element = WaitUtils.waitForVisibility(locator);n32        String selector = convertByToSelector(locator);
42        element.clear();33        // Playwright's fill() automatically clears and types
43        element.sendKeys(text);34        getPage().locator(selector).fill(text);
44    }35    }
4536
n46    /**n37    // Migration: Replaced WebElement.getText() with Playwright locator.textCont
 >ent() - auto-waits for visibility
47     * Get text from element
48     */
49    public static String getText(By locator) {38    public static String getText(By locator) {
n50        WebElement element = WaitUtils.waitForVisibility(locator);n39        String selector = convertByToSelector(locator);
51        return element.getText();40        return getPage().locator(selector).textContent();
52    }41    }
5342
n54    /**n43    // Migration: Replaced WebElement.isDisplayed() with Playwright locator.isVi
 >sible()
55     * Check if element is displayed
56     */
57    public static boolean isDisplayed(By locator) {44    public static boolean isDisplayed(By locator) {
58        try {45        try {
n59            return getDriver().findElement(locator).isDisplayed();n46            String selector = convertByToSelector(locator);
47            return getPage().locator(selector).isVisible();
60        } catch (Exception e) {48        } catch (Exception e) {
61            return false;49            return false;
62        }50        }
63    }51    }
6452
n65    /**n53    // Migration: Replaced WebElement.isEnabled() with Playwright locator.isEnab
 >led()
66     * Check if element is enabled
67     */
68    public static boolean isEnabled(By locator) {54    public static boolean isEnabled(By locator) {
69        try {55        try {
nn56            String selector = convertByToSelector(locator);
70            return getDriver().findElement(locator).isEnabled();57            return getPage().locator(selector).isEnabled();
71        } catch (Exception e) {58        } catch (Exception e) {
72            return false;59            return false;
73        }60        }
74    }61    }
7562
n76    /**n63    // Migration: Replaced Selenium Select with Playwright selectOption() - auto
 >-waits for element
77     * Select option by visible text
78     */
79    public static void selectByText(By locator, String text) {64    public static void selectByText(By locator, String text) {
80        Log.action("Select '" + text + "' from: " + locator);65        Log.action("Select '" + text + "' from: " + locator);
n81        WebElement element = WaitUtils.waitForVisibility(locator);n66        String selector = convertByToSelector(locator);
82        new Select(element).selectByVisibleText(text);67        // Playwright selectOption by visible text
68        getPage().locator(selector).selectOption(new String[]{text});
83    }69    }
8470
n85    /**n71    // Migration: Replaced JavaScript scrollIntoView with Playwright scrollIntoV
 >iewIfNeeded()
86     * Scroll to element
87     */
88    public static void scrollToElement(By locator) {72    public static void scrollToElement(By locator) {
89        Log.action("Scroll to: " + locator);73        Log.action("Scroll to: " + locator);
n90        WebElement element = getDriver().findElement(locator);n74        String selector = convertByToSelector(locator);
91        ((JavascriptExecutor) getDriver()).executeScript("arguments[0].scrollInt75        getPage().locator(selector).scrollIntoViewIfNeeded();
>oView(true);", element); 
92    }76    }
9377
n94    /**n78    // Migration: Replaced Selenium Actions.moveToElement() with Playwright loca
 >tor.hover() - auto-waits
95     * Hover over element
96     */
97    public static void hover(By locator) {79    public static void hover(By locator) {
98        Log.action("Hover: " + locator);80        Log.action("Hover: " + locator);
n99        WebElement element = WaitUtils.waitForVisibility(locator);n81        String selector = convertByToSelector(locator);
100        new Actions(getDriver()).moveToElement(element).perform();82        getPage().locator(selector).hover();
101    }83    }
10284
n103    /**n85    // Migration: Replaced JavascriptExecutor with Playwright page.evaluate() fo
 >r JavaScript execution
104     * JavaScript click (for stubborn elements)
105     */
106    public static void jsClick(By locator) {86    public static void jsClick(By locator) {
107        Log.action("JS Click: " + locator);87        Log.action("JS Click: " + locator);
n108        WebElement element = getDriver().findElement(locator);n88        String selector = convertByToSelector(locator);
109        ((JavascriptExecutor) getDriver()).executeScript("arguments[0].click();"89        // Use Playwright's evaluate to perform JavaScript click
>, element); 
90        getPage().evaluate("document.querySelector('" + selector + "').click()")
 >;
110    }91    }
11192
n112    /**n93    // Migration: Utility method preserved as-is - no Playwright changes needed
113     * Mask sensitive data for logging
114     */
115    private static String maskSensitiveData(String text) {94    private static String maskSensitiveData(String text) {
116        if (text == null || text.length() <= 2) {95        if (text == null || text.length() <= 2) {
117            return "****";96            return "****";
118        }97        }
119        return text.substring(0, 2) + "****";98        return text.substring(0, 2) + "****";
120    }99    }
tt100 
101    // Migration: Helper method to convert Selenium By locators to Playwright se
 >lector strings
102    private static String convertByToSelector(By locator) {
103        String locatorString = locator.toString();
104        if (locatorString.startsWith("By.id: ")) {
105            return "#" + locatorString.substring(7);
106        } else if (locatorString.startsWith("By.className: ")) {
107            return "." + locatorString.substring(14);
108        } else if (locatorString.startsWith("By.cssSelector: ")) {
109            return locatorString.substring(16);
110        } else if (locatorString.startsWith("By.name: ")) {
111            return "[name='" + locatorString.substring(9) + "']";
112        } else if (locatorString.startsWith("By.tagName: ")) {
113            return locatorString.substring(12);
114        } else if (locatorString.startsWith("By.xpath: ")) {
115            return "xpath=" + locatorString.substring(10);
116        } else if (locatorString.startsWith("By.linkText: ")) {
117            // For link text, we'll use a more complex selector
118            String linkText = locatorString.substring(13);
119            return "a:has-text('" + linkText + "')";
120        } else if (locatorString.startsWith("By.partialLinkText: ")) {
121            String partialText = locatorString.substring(20);
122            return "a:has-text('" + partialText + "')";
123        }
124        // Fallback - return as xpath if we can't parse it
125        return "xpath=" + locatorString;
126    }
127 
121}128}
✓ Success
TestRunner.java D:\TestFlux\samples\selenium-java-project-bdd\src\test\java\com\qastarter\runners\TestRunner.java
21 → 21 lines
100%
0.1s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • None detected
Before → After

Original (Selenium)
Generated (Playwright)
t1package com.qastarter.runners;t1package com.qastarter.runners.playwright;
22
3import org.junit.platform.suite.api.ConfigurationParameter;3import org.junit.platform.suite.api.ConfigurationParameter;
4import org.junit.platform.suite.api.IncludeEngines;4import org.junit.platform.suite.api.IncludeEngines;
✓ Success
Hooks.java D:\TestFlux\samples\selenium-java-project-bdd\src\test\java\com\qastarter\stepdefinitions\Hooks.java
45 → 46 lines
100%
8.9s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • Cucumber_Scenario_Inject×2Keep io.cucumber.java.Scenario parameter injection unchanged. Scenario.attach() is the same in Cucumber 7+ regardless of underlying browser framework.
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.stepdefinitions;n1package com.qastarter.stepdefinitions.playwright;
22
n3import com.qastarter.core.DriverManager;n3import com.qastarter.core.playwright.DriverManager;
4import com.qastarter.utils.Log;4import com.qastarter.utils.playwright.Log;
5import com.qastarter.utils.ScreenshotUtils;5import com.qastarter.utils.playwright.ScreenshotUtils;
6import io.cucumber.java.After;6import io.cucumber.java.After;
7import io.cucumber.java.Before;7import io.cucumber.java.Before;
8import io.cucumber.java.Scenario;8import io.cucumber.java.Scenario;
99
n10/**n
11 * Cucumber Hooks - Setup and teardown for BDD scenarios.
12 */
13public class Hooks {10public class Hooks {
1411
nn12    // No explicit constructor needed - using default constructor
13 
14    // Migration: Preserved Cucumber @Before hook with Scenario injection. Drive
 >rManager.initializeDriver() now creates Playwright browser context instead of We
 >bDriver.
15    @Before15    @Before
16    public void setUp(Scenario scenario) {16    public void setUp(Scenario scenario) {
17        Log.info("==============================================================17        Log.info("==============================================================
>==================");>==================");
21        Log.info("Browser initialized for scenario");21        Log.info("Browser initialized for scenario");
22    }22    }
2323
nn24    // Migration: Preserved Cucumber @After hook with Scenario injection. Screen
 >shot capture now uses Playwright page.screenshot() instead of TakesScreenshot. S
 >cenario.attach() remains unchanged as it's Cucumber API.
24    @After25    @After
25    public void tearDown(Scenario scenario) {26    public void tearDown(Scenario scenario) {
26        try {27        try {
27            if (scenario.isFailed()) {28            if (scenario.isFailed()) {
28                Log.error("Scenario FAILED: " + scenario.getName());29                Log.error("Scenario FAILED: " + scenario.getName());
n29 n
30                if (DriverManager.isDriverInitialized()) {30                if (DriverManager.isDriverInitialized()) {
31                    byte[] screenshot = ScreenshotUtils.captureAsBytes();31                    byte[] screenshot = ScreenshotUtils.captureAsBytes();
32                    if (screenshot != null) {32                    if (screenshot != null) {
42            Log.info("Browser closed");42            Log.info("Browser closed");
43        }43        }
44    }44    }
tt45 
45}46}
✓ Success
LoginSteps.java D:\TestFlux\samples\selenium-java-project-bdd\src\test\java\com\qastarter\stepdefinitions\LoginSteps.java
57 → 61 lines
100%
13.0s ✓ Compiled
ℹ Compiled clean on first attempt.
Patterns handled
  • assertTrue×3Replace with Playwright expect assertions
  • Cucumber_Given×1Keep @Given annotation EXACTLY as-is. Only replace Selenium WebDriver API calls in the method body with Playwright Page API calls. Method signature is FROZEN.
  • Cucumber_When×2Keep @When annotation EXACTLY as-is. Only migrate WebDriver → Page inside the method body.
  • Cucumber_Then×2Keep @Then annotation EXACTLY as-is. Replace Selenium assertions with Playwright assertThat().
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.stepdefinitions;n1package com.qastarter.stepdefinitions.playwright;
22
n3import com.qastarter.config.ConfigurationReader;n3import com.qastarter.config.playwright.ConfigurationReader;
4import com.qastarter.core.DriverManager;4import com.qastarter.core.playwright.DriverManager;
5import com.qastarter.pages.LoginPage;5import com.qastarter.pages.playwright.LoginPage;
6import com.qastarter.utils.Log;6import com.qastarter.utils.playwright.Log;
7import io.cucumber.java.en.Given;7import io.cucumber.java.en.Given;
8import io.cucumber.java.en.When;8import io.cucumber.java.en.When;
9import io.cucumber.java.en.Then;9import io.cucumber.java.en.Then;
n10 n
11import static org.junit.jupiter.api.Assertions.*;10import static org.junit.jupiter.api.Assertions.*;
1211
n13/**n
14 * Step Definitions for Login Feature (BDD Style)
15 */
16public class LoginSteps {12public class LoginSteps {
1713
18    private LoginPage loginPage;14    private LoginPage loginPage;
1915
nn16    // No explicit constructor needed - using default constructor
17 
18    // Migration: Replaced driver.get() with page.navigate(), injected Page into
 > LoginPage constructor
20    @Given("I am on the login page")19    @Given("I am on the login page")
21    public void iAmOnTheLoginPage() {20    public void iAmOnTheLoginPage() {
22        Log.step("Opening login page");21        Log.step("Opening login page");
23        String baseUrl = ConfigurationReader.getBaseUrl();22        String baseUrl = ConfigurationReader.getBaseUrl();
n24        DriverManager.getDriver().get(baseUrl);n23        DriverManager.getDriver().navigate(baseUrl);
25        loginPage = new LoginPage();24        loginPage = new LoginPage(DriverManager.getDriver());
26        assertTrue(loginPage.isLoaded(), "Login page should be loaded");25        assertTrue(loginPage.isLoaded(), "Login page should be loaded");
27        Log.info("Login page loaded successfully");26        Log.info("Login page loaded successfully");
28    }27    }
2928
nn29    // Migration: No changes needed - business logic preserved
30    @When("I login with valid credentials")30    @When("I login with valid credentials")
31    public void iLoginWithValidCredentials() {31    public void iLoginWithValidCredentials() {
32        Log.step("Logging in with valid credentials from config");32        Log.step("Logging in with valid credentials from config");
35        loginPage.login(username, password);35        loginPage.login(username, password);
36    }36    }
3737
nn38    // Migration: No changes needed - business logic preserved
38    @When("I login with username {string} and password {string}")39    @When("I login with username {string} and password {string}")
39    public void iLoginWithUsernameAndPassword(String username, String password) 40    public void iLoginWithUsernameAndPassword(String username, String password) 
>{>{
40        Log.step("Logging in with username: " + username);41        Log.step("Logging in with username: " + username);
41        loginPage.login(username, password);42        loginPage.login(username, password);
42    }43    }
4344
nn45    // Migration: Kept JUnit assertTrue for boolean assertion from page object m
 >ethod
44    @Then("login should be successful")46    @Then("login should be successful")
45    public void loginShouldBeSuccessful() {47    public void loginShouldBeSuccessful() {
46        Log.step("Verifying login success");48        Log.step("Verifying login success");
48        Log.info("Login verified successfully");50        Log.info("Login verified successfully");
49    }51    }
5052
nn53    // Migration: Kept JUnit assertTrue for boolean assertion from page object m
 >ethod
51    @Then("I should see an error message")54    @Then("I should see an error message")
52    public void iShouldSeeAnErrorMessage() {55    public void iShouldSeeAnErrorMessage() {
53        Log.step("Verifying error message is displayed");56        Log.step("Verifying error message is displayed");
54        assertTrue(loginPage.isErrorDisplayed(), "Error message should be displa57        assertTrue(loginPage.isErrorDisplayed(), "Error message should be displa
>yed");>yed");
55        Log.info("Error message verified: " + loginPage.getErrorMessage());58        Log.info("Error message verified: " + loginPage.getErrorMessage());
56    }59    }
tt60 
57}61}
✓ Success
LoginTests.java D:\TestFlux\samples\selenium-java-project-bdd\src\test\java\com\qastarter\tests\LoginTests.java
53 → 54 lines
90%
12.4s ✓ Compiled 2 fix attempt(s)
ℹ Compiled after 2 fix attempt(s).
Patterns handled
  • assertTrue×2Replace with Playwright expect assertions
Before → After

Original (Selenium)
Generated (Playwright)
n1package com.qastarter.tests;n1package com.qastarter.tests.playwright;
22
n3import com.qastarter.config.ConfigurationReader;n3import com.qastarter.config.playwright.ConfigurationReader;
4import com.qastarter.core.BaseTest;4import com.qastarter.core.playwright.BaseTest;
5import com.qastarter.pages.LoginPage;5import com.qastarter.pages.playwright.LoginPage;
6import com.qastarter.utils.Log;6import com.qastarter.utils.playwright.Log;
7import org.junit.jupiter.api.DisplayName;7import org.junit.jupiter.api.DisplayName;
8import org.junit.jupiter.api.Order;8import org.junit.jupiter.api.Order;
9import org.junit.jupiter.api.Tag;9import org.junit.jupiter.api.Tag;
10import org.junit.jupiter.api.Test;10import org.junit.jupiter.api.Test;
n11import org.junit.jupiter.params.ParameterizedTest;n
12import org.junit.jupiter.params.provider.CsvFileSource;
13 
14import static org.junit.jupiter.api.Assertions.*;11import static org.junit.jupiter.api.Assertions.*;
1512
16/**13/**
n17* Login Tests - Example test class for SauceDemo.n14 * Login Tests - Example test class for SauceDemo.
18* Demonstrates both configuration-based and data-driven testing.15 * Demonstrates both configuration-based and data-driven testing.
16 * Migrated from Selenium to Playwright Java.
19*/17 */
20class LoginTests extends BaseTest {18class LoginTests extends BaseTest {
2119
n22@Testn20    // No explicit constructor needed - inheriting from BaseTest
23@Order(1)
24@Tag("smoke")
25@DisplayName("Verify successful login with valid credentials")
26void testValidLogin() {
27Log.step("Testing valid login");
28LoginPage loginPage = new LoginPage();
2921
nn22    // Migration: Migrated from Selenium WebDriver to Playwright Page. LoginPage
 > now uses constructor injection with Page object. Preserved JUnit 5 assertTrue f
 >or boolean return value.
23    @Test
24    @Order(1)
25    @Tag("smoke")
26    @DisplayName("Verify successful login with valid credentials")
27    void testValidLogin() {
28        Log.step("Testing valid login");
29        // Using Page constructor injection pattern for Playwright
30        LoginPage loginPage = new LoginPage(getDriver());
30String username = ConfigurationReader.getProperty("username");31        String username = ConfigurationReader.getProperty("username");
31String password = ConfigurationReader.getProperty("password");32        String password = ConfigurationReader.getProperty("password");
33        loginPage.login(username, password);
34        // Using JUnit 5 assertion - LoginPage.isLoginSuccessful() returns boole
 >an
35        assertTrue(loginPage.isLoginSuccessful(), "Login should be successful");
36        Log.info("Valid login test passed");
37    }
3238
t33loginPage.login(username, password);t39    // Migration: Migrated from Selenium WebDriver to Playwright Page. LoginPage
 > now uses constructor injection with Page object. Preserved JUnit 5 assertTrue f
 >or boolean return value.
34 40    @Test
35assertTrue(loginPage.isLoginSuccessful(), "Login should be successful");
36Log.info("Valid login test passed");
37}
38 
39@Test
40@Order(2)41    @Order(2)
41@Tag("regression")42    @Tag("regression")
42@DisplayName("Verify error message with invalid credentials")43    @DisplayName("Verify error message with invalid credentials")
43void testInvalidLogin() {44    void testInvalidLogin() {
44Log.step("Testing invalid login");45        Log.step("Testing invalid login");
46        // Using Page constructor injection pattern for Playwright
45LoginPage loginPage = new LoginPage();47        LoginPage loginPage = new LoginPage(getDriver());
46 
47loginPage.login("invalid_user", "wrong_password");48        loginPage.login("invalid_user", "wrong_password");
48 49        // Using JUnit 5 assertion - LoginPage.isErrorDisplayed() returns boolea
 >n
49assertTrue(loginPage.isErrorDisplayed(), "Error message should be displayed");50        assertTrue(loginPage.isErrorDisplayed(), "Error message should be displa
 >yed");
50Log.info("Invalid login test passed - error displayed as expected");51        Log.info("Invalid login test passed - error displayed as expected");
51}52    }
5253
53}54}