UI Testing with Puppeteer by Dario Kondratiuk
Author:Dario Kondratiuk
Language: eng
Format: epub
Publisher: Packt Publishing
Published: 2021-03-10T00:00:00+00:00
Variable scopes in Puppeteer
As you can see, the name didn't get to the alert. For us as developers, the big issue is that the code looks good. If you look at the code, the code is perfect. It's not very different from our previous examples. But something works differently there. Once you understand this, you will be able to answer lots of questions on Stack Overflow.
First, the signature of page.evaluate is page.evaluate(pageFunction[, ...args]), where pageFunction can be a string or a function. The second argument is an optional list of values to pass to pageFunction.
You can pass expressions as strings to the evaluate function. An expression is a statement like the ones you can write inside the DevTools console. For instance, a simple string returning the URL property of the document object:
console.log(await page.evaluate('document.URL'));
page.evaluate will send the expression document.URL to the browser and the browser will evaluate it. Once the browser evaluates the expression, it will send that back to Puppeteer, and page.evaluate will return the result. In this case, about:blank.
Expressions are perfect when you want to evaluate simple expressions. But you could accomplish the same result using a JavaScript function:
console.log(await page.evaluate(() => document.URL));
As you can see, passing an expression is more straightforward, but you will be able to write more complex code using functions, and, no less important, you will get the autocomplete features of your code editor.
The key concept here is that page.evaluate will send the expression to the browser. How can Puppeteer send a function to the browser? It will serialize it. As I mentioned before, functions are first-class citizens in JavaScript, which means that you can call toString() to function inside a variable. Let's try that out:
console.log((() => alert('Hello ' + name)).toString());
This will print the function as a string value in the console:
() => alert('Hello ' + name)
If Puppeteer takes that function, converts it to a string using toString, and sends it to the browser, the value of the name variable will be lost in the process.
When you send a function to be evaluated inside the browser context, you need to make sure that all the values the function uses are already in the browser or are being passed as an argument. This is how we can fix our code:
const browser = await puppeteer.launch({headless: false, defaultViewport: null});
const page = await browser.newPage();
const name = 'world';
await page.evaluate((n) => alert('Hello ' + n), name);
browser.close();
As we can see, we are passing the name variable as part of the args argument of evaluate. Now Puppeteer knows that it has to serialize that function and also send args. The browser will now be able to execute that function, passing those arguments.
Tip
Notice that I renamed the variable name to n. It's not required, but this practice will help you avoid these kinds of scope mistakes. Now you, and your IDE, know that the n variable being used in the alert function is an argument being passed to that function.
This evaluate function is available not only in the page and frame classes but also in the JSHandle and ElementHandle classes.
Download
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.
Exploring Deepfakes by Bryan Lyon and Matt Tora(7709)
Robo-Advisor with Python by Aki Ranin(7607)
Offensive Shellcode from Scratch by Rishalin Pillay(6095)
Microsoft 365 and SharePoint Online Cookbook by Gaurav Mahajan Sudeep Ghatak Nate Chamberlain Scott Brewster(5003)
Ego Is the Enemy by Ryan Holiday(4956)
Management Strategies for the Cloud Revolution: How Cloud Computing Is Transforming Business and Why You Can't Afford to Be Left Behind by Charles Babcock(4438)
Python for ArcGIS Pro by Silas Toms Bill Parker(4173)
Elevating React Web Development with Gatsby by Samuel Larsen-Disney(3876)
Machine Learning at Scale with H2O by Gregory Keys | David Whiting(3612)
Learning C# by Developing Games with Unity 2021 by Harrison Ferrone(3284)
Speed Up Your Python with Rust by Maxwell Flitton(3231)
Liar's Poker by Michael Lewis(3220)
OPNsense Beginner to Professional by Julio Cesar Bueno de Camargo(3195)
Extreme DAX by Michiel Rozema & Henk Vlootman(3169)
Agile Security Operations by Hinne Hettema(3122)
Linux Command Line and Shell Scripting Techniques by Vedran Dakic and Jasmin Redzepagic(3108)
Essential Cryptography for JavaScript Developers by Alessandro Segala(3081)
Cryptography Algorithms by Massimo Bertaccini(3001)
AI-Powered Commerce by Andy Pandharikar & Frederik Bussler(2981)
