The evaluate() method in Playwright for Java provides a mechanism to execute JavaScript code within the context of a web page. It allows us to interact with the Document Object Model (DOM) and manipulate elements, retrieve data, and perform complex operations that go beyond the built-in functions of Playwright. This post will delve into the depths of the evaluate() method and discuss it in detail.
Page interface provides two overloaded evaluate() methods –
- default Object evaluate(String expression)
- Object evaluate(String expression, Object arg)
One method accepts only one argument, whereas the second method accepts two arguments.
Passing only a single argument in the evaluate() method
The evaluate() method can execute Javascript code on its own. We can pass the code as an argument to the evaluate() method for execution.
Let’s take a simple Javascript code that prints some value on the browser console.
console.log('Playwright Tutorial')
The code above will display “Playwright Tutorial” on the browser console. To execute this code with Playwright, we can use the evaluate() method and pass the script as an argument, as demonstrated below.
// executing Javascript code
page.evaluate("console.log('Playwright Tutorial')");
To view the message on the browser console, simply open up a browser, navigate to any URL, and use the evaluate() method.
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// opening the browser
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
// executing Javascript code
page.evaluate("console.log('Playwright Tutorial')");
// not closing the browser, so we can visualize the message printed in the console.
}
}
Note: We chose not to open the browser in headless mode so that we could visually confirm the message printed on the browser. As a result, we did not use the “browser.close()” command to close the browser at the end of the program.
Run the above code and check the message printed on the browser’s console.
How to open the browser console?
- Right-click on the webpage.
- Select the Inspect option.
- This will open the browser’s developer tools, where we can see the console tab.
We can see the message printed in the console, and this is how we can easily execute the javascript code in Playwright. But the story doesn’t end here, there is more to the evaluate() method which we are going to discuss in the next section.
Passing two arguments in the evaluate() method
evaluate() method also accepts two arguments – one is the javascript code itself, and the second is an object.
What will be the need to pass a second argument?
While the primary argument of the evaluate() method is the JavaScript code itself, there are scenarios where you may need to pass a second argument to provide additional data or context for your script.
Transferring Data
At times, it may be necessary to transfer data from our program to the evaluated Javascript code. This can be accomplished by passing the data as the second argument to the evaluate() method.
Context sharing
It may happen that you’ll end up executing multiple Javascript codes throughout the program. So, if you want the result of one JS code to be passed to another, then you can do that by passing the context as the second argument to the evaluate() method.
Javascript function arguments
If your evaluated JavaScript code is defined as a function, you can pass arguments to that function by providing them as the second argument in the evaluate() method. This allows you to pass dynamic values or parameters to the JavaScript function for processing within the page context.
What type of parameters is accepted as the second argument to the evaluate() method?
There are different types of parameters that one can pass in the evaluate() method. Some of them are listed below
Let’s look at them one by one with examples.
int, double, boolean and String
We can pass int, double, boolean, and String as the second argument to the evaluate() method. Afterwards, we can use the parameters within the Javascript code to perform any desired action.
// passing integer
page.evaluate("value => console.log(value)", 100);
// passing double
page.evaluate("value => console.log(value)", 100.29);
// passing boolean
page.evaluate("value => console.log(value)", true);
// passing string
page.evaluate("value => console.log(value)", "Codekru Playwright tutorial");
In the above lines of code, we have passed the parameters and then printed the values on the browser console.
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// opening up the browser so that we can see the console message printed on the
// browser
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
// passing integer
page.evaluate("value => console.log(value)", 100);
// passing double
page.evaluate("value => console.log(value)", 100.29);
// passing boolean
page.evaluate("value => console.log(value)", true);
// passing string
page.evaluate("value => console.log(value)", "Codekru Playwright tutorial");
// not closing the browser, so we can observe the message printed in the console.
}
}
Run the above code and open the browser’s console tab to see the values printed by the code.
We can see that the values are printed on the browser’s console, and this is how we can transfer the data to the Javascript code and use it in our script.
JSON-serializable Objects
A JSON-serializable object refers to an object that can be converted into a JSON (JavaScript Object Notation) format. We can utilize these objects as an argument for the evaluate() method. Here are some examples of such objects.
- Map
- List
- Set
- Wrapper classes
We can directly pass these objects as an argument and use them in the JS code.
Map<String, Object> map = new HashMap<>();
map.put("name", "Codekru");
map.put("tutorial", "Playwright");
// passing map
page.evaluate("data => console.log('Website name:',data.name)", map); // accessing map as a JSON object with JS code
List<String> list = new ArrayList<>();
list.add("Codekru");
list.add("Playwright");
list.add("Tutorial");
// passing list
page.evaluate("data => console.log('List size:',data.length)", list);
Let’s see things in action.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// opening up the browser so that we can see the console message printed on the
// browser
Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
Map<String, Object> map = new HashMap<>();
map.put("name", "Codekru");
map.put("tutorial", "Playwright");
// passing map
page.evaluate("data => console.log('Website name:',data.name)", map);
List<String> list = new ArrayList<>();
list.add("Codekru");
list.add("Playwright");
list.add("Tutorial");
// passing list
page.evaluate("data => console.log('List size:',data.length)", list);
// not closing the browser, so we can observe the message printed in the console.
}
}
Run the above code and observe the values printed on the browser console.
Note: We cannot pass Playwright’s Locator directly as an argument because it isn’t a JSON-serializable object. However, there are some alternative approaches that can help us achieve similar functionality.
We’ve discussed the types of arguments that can be passed, and now let’s explore the possible return types from the evaluate() method.
Return types of evaluate() method
According to the declaration, the evaluate() method returns an Object. In Java, Object is a root class that can be type casted to a desired data type. It is important to ensure that the data type returned by evaluate() method script can be type casted to the desired Java data type.
Object evaluate(String expression, Object arg);
Some of the types returned by the evaluate() method are –
Let’s look at each of them one by one.
int, double, boolean and String
JavaScript primitives such as string
, number
, boolean
, null
, and undefined
are converted to their corresponding Java counterparts (String
, Double
, Boolean
, null
, and null
, respectively). Therefore, if a number value is returned from the evaluate() function, it can easily be converted to a Double object in Java code.
String script = "100.29";
Object result = page.evaluate(script); // Returns a Double
Double numberResult = (Double) result;
System.out.println("Number Result: " + numberResult); // Output: 100.29
script = "'Playwright Tutorial'";
result = page.evaluate(script); // Returns a String
String stringResult = (String) result;
System.out.println("String Result: " + stringResult); // Output: Playwright Tutorial
script = "true";
result = page.evaluate(script); // Returns a Boolean
Boolean booleanResult = (Boolean) result;
System.out.println("Boolean Result: " + booleanResult); // Output: true
Let’s see things in action with a working code example
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// Launching the browser
Browser browser = playwright.chromium().launch();
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
String script = "100.29";
Object result = page.evaluate(script); // Returns a Double
Double numberResult = (Double) result;
System.out.println("Number Result: " + numberResult); // Output: 100.29
script = "'Playwright Tutorial'";
result = page.evaluate(script); // Returns a String
String stringResult = (String) result;
System.out.println("String Result: " + stringResult); // Output: Playwright Tutorial
script = "true";
result = page.evaluate(script); // Returns a Boolean
Boolean booleanResult = (Boolean) result;
System.out.println("Boolean Result: " + booleanResult); // Output: true
// closing the instances
browser.close();
playwright.close();
}
}
Output –
Number Result: 100.29
String Result: Playwright Tutorial
Boolean Result: true
Corresponding values have been printed in the output.
List
If Javascript returns an array, it can be converted to a Java List of objects ( List<Object> ). We can then iterate over the list and perform desired operations.
String script = "[10, 20, 30, 40, 50]";
List<Object> result = (List<Object>) page.evaluate(script); // Returns an Object[]
for (Object item : result) {
System.out.println("List Item: " + item);
}
If we are certain about the data type of the elements in the array, we can also typecast the List with a specific type.
String script = "[10, 20, 30, 40, 50]";
List<Integer> result = (List<Integer>) page.evaluate(script); // Returns an Object[]
for (Integer item : result) {
System.out.println("List Item: " + item);
}
We converted the JavaScript array to a list of integers since we were aware that the array only consisted of integers.
import java.util.List;
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// Launching the browser
Browser browser = playwright.chromium().launch();
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
String script = "[10, 20, 30, 40, 50]";
List<Integer> result = (List<Integer>) page.evaluate(script); // Returns an Object[]
for (Integer item : result) {
System.out.println("List Item: " + item);
}
// closing the instances
browser.close();
playwright.close();
}
}
Output –
List Item: 10
List Item: 20
List Item: 30
List Item: 40
List Item: 50
Promises
If the JavaScript code returns a Promise, the page.evaluate() method will wait for the Promise to resolve, and the resolved value will be returned.
String script = "new Promise(resolve => setTimeout(() => resolve('Delayed result'), 2000))";
Object result = page.evaluate(script); // Returns a Promise
Below is the whole code.
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
public class CodekruTest {
public static void main(String[] args) {
Playwright playwright = Playwright.create();
// Launching the browser
Browser browser = playwright.chromium().launch();
// creating a BrowserContext
BrowserContext browserContext = browser.newContext();
// creating the page
Page page = browserContext.newPage();
// Navigating to the URL
page.navigate("https://testkru.com/Elements/TextFields");
String script = "new Promise(resolve => setTimeout(() => resolve('Codekru Website'), 2000))";
Object result = page.evaluate(script); // Returns a Promise
System.out.println("Promise Result: " + result); // Output: Codekru Website
// closing the instances
browser.close();
playwright.close();
}
}
Output –
Promise Result: Codekru Website
The result of Promise can be converted to the type that the JavaScript code returns.
We hope that you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at admin@codekru.com.