How to use EvaluateExpressionAsync method of PuppeteerSharp.Frame class

Best Puppeteer-sharp code snippet using PuppeteerSharp.Frame.EvaluateExpressionAsync

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Methods.cs

Source: Methods.cs Github

copy
1using PuppeteerSharp;
2using RuriLib.Attributes;
3using RuriLib.Functions.Files;
4using RuriLib.Functions.Puppeteer;
5using RuriLib.Logging;
6using RuriLib.Models.Bots;
7using System;
8using System.Collections.Generic;
9using System.Linq;
10using System.Threading.Tasks;
11
12namespace RuriLib.Blocks.Puppeteer.Elements
13{
14    [BlockCategory("Elements", "Blocks for interacting with elements on a puppeteer browser page", "#e9967a")]
15    public static class Methods
16    {
17        [Block("Sets the value of the specified attribute of an element", name = "Set Attribute Value")]
18        public static async Task PuppeteerSetAttributeValue(BotData data, FindElementBy findBy, string identifier, int index,
19            string attributeName, string value)
20        {
21            data.Logger.LogHeader();
22
23            var elemScript = GetElementScript(findBy, identifier, index);
24            var frame = GetFrame(data);
25            var script = elemScript + $".setAttribute('{attributeName}', '{value}');";
26            await frame.EvaluateExpressionAsync(script);
27
28            data.Logger.Log($"Set value {value} of attribute {attributeName} by executing {script}", LogColors.DarkSalmon);
29        }
30
31        [Block("Types text in an input field", name = "Type")]
32        public static async Task PuppeteerTypeElement(BotData data, FindElementBy findBy, string identifier, int index,
33            string text, int timeBetweenKeystrokes = 0)
34        {
35            data.Logger.LogHeader();
36
37            var frame = GetFrame(data);
38            var elem = await GetElement(frame, findBy, identifier, index);
39            await elem.TypeAsync(text, new PuppeteerSharp.Input.TypeOptions { Delay = timeBetweenKeystrokes });
40
41            data.Logger.Log($"Typed {text}", LogColors.DarkSalmon);
42        }
43
44        [Block("Types text in an input field with human-like random delays", name = "Type Human")]
45        public static async Task PuppeteerTypeElementHuman(BotData data, FindElementBy findBy, string identifier, int index,
46            string text)
47        {
48            data.Logger.LogHeader();
49
50            var frame = GetFrame(data);
51            var elem = await GetElement(frame, findBy, identifier, index);
52
53            foreach (var c in text)
54            {
55                await elem.TypeAsync(c.ToString());
56                await Task.Delay(data.Random.Next(100, 300)); // Wait between 100 and 300 ms (average human type speed is 60 WPM ~ 360 CPM)
57            }
58
59            data.Logger.Log($"Typed {text}", LogColors.DarkSalmon);
60        }
61
62        [Block("Clicks an element", name = "Click")]
63        public static async Task PuppeteerClick(BotData data, FindElementBy findBy, string identifier, int index,
64            PuppeteerSharp.Input.MouseButton mouseButton = PuppeteerSharp.Input.MouseButton.Left, int clickCount = 1,
65            int timeBetweenClicks = 0)
66        {
67            data.Logger.LogHeader();
68
69            var frame = GetFrame(data);
70            var elem = await GetElement(frame, findBy, identifier, index);
71            await elem.ClickAsync(new PuppeteerSharp.Input.ClickOptions { Button = mouseButton, ClickCount = clickCount, Delay = timeBetweenClicks });
72
73            data.Logger.Log($"Clicked {clickCount} time(s) with {mouseButton} button", LogColors.DarkSalmon);
74        }
75
76        [Block("Submits a form", name = "Submit")]
77        public static async Task PuppeteerSubmit(BotData data, FindElementBy findBy, string identifier, int index)
78        {
79            data.Logger.LogHeader();
80
81            var elemScript = GetElementScript(findBy, identifier, index);
82            var frame = GetFrame(data);
83            var script = elemScript + ".submit();";
84            await frame.EvaluateExpressionAsync(script);
85
86            data.Logger.Log($"Submitted the form by executing {script}", LogColors.DarkSalmon);
87        }
88
89        [Block("Selects a value in a select element", name = "Select")]
90        public static async Task PuppeteerSelect(BotData data, FindElementBy findBy, string identifier, int index, string value)
91        {
92            data.Logger.LogHeader();
93
94            var frame = GetFrame(data);
95            var elem = await GetElement(frame, findBy, identifier, index);
96            await elem.SelectAsync(value);
97
98            data.Logger.Log($"Selected value {value}", LogColors.DarkSalmon);
99        }
100
101        [Block("Selects a value by index in a select element", name = "Select by Index")]
102        public static async Task PuppeteerSelectByIndex(BotData data, FindElementBy findBy, string identifier, int index, int selectionIndex)
103        {
104            data.Logger.LogHeader();
105
106            var frame = GetFrame(data);
107            var elemScript = GetElementScript(findBy, identifier, index);
108            var script = elemScript + $".getElementsByTagName('option')[{selectionIndex}].value;";
109            var value = (await frame.EvaluateExpressionAsync(script)).ToString();
110
111            var elem = await GetElement(frame, findBy, identifier, index);
112            await elem.SelectAsync(value);
113
114            data.Logger.Log($"Selected value {value}", LogColors.DarkSalmon);
115        }
116
117        [Block("Selects a value by text in a select element", name = "Select by Text")]
118        public static async Task PuppeteerSelectByText(BotData data, FindElementBy findBy, string identifier, int index, string text)
119        {
120            data.Logger.LogHeader();
121
122            var frame = GetFrame(data);
123            var elemScript = GetElementScript(findBy, identifier, index);
124            var script = $"el={elemScript};for(let i=0;i<el.options.length;i++){{if(el.options[i].text=='{text}'){{el.selectedIndex = i;break;}}}}";
125            await frame.EvaluateExpressionAsync(script);
126
127            data.Logger.Log($"Selected text {text}", LogColors.DarkSalmon);
128        }
129
130        [Block("Gets the value of an attribute of an element", name = "Get Attribute Value")]
131        public static async Task<string> PuppeteerGetAttributeValue(BotData data, FindElementBy findBy, string identifier, int index,
132            string attributeName = "innerText")
133        {
134            data.Logger.LogHeader();
135
136            var elemScript = GetElementScript(findBy, identifier, index);
137            var frame = GetFrame(data);
138            var script = $"{elemScript}.{attributeName};";
139            var value = await frame.EvaluateExpressionAsync<string>(script);
140
141            data.Logger.Log($"Got value {value} of attribute {attributeName} by executing {script}", LogColors.DarkSalmon);
142            return value;
143        }
144
145        [Block("Gets the values of an attribute of multiple elements", name = "Get Attribute Value All")]
146        public static async Task<List<string>> PuppeteerGetAttributeValueAll(BotData data, FindElementBy findBy, string identifier,
147            string attributeName = "innerText")
148        {
149            data.Logger.LogHeader();
150
151            var elemScript = GetElementsScript(findBy, identifier);
152            var frame = GetFrame(data);
153            var script = $"Array.prototype.slice.call({elemScript}).map((item) => item.{attributeName})";
154            var values = await frame.EvaluateExpressionAsync<string[]>(script);
155
156            data.Logger.Log($"Got {values.Length} values for attribute {attributeName} by executing {script}", LogColors.DarkSalmon);
157            return values.ToList();
158        }
159
160        [Block("Checks if an element is currently being displayed on the page", name = "Is Displayed")]
161        public static async Task<bool> PuppeteerIsDisplayed(BotData data, FindElementBy findBy, string identifier, int index)
162        {
163            data.Logger.LogHeader();
164
165            var elemScript = GetElementScript(findBy, identifier, index);
166            var frame = GetFrame(data);
167            var script = $"window.getComputedStyle({elemScript}).display !== 'none';";
168            var displayed = await frame.EvaluateExpressionAsync<bool>(script);
169
170            data.Logger.Log($"Found out the element is{(displayed ? "" : " not")} displayed by executing {script}", LogColors.DarkSalmon);
171            return displayed;
172        }
173
174        [Block("Checks if an element exists on the page", name = "Exists")]
175        public static async Task<bool> PuppeteerExists(BotData data, FindElementBy findBy, string identifier, int index)
176        {
177            data.Logger.LogHeader();
178
179            var elemScript = GetElementScript(findBy, identifier, index);
180            var frame = GetFrame(data);
181            var script = $"window.getComputedStyle({elemScript}).display !== 'none';";
182
183            try
184            {
185                var displayed = await frame.EvaluateExpressionAsync<bool>(script);
186                data.Logger.Log("The element exists", LogColors.DarkSalmon);
187                return true;
188            }
189            catch
190            {
191                data.Logger.Log("The element does not exist", LogColors.DarkSalmon);
192                return false;
193            }
194        }
195
196        [Block("Uploads one or more files to the selected element", name = "Upload Files")]
197        public static async Task PuppeteerUploadFiles(BotData data, FindElementBy findBy, string identifier, int index, List<string> filePaths)
198        {
199            data.Logger.LogHeader();
200
201            var frame = GetFrame(data);
202            var elem = await GetElement(frame, findBy, identifier, index);
203            await elem.UploadFileAsync(filePaths.ToArray());
204
205            data.Logger.Log($"Uploaded {filePaths.Count} files to the element", LogColors.DarkSalmon);
206        }
207
208        [Block("Gets the X coordinate of the element in pixels", name = "Get Position X")]
209        public static async Task<int> PuppeteerGetPositionX(BotData data, FindElementBy findBy, string identifier, int index)
210        {
211            data.Logger.LogHeader();
212
213            var frame = GetFrame(data);
214            var elem = await GetElement(frame, findBy, identifier, index);
215            var x = (int)(await elem.BoundingBoxAsync()).X;
216
217            data.Logger.Log($"The X coordinate of the element is {x}", LogColors.DarkSalmon);
218            return x;
219        }
220
221        [Block("Gets the Y coordinate of the element in pixels", name = "Get Position Y")]
222        public static async Task<int> PuppeteerGetPositionY(BotData data, FindElementBy findBy, string identifier, int index)
223        {
224            data.Logger.LogHeader();
225
226            var frame = GetFrame(data);
227            var elem = await GetElement(frame, findBy, identifier, index);
228            var y = (int)(await elem.BoundingBoxAsync()).Y;
229
230            data.Logger.Log($"The Y coordinate of the element is {y}", LogColors.DarkSalmon);
231            return y;
232        }
233
234        [Block("Gets the width of the element in pixels", name = "Get Width")]
235        public static async Task<int> PuppeteerGetWidth(BotData data, FindElementBy findBy, string identifier, int index)
236        {
237            data.Logger.LogHeader();
238
239            var frame = GetFrame(data);
240            var elem = await GetElement(frame, findBy, identifier, index);
241            var width = (int)(await elem.BoundingBoxAsync()).Width;
242
243            data.Logger.Log($"The width of the element is {width}", LogColors.DarkSalmon);
244            return width;
245        }
246
247        [Block("Gets the height of the element in pixels", name = "Get Height")]
248        public static async Task<int> PuppeteerGetHeight(BotData data, FindElementBy findBy, string identifier, int index)
249        {
250            data.Logger.LogHeader();
251
252            var frame = GetFrame(data);
253            var elem = await GetElement(frame, findBy, identifier, index);
254            var height = (int)(await elem.BoundingBoxAsync()).Height;
255
256            data.Logger.Log($"The height of the element is {height}", LogColors.DarkSalmon);
257            return height;
258        }
259
260        [Block("Takes a screenshot of the element and saves it to an output file", name = "Screenshot Element")]
261        public static async Task PuppeteerScreenshotElement(BotData data, FindElementBy findBy, string identifier, int index,
262            string fileName, bool fullPage = false, bool omitBackground = false)
263        {
264            data.Logger.LogHeader();
265
266            if (data.Providers.Security.RestrictBlocksToCWD)
267                FileUtils.ThrowIfNotInCWD(fileName);
268
269            var frame = GetFrame(data);
270            var elem = await GetElement(frame, findBy, identifier, index);
271            await elem.ScreenshotAsync(fileName, new ScreenshotOptions 
272            {
273                FullPage = fullPage,
274                OmitBackground = omitBackground,
275                Type = omitBackground ? ScreenshotType.Png : ScreenshotType.Jpeg,
276                Quality = omitBackground ? null : 100
277            });
278
279            data.Logger.Log($"Took a screenshot of the element and saved it to {fileName}", LogColors.DarkSalmon);
280        }
281
282        [Block("Takes a screenshot of the element and converts it to a base64 string", name = "Screenshot Element Base64")]
283        public static async Task<string> PuppeteerScreenshotBase64(BotData data, FindElementBy findBy, string identifier, int index,
284            bool fullPage = false, bool omitBackground = false)
285        {
286            data.Logger.LogHeader();
287
288            var frame = GetFrame(data);
289            var elem = await GetElement(frame, findBy, identifier, index);
290            var base64 = await elem.ScreenshotBase64Async(new ScreenshotOptions 
291            { 
292                FullPage = fullPage,
293                OmitBackground = omitBackground,
294                Type = omitBackground ? ScreenshotType.Png : ScreenshotType.Jpeg,
295                Quality = omitBackground ? null : 100
296            });
297
298            data.Logger.Log($"Took a screenshot of the element as base64", LogColors.DarkSalmon);
299            return base64;
300        }
301
302        [Block("Switches to a different iframe", name = "Switch to Frame")]
303        public static async Task PuppeteerSwitchToFrame(BotData data, FindElementBy findBy, string identifier, int index)
304        {
305            data.Logger.LogHeader();
306
307            var frame = GetFrame(data);
308            var elem = await GetElement(frame, findBy, identifier, index);
309            data.SetObject("puppeteerFrame", await elem.ContentFrameAsync());
310
311            data.Logger.Log($"Switched to iframe", LogColors.DarkSalmon);
312        }
313
314        [Block("Waits for an element to appear on the page", name = "Wait for Element")]
315        public static async Task PuppeteerWaitForElement(BotData data, FindElementBy findBy, string identifier, bool hidden = false, bool visible = true,
316            int timeout = 30000)
317        {
318            data.Logger.LogHeader();
319
320            var frame = GetFrame(data);
321            var options = new WaitForSelectorOptions { Hidden = hidden, Visible = visible, Timeout = timeout };
322
323            if (findBy == FindElementBy.XPath)
324            {
325                await frame.WaitForXPathAsync(identifier, options);
326            }
327            else
328            {
329                await frame.WaitForSelectorAsync(BuildSelector(findBy, identifier), options);
330            }
331
332            data.Logger.Log($"Waited for element with {findBy} {identifier}", LogColors.DarkSalmon);
333        }
334
335        private static async Task<ElementHandle> GetElement(Frame frame, FindElementBy findBy, string identifier, int index)
336        {
337            var elements = findBy == FindElementBy.XPath
338                ? await frame.XPathAsync(identifier)
339                : await frame.QuerySelectorAllAsync(BuildSelector(findBy, identifier));
340
341            if (elements.Length < index + 1)
342            {
343                throw new Exception($"Expected at least {index + 1} elements to be found but {elements.Length} were found");
344            }
345
346            return elements[index];
347        }
348
349        private static string GetElementsScript(FindElementBy findBy, string identifier)
350        {
351            if (findBy == FindElementBy.XPath)
352            {
353                var script = $"document.evaluate(\"{identifier.Replace("\"", "\\\"")}\", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)";
354                return $"Array.from({{ length: {script}.snapshotLength }}, (_, index) => {script}.snapshotItem(index))";
355            }
356            else
357            {
358                return $"document.querySelectorAll('{BuildSelector(findBy, identifier)}')";
359            }
360        }
361
362        private static string GetElementScript(FindElementBy findBy, string identifier, int index)
363            => findBy == FindElementBy.XPath
364            ? $"document.evaluate(\"{identifier.Replace("\"", "\\\"")}\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue"
365            : $"document.querySelectorAll('{BuildSelector(findBy, identifier)}')[{index}]";
366
367        private static string BuildSelector(FindElementBy findBy, string identifier)
368            => findBy switch
369            {
370                FindElementBy.Id => '#' + identifier,
371                FindElementBy.Class => '.' + string.Join('.', identifier.Split(' ')), // "class1 class2" => ".class1.class2"
372                FindElementBy.Selector => identifier,
373                _ => throw new NotSupportedException()
374            };
375
376        private static PuppeteerSharp.Browser GetBrowser(BotData data)
377            => data.TryGetObject<PuppeteerSharp.Browser>("puppeteer") ?? throw new Exception("The browser is not open!");
378
379        private static PuppeteerSharp.Page GetPage(BotData data)
380            => data.TryGetObject<PuppeteerSharp.Page>("puppeteerPage") ?? throw new Exception("No pages open!");
381
382        private static Frame GetFrame(BotData data)
383            => data.TryGetObject<Frame>("puppeteerFrame") ?? GetPage(data).MainFrame;
384    }
385}
386
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)