My Journey with Authenticate Once in Playwright Java

anushka singh
Naukri Engineering
Published in
3 min readSep 1, 2023

“Authenticate once” in playwright is an unexplored region, while we can find sources that explain the basic implementation and its benefits. Here we will explore how LORA (Login Once Reuse Anywhere) is implemented in a parallel testing framework along with the benefits and the drawbacks.

The blog is divided into the following parts:

  • Playwright Setup
  • Authenticate and Store
  • Use the stored cookies

Playwright Setup with multithreading

To start using Playwright,

Create a maven project and add the playwright dependency in the pom.xml of our project

<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.36.0</version>
</dependency>

Now we will start using Playwright. I will explain the code on the most basic level and the same would be implemented along with getter, setter, and Threadlocal.

Playwright.create() — Initializes the playwright server

Playwright.chromium().launch() -Initializes the Chromium browser, you can change the method to launch respective browsers.

Browser.newContext - Initializes a window in the browser. At this stage, we can set browser properties like cookies, test case recording, etc.

Context. newPage() - Initializes a new tab in Playwright

NOTE: setStorageStatePath(Paths.get(login_user) is used to set the authentication in the browser context, we will deep dive into the login_user variable further.

  public class PlaywrightFactory 
{
private static ThreadLocal<Browser> tlBrowser = new ThreadLocal<>();
private static ThreadLocal<BrowserContext> tlBrowserContext = new ThreadLocal<>();
private static ThreadLocal<Page> tlPage = new ThreadLocal<>();
private static ThreadLocal<Playwright> tlPlaywright = new ThreadLocal<>();
NewContextOptions newContextOptions;
public static Browser getBrowser(){
return tlBrowser.get();
}

public static BrowserContext getBrowserContext(){
return tlBrowserContext.get();
}

public static void setBrowserContext(BrowserContext context) {
tlBrowserContext.set(context);
}

public static Page getPage(){
return tlPage.get();
}

public static void setPage(Page page) {
tlPage.set(page);
}

public static Playwright getPlaywright(){
return tlPlaywright.get();
}

public void initBrowser(String login_user){
tlPlaywright.set(Playwright.create());
tlBrowser.set( getPlaywright().chromium().launch());
if(loginuser!=null)
tlBrowserContext.set(getBrowser().newContext(
new Browser.NewContextOptions().setStorageStatePath(Paths.get(login_user))));
else
tlBrowserContext.set(getBrowser().newContext(new Browser.NewContextOptions())));
tlPage.set(getBrowserContext().newPage());

}
}

Now that you are all set with the playwright initialization. Let’s start with the next step

Authenticate and Store

The below example is for two different user logins, you can use the same for any number of users.

context.storageState method will retrieve the Auth Cookies from the browser and store them into a JSON file.

You can set the path of the JSON file using the set path method.

public class SingleLogin {

PlaywrightFactory playwrightFactory = new PlaywrightFactory();

public void loginBeforeSuite() {
loginNStore("username1","Password1","username1.json");
loginNStore("username2","Password2","username2.json");
}

public void loginNStore(String username, String password, String filename) {

playwrightFactory.initBrowser(null);
page=playwrightFactory.getPage();

//Code to login into a website

context=playwrightFactory.getBrowserContext();
context.storageState(new BrowserContext.StorageStateOptions()
.setPath(Paths.get(filename+".json")));
context.close();
}
}

In the loginNStore method, we are closing the used browser Context and creating a new one to maintain the sanity of the Authentication cookies.

Since the above method needs to be executed only once in a test suite lifetime, we will use @BeforeSuite testNG Annotation to invoke the LoginBeforeSuite method.

public class BaseTest {

String TestName;
SingleLogin singlelogin;

@BeforeSuite
public void setup(){
singlelogin = new SingleLogin();
singlelogin.loginBeforeSuite();
}
}

Use the stored cookies

Create a class where you want to use the auth cookies and implement the following code

import java.lang.reflect.Method;

public class DemoTest extends BaseTest{

String TestName;
PlaywrightFactory playwrightFactory;
String Loginconfig = "your_config.properties";

@BeforeMethod
void createContextAndPage(Method method) {
playwrightFactory = new PlaywrightFactory();
TestName=method.getName();
String loginuser=ReadWritePropertyFile.getProperty(TestName, Loginconfig);
playwrightFactory.initBrowser(playwrightFactory.initProp(), loginuser);
}

@AfterMethod
public void CloseContext() {
CloseContext(playwrightFactory.getBrowserContext());
}

java.lang.reflect.Method class provides the name of the method that has invoked the @beforeMethod. Which can be used to get the UserName that a test case requires.

Here I have used the Properties file to store test_name and username in a key-value pair format, we can use Excel or Databases to store the same as per the requirement.

Therefore loginuser contains the name of the JSON file i.e. either username1.json or username2.json, which then will be passed to the initBrowser method of PlaywrightFactory, resulting in the launch of an authenticated browser.

Perks of this feature:

I believe, will be stating the obvious here still let’s go,

  1. Time Saving: The feature is a guaranteed way to reduce the overall execution time significantly while maintaining the execution of testcases in complete isolation.
  2. Efficiency: It increases the efficiency by eliminating the repeated steps of login while enhancing the readability of testcases as well.

Drawbacks of implementing this feature:

As promised, will be enlisting the issues I faced after implementing the framework.

  1. If the login fails once, the whole test suite will fail.
  2. Relogin scenarios cannot be covered with this feature, If any of the browsers log out, the Auth cookies will expire leading to failure of the remaining test cases.

We were all aware of the perks and now we are also equipped with the detriments. Analyze the needs of your project, and choose wisely.

I hope this blog was helpful.

--

--