Skip to content

Commit fea43a6

Browse files
Added resource cleanups for Browser Management.
1 parent f6d7d39 commit fea43a6

3 files changed

Lines changed: 80 additions & 20 deletions

File tree

src/main/java/io/swaglabs/portal/qa/browsermanager/BrowserFactory.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@
22

33
import io.swaglabs.portal.qa.constants.WebPortalConstants;
44

5+
import java.util.HashMap;
6+
import java.util.Map;
7+
58
public class BrowserFactory {
69

10+
ThreadLocal<Map<String, IBrowser>> BROWWSER_CACHE = ThreadLocal.withInitial(HashMap::new);
11+
712
public IBrowser createBrowser() {
8-
return switch (BrowserName.fromConfigValue(WebPortalConstants.BROWSER)) {
9-
case CHROME -> new ChromeBrowser();
10-
case EDGE -> new EdgeBrowser();
11-
case FIREFOX -> new FirefoxBrowser();
12-
case WEBKIT -> new WebkitBrowser();
13-
};
13+
String browserName = WebPortalConstants.BROWSER;
14+
return BROWWSER_CACHE.get().computeIfAbsent(browserName, name ->
15+
switch (BrowserName.fromConfigValue(browserName)) {
16+
case CHROME -> new ChromeBrowser();
17+
case EDGE -> new EdgeBrowser();
18+
case FIREFOX -> new FirefoxBrowser();
19+
case WEBKIT -> new WebkitBrowser();
20+
21+
});
1422
}
1523
}
Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,58 @@
11
package io.swaglabs.portal.qa.browsermanager;
22

3+
import com.microsoft.playwright.Browser;
34
import com.microsoft.playwright.BrowserContext;
45
import com.microsoft.playwright.Page;
56
import com.microsoft.playwright.Playwright;
67
import io.swaglabs.portal.qa.constants.WebPortalConstants;
8+
import io.swaglabs.portal.qa.exceptions.WebUtilsException;
9+
import lombok.extern.slf4j.Slf4j;
710

811
import java.util.Objects;
912

13+
@Slf4j
1014
public class BrowserManager implements IBrowserManager<Page> {
1115

16+
private static final ThreadLocal<BrowserContext> BROWSER_CONTEXT = new ThreadLocal<>();
17+
private static final ThreadLocal<Browser> BROWSER = new ThreadLocal<>();
18+
1219
@Override
1320
public Page getBrowserPage(Playwright playwright) {
14-
Objects.requireNonNull(playwright, "Playwright instance is null in Browser Manager!");
15-
boolean isHeadless = "headless".equals(WebPortalConstants.RUN_MODE);
16-
BrowserContext browserContext = new BrowserFactory().createBrowser().createSession(playwright, isHeadless);
17-
Objects.requireNonNull(browserContext, "Playwright Browser Context is null!");
18-
return browserContext.newPage();
21+
try {
22+
Objects.requireNonNull(playwright, "Playwright instance is null in Browser Manager!");
23+
boolean isHeadless = "headless".equals(WebPortalConstants.RUN_MODE);
24+
BrowserContext browserContext = new BrowserFactory().createBrowser().createSession(playwright, isHeadless);
25+
BROWSER_CONTEXT.set(browserContext);
26+
if (browserContext.browser() != null)
27+
BROWSER.set(browserContext.browser());
28+
return browserContext.newPage();
29+
} catch (Exception e) {
30+
log.error("Browser initialization failed.");
31+
cleanUp();
32+
throw new WebUtilsException("Failed to create browser page: " + e);
33+
}
1934
}
2035

2136
@Override
2237
public void destroyBrowserPage(Page page) {
23-
Objects.requireNonNull(page, "Playwright Browser is null!");
24-
page.close();
38+
try {
39+
if (page != null)
40+
page.close();
41+
} finally {
42+
cleanUp();
43+
}
44+
}
45+
46+
private void cleanUp() {
47+
BrowserContext browserContext = BROWSER_CONTEXT.get();
48+
if (browserContext != null) {
49+
browserContext.close();
50+
BROWSER_CONTEXT.remove();
51+
}
52+
Browser browser = BROWSER.get();
53+
if (browser != null) {
54+
browser.close();
55+
BROWSER.remove();
56+
}
2557
}
2658
}

src/test/java/io/swaglabs/portal/qa/testcases/SwagLabsTestBase.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,37 @@ public sealed class SwagLabsTestBase extends WebBaseTest permits SwagLabsE2ETest
1616

1717
@BeforeMethod(alwaysRun = true)
1818
public void setUpSwagLabsPortal(Method method) {
19-
log.info("Thread id in BeforeMethod for the test method : {} is {}.", method.getName(), Thread.currentThread().getId());
20-
SWAG_LABS_PORTAL.set(new SwagLabsPortal(page.get()));
21-
SWAG_LABS_PORTAL.get().visit();
22-
boolean isLoggedIn = SWAG_LABS_PORTAL.get().LOGIN_PAGE.isLoginSuccess();
23-
if (!isLoggedIn)
24-
throw new WebPageException("Swags Labs Portal Not Logged In!");
19+
final long threadId = Thread.currentThread().getId();
20+
log.info("Thread {} starting method {}", threadId, method.getName());
21+
try {
22+
// 1. Initialize portal (thread-safe via ThreadLocal)
23+
SWAG_LABS_PORTAL.set(new SwagLabsPortal(page.get()));
24+
// 2. Visit and login
25+
SWAG_LABS_PORTAL.get().visit();
26+
boolean isLoggedIn = SWAG_LABS_PORTAL.get().LOGIN_PAGE.isLoginSuccess();
27+
if (!isLoggedIn)
28+
throw new WebPageException("Swags Labs Portal Not Logged In!");
29+
} catch (Exception e) {
30+
log.error("Initialization failed for thread {}", threadId, e);
31+
cleanUpResources();
32+
throw e;
33+
}
2534
}
2635

2736
@AfterMethod(alwaysRun = true)
2837
public void tearDownSwagLabsPortal(Method method) {
29-
log.info("Thread id in AfterMethod for the test method :{} is {}.", method.getName(), Thread.currentThread().getId());
38+
final long threadId = Thread.currentThread().getId();
39+
log.info("Thread {} finishing method {}", threadId, method.getName());
3040
SWAG_LABS_PORTAL.remove();
3141
}
42+
43+
private void cleanUpResources() {
44+
try {
45+
if (SWAG_LABS_PORTAL.get() != null)
46+
// Simple cleanup - just remove the ThreadLocal
47+
SWAG_LABS_PORTAL.remove();
48+
} catch (Exception e) {
49+
log.error("Thread {} cleanup error", Thread.currentThread().getId(), e);
50+
}
51+
}
3252
}

0 commit comments

Comments
 (0)