How to use Accessibility class of PuppeteerSharp.PageAccessibility package

Best Puppeteer-sharp code snippet using PuppeteerSharp.PageAccessibility.Accessibility

Page.cs

Source:Page.cs Github

copy

Full Screen

2using PuppeteerSharp.Helpers.Json;3using PuppeteerSharp.Input;4using PuppeteerSharp.Media;5using PuppeteerSharp.Messaging;6using PuppeteerSharp.PageAccessibility;7using PuppeteerSharp.PageCoverage;8using System;9using System.Collections.Generic;10using System.Diagnostics;11using System.Globalization;12using System.IO;13using System.Linq;14using System.Reflection;15using System.Threading.Tasks;16namespace PuppeteerSharp17{18    /// <summary>19    /// Provides methods to interact with a single tab in Chromium. One <see cref="Browser"/> instance might have multiple <see cref="Page"/> instances.20    /// </summary>21    /// <example>22    /// This example creates a page, navigates it to a URL, and then saves a screenshot:23    /// <code>24    /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions());25    /// var page = await browser.NewPageAsync();26    /// await page.GoToAsync("https://example.com");27    /// await page.ScreenshotAsync("screenshot.png");28    /// await browser.CloseAsync();29    /// </code>30    /// </example>31    [DebuggerDisplay("Page {Url}")]32    public class Page : IDisposable33    {34        private readonly TaskQueue _screenshotTaskQueue;35        private readonly EmulationManager _emulationManager;36        private readonly Dictionary<string, Delegate> _pageBindings;37        private readonly TaskCompletionSource<bool> _closeCompletedTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);38        private TaskCompletionSource<bool> _sessionClosedTcs;39        private readonly TimeoutSettings _timeoutSettings;40        private static readonly Dictionary<string, decimal> _unitToPixels = new Dictionary<string, decimal> {41            {"px", 1},42            {"in", 96},43            {"cm", 37.8m},44            {"mm", 3.78m}45        };46        private Page(47            CDPSession client,48            Target target,49            TaskQueue screenshotTaskQueue)50        {51            Client = client;52            Target = target;53            Keyboard = new Keyboard(client);54            Mouse = new Mouse(client, Keyboard);55            Touchscreen = new Touchscreen(client, Keyboard);56            Coverage = new Coverage(client);57            //_fileChooserInterceptors = new ConcurrentDictionary<Guid, TaskCompletionSource<FileChooser>>();58            _timeoutSettings = new TimeoutSettings();59            _emulationManager = new EmulationManager(client);60            _pageBindings = new Dictionary<string, Delegate>();61            //_workers = new Dictionary<string, Worker>();62            Accessibility = new Accessibility(client);63            _screenshotTaskQueue = screenshotTaskQueue;64            _ = target.CloseTask.ContinueWith((arg) =>65            {66                try67                {68                    Close?.Invoke(this, EventArgs.Empty);69                }70                finally71                {72                    IsClosed = true;73                    _closeCompletedTcs.TrySetResult(true);74                }75            });76        }77        #region Public Properties78        /// <summary>79        /// Chrome DevTools Protocol session.80        /// </summary>81        public CDPSession Client { get; }82        /// <summary>83        /// Raised when the JavaScript <c>load</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/load"/> event is dispatched.84        /// </summary>85        public event EventHandler Load;86        /// <summary>87        /// Raised when the page crashes88        /// </summary>89        public event EventHandler<ErrorEventArgs> Error;90        /// <summary>91        /// Raised when the JavaScript <c>DOMContentLoaded</c> <see href="https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded"/> event is dispatched.92        /// </summary>93        public event EventHandler DOMContentLoaded;94        /// <summary>95        /// Raised when JavaScript within the page calls one of console API methods, e.g. <c>console.log</c> or <c>console.dir</c>. Also emitted if the page throws an error or a warning.96        /// The arguments passed into <c>console.log</c> appear as arguments on the event handler.97        /// </summary>98        /// <example>99        /// An example of handling <see cref="Console"/> event:100        /// <code>101        /// <![CDATA[102        /// page.Console += (sender, e) => 103        /// {104        ///     for (var i = 0; i < e.Message.Args.Count; ++i)105        ///     {106        ///         System.Console.WriteLine($"{i}: {e.Message.Args[i]}");107        ///     }108        /// }109        /// ]]>110        /// </code>111        /// </example>112        //public event EventHandler<ConsoleEventArgs> Console;113        /// <summary>114        /// Raised when a frame is attached.115        /// </summary>116        public event EventHandler<FrameEventArgs> FrameAttached;117        /// <summary>118        /// Raised when a frame is detached.119        /// </summary>120        public event EventHandler<FrameEventArgs> FrameDetached;121        /// <summary>122        /// Raised when a frame is navigated to a new url.123        /// </summary>124        public event EventHandler<FrameEventArgs> FrameNavigated;125        /// <summary>126        /// Raised when a <see cref="Response"/> is received.127        /// </summary>128        /// <example>129        /// An example of handling <see cref="Response"/> event:130        /// <code>131        /// <![CDATA[132        /// var tcs = new TaskCompletionSource<string>();133        /// page.Response += async(sender, e) =>134        /// {135        ///     if (e.Response.Url.Contains("script.js"))136        ///     {137        ///         tcs.TrySetResult(await e.Response.TextAsync());138        ///     }139        /// };140        ///141        /// await Task.WhenAll(142        ///     page.GoToAsync(TestConstants.ServerUrl + "/grid.html"),143        ///     tcs.Task);144        /// Console.WriteLine(await tcs.Task);145        /// ]]>146        /// </code>147        /// </example>148        public event EventHandler<ResponseCreatedEventArgs> Response;149        /// <summary>150        /// Raised when a page issues a request. The <see cref="Request"/> object is read-only.151        /// In order to intercept and mutate requests, see <see cref="SetRequestInterceptionAsync(bool)"/>152        /// </summary>153        public event EventHandler<RequestEventArgs> Request;154        /// <summary>155        /// Raised when a request finishes successfully.156        /// </summary>157        public event EventHandler<RequestEventArgs> RequestFinished;158        /// <summary>159        /// Raised when a request fails, for example by timing out.160        /// </summary>161        public event EventHandler<RequestEventArgs> RequestFailed;162        /// <summary>163        /// Raised when an uncaught exception happens within the page.164        /// </summary>165        public event EventHandler<PageErrorEventArgs> PageError;166        ///// <summary>167        ///// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is spawned by the page.168        ///// </summary>169        //public event EventHandler<WorkerEventArgs> WorkerCreated;170        ///// <summary>171        ///// Emitted when a dedicated WebWorker (<see href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API"/>) is terminated.172        ///// </summary>173        //public event EventHandler<WorkerEventArgs> WorkerDestroyed;174        /// <summary>175        /// Raised when the page closes.176        /// </summary>177        public event EventHandler Close;178        /// <summary>179        /// Raised when the page opens a new tab or window.180        /// </summary>181        public event EventHandler<PopupEventArgs> Popup;182        /// <summary>183        /// This setting will change the default maximum time for the following methods:184        /// - <see cref="GoToAsync(string, NavigationOptions)"/>185        /// - <see cref="GoBackAsync(NavigationOptions)"/>186        /// - <see cref="GoForwardAsync(NavigationOptions)"/>187        /// - <see cref="ReloadAsync(NavigationOptions)"/>188        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>189        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>190        /// **NOTE** <see cref="DefaultNavigationTimeout"/> takes priority over <seealso cref="DefaultTimeout"/>191        /// </summary>192        public int DefaultNavigationTimeout193        {194            get => _timeoutSettings.NavigationTimeout;195            set => _timeoutSettings.NavigationTimeout = value;196        }197        /// <summary>198        /// This setting will change the default maximum times for the following methods:199        /// - <see cref="GoBackAsync(NavigationOptions)"/>200        /// - <see cref="GoForwardAsync(NavigationOptions)"/>201        /// - <see cref="GoToAsync(string, NavigationOptions)"/>202        /// - <see cref="ReloadAsync(NavigationOptions)"/>203        /// - <see cref="SetContentAsync(string, NavigationOptions)"/>204        /// - <see cref="WaitForFunctionAsync(string, object[])"/>205        /// - <see cref="WaitForNavigationAsync(NavigationOptions)"/>206        /// - <see cref="WaitForRequestAsync(string, WaitForOptions)"/>207        /// - <see cref="WaitForResponseAsync(string, WaitForOptions)"/>208        /// - <see cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>209        /// - <see cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>210        /// - <see cref="WaitForExpressionAsync(string, WaitForFunctionOptions)"/>211        /// </summary>212        public int DefaultTimeout213        {214            get => _timeoutSettings.Timeout;215            set => _timeoutSettings.Timeout = value;216        }217        /// <summary>218        /// Gets page's main frame219        /// </summary>220        /// <remarks>221        /// Page is guaranteed to have a main frame which persists during navigations.222        /// </remarks>223        public Frame MainFrame => FrameManager.MainFrame;224        /// <summary>225        /// Gets all frames attached to the page.226        /// </summary>227        /// <value>An array of all frames attached to the page.</value>228        public Frame[] Frames => FrameManager.GetFrames();229        ///// <summary>230        ///// Gets all workers in the page.231        ///// </summary>232        //public Worker[] Workers => _workers.Values.ToArray();233        /// <summary>234        /// Shortcut for <c>page.MainFrame.Url</c>235        /// </summary>236        public string Url => MainFrame.Url;237        /// <summary>238        /// Gets that target this page was created from.239        /// </summary>240        public Target Target { get; }241        /// <summary>242        /// Gets this page's keyboard243        /// </summary>244        public Keyboard Keyboard { get; }245        /// <summary>246        /// Gets this page's touchscreen247        /// </summary>248        public Touchscreen Touchscreen { get; }249        /// <summary>250        /// Gets this page's coverage251        /// </summary>252        public Coverage Coverage { get; }253        /// <summary>254        /// Gets this page's mouse255        /// </summary>256        public Mouse Mouse { get; }257        /// <summary>258        /// Gets this page's viewport259        /// </summary>260        public ViewPortOptions Viewport { get; private set; }261        /// <summary>262        /// List of supported metrics provided by the <see cref="Metrics"/> event.263        /// </summary>264        public static readonly IEnumerable<string> SupportedMetrics = new List<string>265        {266            "Timestamp",267            "Documents",268            "Frames",269            "JSEventListeners",270            "Nodes",271            "LayoutCount",272            "RecalcStyleCount",273            "LayoutDuration",274            "RecalcStyleDuration",275            "ScriptDuration",276            "TaskDuration",277            "JSHeapUsedSize",278            "JSHeapTotalSize"279        };280        /// <summary>281        /// Get the browser the page belongs to.282        /// </summary>283        public Browser Browser => Target.Browser;284        /// <summary>285        /// Get the browser context that the page belongs to.286        /// </summary>287        public BrowserContext BrowserContext => Target.BrowserContext;288        /// <summary>289        /// Get an indication that the page has been closed.290        /// </summary>291        public bool IsClosed { get; private set; }292        /// <summary>293        /// Gets the accessibility.294        /// </summary>295        public Accessibility Accessibility { get; }296        internal bool JavascriptEnabled { get; set; } = true;297        internal bool HasPopupEventListeners => Popup?.GetInvocationList().Any() == true;298        internal FrameManager FrameManager { get; private set; }299        private Task SessionClosedTask300        {301            get302            {303                if (_sessionClosedTcs == null)304                {305                    _sessionClosedTcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);306                    Client.Disconnected += clientDisconnected;307                    void clientDisconnected(object sender, EventArgs e)308                    {309                        _sessionClosedTcs.TrySetException(new TargetClosedException("Target closed", "Session closed"));...

Full Screen

Full Screen

AccessibilityTests.cs

Source:AccessibilityTests.cs Github

copy

Full Screen

1using System.Threading.Tasks;2using PuppeteerSharp.PageAccessibility;3using PuppeteerSharp.Tests.Attributes;4using PuppeteerSharp.Xunit;5using Xunit;6using Xunit.Abstractions;7namespace PuppeteerSharp.Tests.AccesibilityTests8{9    [Collection(TestConstants.TestFixtureCollectionName)]10    public class AccesibilityTests : PuppeteerPageBaseTest11    {12        public AccesibilityTests(ITestOutputHelper output) : base(output)13        {14        }15        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "should work")]16        [SkipBrowserFact(skipFirefox: true)]17        public async Task ShouldWork()18        {19            await Page.SetContentAsync(@"20            <head>21                <title>Accessibility Test</title>22            </head>23            <body>24                <div>Hello World</div>25                <h1>Inputs</h1>26                <input placeholder='Empty input' autofocus />27                <input placeholder='readonly input' readonly />28                <input placeholder='disabled input' disabled />29                <input aria-label='Input with whitespace' value='  ' />30                <input value='value only' />31                <input aria-placeholder='placeholder' value='and a value' />32                <div aria-hidden='true' id='desc'>This is a description!</div>33                <input aria-placeholder='placeholder' value='and a value' aria-describedby='desc' />34                <select>35                    <option>First Option</option>36                    <option>Second Option</option>37                </select>38            </body>");39            var nodeToCheck = new SerializedAXNode40            {41                Role = "RootWebArea",42                Name = "Accessibility Test",43                Children = new SerializedAXNode[]44                    {45                        new SerializedAXNode46                        {47                            Role = "StaticText",48                            Name = "Hello World"49                        },50                        new SerializedAXNode51                        {52                            Role = "heading",53                            Name = "Inputs",54                            Level = 155                        },56                        new SerializedAXNode{57                            Role = "textbox",58                            Name = "Empty input",59                            Focused = true60                        },61                        new SerializedAXNode{62                            Role = "textbox",63                            Name = "readonly input",64                            Readonly = true65                        },66                        new SerializedAXNode{67                            Role = "textbox",68                            Name = "disabled input",69                            Disabled= true70                        },71                        new SerializedAXNode{72                            Role = "textbox",73                            Name = "Input with whitespace",74                            Value= "  "75                        },76                        new SerializedAXNode{77                            Role = "textbox",78                            Name = "",79                            Value= "value only"80                        },81                        new SerializedAXNode{82                            Role = "textbox",83                            Name = "placeholder",84                            Value= "and a value"85                        },86                        new SerializedAXNode{87                            Role = "textbox",88                            Name = "placeholder",89                            Value= "and a value",90                            Description= "This is a description!"},91                        new SerializedAXNode{92                            Role= "combobox",93                            Name= "",94                            Value= "First Option",95                            HasPopup = "menu",96                            Children= new SerializedAXNode[]{97                                new SerializedAXNode98                                {99                                    Role = "menuitem",100                                    Name = "First Option",101                                    Selected= true102                                },103                                new SerializedAXNode104                                {105                                    Role = "menuitem",106                                    Name = "Second Option"107                                }108                            }109                        }110                    }111            };112            await Page.FocusAsync("[placeholder='Empty input']");113            var snapshot = await Page.Accessibility.SnapshotAsync();114            Assert.Equal(nodeToCheck, snapshot);115        }116        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "should report uninteresting nodes")]117        [SkipBrowserFact(skipFirefox: true)]118        public async Task ShouldReportUninterestingNodes()119        {120            await Page.SetContentAsync("<textarea autofocus>hi</textarea>");121            await Page.FocusAsync("textarea");122            Assert.Equal(123                new SerializedAXNode124                {125                    Role = "textbox",126                    Name = "",127                    Value = "hi",128                    Focused = true,129                    Multiline = true,130                    Children = new SerializedAXNode[]131                    {132                        new SerializedAXNode133                        {134                            Role = "generic",135                            Name = "",136                            Children = new SerializedAXNode[]137                            {138                                new SerializedAXNode139                                {140                                    Role = "StaticText",141                                    Name = "hi"142                                }143                            }144                        }145                    }146                },147                FindFocusedNode(await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions148                {149                    InterestingOnly = false150                })));151        }152        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "roledescription")]153        [SkipBrowserFact(skipFirefox: true)]154        public async Task RoleDescription()155        {156            await Page.SetContentAsync("<div tabIndex=-1 aria-roledescription='foo'>Hi</div>");157            var snapshot = await Page.Accessibility.SnapshotAsync();158            // See https://chromium-review.googlesource.com/c/chromium/src/+/3088862159            Assert.Null(snapshot.Children[0].RoleDescription);160        }161        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "orientation")]162        [SkipBrowserFact(skipFirefox: true)]163        public async Task Orientation()164        {165            await Page.SetContentAsync("<a href='' role='slider' aria-orientation='vertical'>11</a>");166            var snapshot = await Page.Accessibility.SnapshotAsync();167            Assert.Equal("vertical", snapshot.Children[0].Orientation);168        }169        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "autocomplete")]170        [SkipBrowserFact(skipFirefox: true)]171        public async Task AutoComplete()172        {173            await Page.SetContentAsync("<input type='number' aria-autocomplete='list' />");174            var snapshot = await Page.Accessibility.SnapshotAsync();175            Assert.Equal("list", snapshot.Children[0].AutoComplete);176        }177        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "multiselectable")]178        [SkipBrowserFact(skipFirefox: true)]179        public async Task MultiSelectable()180        {181            await Page.SetContentAsync("<div role='grid' tabIndex=-1 aria-multiselectable=true>hey</div>");182            var snapshot = await Page.Accessibility.SnapshotAsync();183            Assert.True(snapshot.Children[0].Multiselectable);184        }185        [PuppeteerTest("accessibility.spec.ts", "Accessibility", "keyshortcuts")]186        [SkipBrowserFact(skipFirefox: true)]187        public async Task KeyShortcuts()188        {189            await Page.SetContentAsync("<div role='grid' tabIndex=-1 aria-keyshortcuts='foo'>hey</div>");190            var snapshot = await Page.Accessibility.SnapshotAsync();191            Assert.Equal("foo", snapshot.Children[0].KeyShortcuts);192        }193        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "should not report text nodes inside controls")]194        [SkipBrowserFact(skipFirefox: true)]195        public async Task ShouldNotReportTextNodesInsideControls()196        {197            await Page.SetContentAsync(@"198            <div role='tablist'>199                <div role='tab' aria-selected='true'><b>Tab1</b></div>200                <div role='tab'>Tab2</div>201            </div>");202            Assert.Equal(203                new SerializedAXNode204                {205                    Role = "RootWebArea",206                    Name = "",207                    Children = new SerializedAXNode[]208                    {209                        new SerializedAXNode210                        {211                            Role = "tab",212                            Name = "Tab1",213                            Selected = true214                        },215                        new SerializedAXNode216                        {217                            Role = "tab",218                            Name = "Tab2"219                        }220                    }221                },222                await Page.Accessibility.SnapshotAsync());223        }224        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "rich text editable fields should have children")]225        [SkipBrowserFact(skipFirefox: true)]226        public async Task RichTextEditableFieldsShouldHaveChildren()227        {228            await Page.SetContentAsync(@"229            <div contenteditable='true'>230                Edit this image: <img src='fakeimage.png' alt='my fake image'>231            </div>");232            Assert.Equal(233                new SerializedAXNode234                {235                    Role = "generic",236                    Name = "",237                    Value = "Edit this image: ",238                    Children = new SerializedAXNode[]239                    {240                        new SerializedAXNode241                        {242                            Role = "StaticText",243                            Name = "Edit this image:"244                        },245                        new SerializedAXNode246                        {247                            Role = "img",248                            Name = "my fake image"249                        }250                    }251                },252                (await Page.Accessibility.SnapshotAsync()).Children[0]);253        }254        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "rich text editable fields with role should have children")]255        [SkipBrowserFact(skipFirefox: true)]256        public async Task RichTextEditableFieldsWithRoleShouldHaveChildren()257        {258            await Page.SetContentAsync(@"259            <div contenteditable='true' role='textbox'>260                Edit this image: <img src='fakeimage.png' alt='my fake image'>261            </div>");262            Assert.Equal(263                new SerializedAXNode264                {265                    Role = "textbox",266                    Name = "",267                    Value = "Edit this image: ",268                    Multiline = true,269                    Children = new SerializedAXNode[]270                    {271                        new SerializedAXNode272                        {273                            Role = "StaticText",274                            Name = "Edit this image:"275                        },276                        new SerializedAXNode277                        {278                            Role = "img",279                            Name = "my fake image"280                        }281                    }282                },283                (await Page.Accessibility.SnapshotAsync()).Children[0]);284        }285        [PuppeteerTest("accessibility.spec.ts", "plaintext contenteditable", "plain text field with role should not have children")]286        [SkipBrowserFact(skipFirefox: true)]287        public async Task PlainTextFieldWithRoleShouldNotHaveChildren()288        {289            await Page.SetContentAsync("<div contenteditable='plaintext-only' role='textbox'>Edit this image:<img src='fakeimage.png' alt='my fake image'></div>");290            Assert.Equal(291                new SerializedAXNode292                {293                    Role = "textbox",294                    Name = "",295                    Value = "Edit this image:",296                    Multiline = true,297                },298                (await Page.Accessibility.SnapshotAsync()).Children[0]);299        }300        [PuppeteerTest("accessibility.spec.ts", "plaintext contenteditable", "plain text field with tabindex and without role should not have content")]301        [SkipBrowserFact(skipFirefox: true)]302        public async Task PlainTextFieldWithoutRoleShouldNotHaveContent()303        {304            await Page.SetContentAsync(305                "<div contenteditable='plaintext-only'>Edit this image:<img src='fakeimage.png' alt='my fake image'></div>");306            var snapshot = await Page.Accessibility.SnapshotAsync();307            Assert.Equal("generic", snapshot.Children[0].Role);308            Assert.Equal(string.Empty, snapshot.Children[0].Name);309        }310        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "non editable textbox with role and tabIndex and label should not have children")]311        [SkipBrowserFact(skipFirefox: true)]312        public async Task NonEditableTextboxWithRoleAndTabIndexAndLabelShouldNotHaveChildren()313        {314            await Page.SetContentAsync(@"315            <div role='textbox' tabIndex=0 aria-checked='true' aria-label='my favorite textbox'>316                this is the inner content317                <img alt='yo' src='fakeimg.png'>318            </div>");319            Assert.Equal(320                new SerializedAXNode321                {322                    Role = "textbox",323                    Name = "my favorite textbox",324                    Value = "this is the inner content "325                },326                (await Page.Accessibility.SnapshotAsync()).Children[0]);327        }328        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "checkbox with and tabIndex and label should not have children")]329        [SkipBrowserFact(skipFirefox: true)]330        public async Task CheckboxWithAndTabIndexAndLabelShouldNotHaveChildren()331        {332            await Page.SetContentAsync(@"333            <div role='checkbox' tabIndex=0 aria-checked='true' aria-label='my favorite checkbox'>334                this is the inner content335                <img alt='yo' src='fakeimg.png'>336            </div>");337            Assert.Equal(338                new SerializedAXNode339                {340                    Role = "checkbox",341                    Name = "my favorite checkbox",342                    Checked = CheckedState.True343                },344                (await Page.Accessibility.SnapshotAsync()).Children[0]);345        }346        [PuppeteerTest("accessibility.spec.ts", "filtering children of leaf nodes", "checkbox without label should not have children")]347        [SkipBrowserFact(skipFirefox: true)]348        public async Task CheckboxWithoutLabelShouldNotHaveChildren()349        {350            await Page.SetContentAsync(@"351            <div role='checkbox' aria-checked='true'>352                this is the inner content353                <img alt='yo' src='fakeimg.png'>354            </div>");355            Assert.Equal(356                new SerializedAXNode357                {358                    Role = "checkbox",359                    Name = "this is the inner content yo",360                    Checked = CheckedState.True361                },362                (await Page.Accessibility.SnapshotAsync()).Children[0]);363        }364        private SerializedAXNode FindFocusedNode(SerializedAXNode serializedAXNode)365        {366            if (serializedAXNode.Focused)367            {368                return serializedAXNode;369            }370            foreach (var item in serializedAXNode.Children)371            {372                var focusedChild = FindFocusedNode(item);373                if (focusedChild != null)374                {375                    return focusedChild;376                }...

Full Screen

Full Screen

AXNode.cs

Source:AXNode.cs Github

copy

Full Screen

...3using System.Collections.Generic;4using PuppeteerSharp.Messaging;5using Newtonsoft.Json.Linq;6using PuppeteerSharp.Helpers;7namespace PuppeteerSharp.PageAccessibility8{9    internal class AXNode10    {11        internal AccessibilityGetFullAXTreeResponse.AXTreeNode Payload { get; }12        public List<AXNode> Children { get; }13        public bool Focusable { get; set; }14        private readonly string _name;15        private string _role;16        private readonly bool _richlyEditable;17        private readonly bool _editable;18        private readonly bool _expanded;19        private readonly bool _hidden;20        private bool? _cachedHasFocusableChild;21        public AXNode(AccessibilityGetFullAXTreeResponse.AXTreeNode payload)22        {23            Payload = payload;24            Children = new List<AXNode>();25            _name = payload.Name != null ? payload.Name.Value.ToObject<string>() : string.Empty;26            _role = payload.Role != null ? payload.Role.Value.ToObject<string>() : "Unknown";27            _richlyEditable = payload.Properties.FirstOrDefault(p => p.Name == "editable")?.Value.Value.ToObject<string>() == "richtext";28            _editable |= _richlyEditable;29            _expanded = payload.Properties.FirstOrDefault(p => p.Name == "expanded")?.Value.Value.ToObject<bool>() == true;30            _hidden = payload.Properties.FirstOrDefault(p => p.Name == "hidden")?.Value.Value.ToObject<bool>() == true;31            Focusable = payload.Properties.FirstOrDefault(p => p.Name == "focusable")?.Value.Value.ToObject<bool>() == true;32        }33        internal static AXNode CreateTree(IEnumerable<AccessibilityGetFullAXTreeResponse.AXTreeNode> payloads)34        {35            var nodeById = new Dictionary<string, AXNode>();36            foreach (var payload in payloads)37            {38                nodeById[payload.NodeId] = new AXNode(payload);39            }40            foreach (var node in nodeById.Values)41            {42                foreach (var childId in node.Payload.ChildIds)43                {44                    node.Children.Add(nodeById[childId]);45                }46            }47            return nodeById.Values.FirstOrDefault();...

Full Screen

Full Screen

SerializedAXNode.cs

Source:SerializedAXNode.cs Github

copy

Full Screen

1using System;2using System.Linq;3namespace PuppeteerSharp.PageAccessibility4{5    /// <summary>6    /// AXNode.7    /// </summary>8    public class SerializedAXNode : IEquatable<SerializedAXNode>9    {10        /// <summary>11        /// Creates a new serialized node12        /// </summary>13        public SerializedAXNode() => Children = Array.Empty<SerializedAXNode>();14        /// <summary>15        /// The <see fref="https://www.w3.org/TR/wai-aria/#usage_intro">role</see>.16        /// </summary>17        public string Role { get; set; }...

Full Screen

Full Screen

RootOptionTests.cs

Source:RootOptionTests.cs Github

copy

Full Screen

1using System.Threading.Tasks;2using PuppeteerSharp.PageAccessibility;3using Xunit;4using Xunit.Abstractions;56namespace PuppeteerSharp.Tests.AccesibilityTests7{8    [Collection(TestConstants.TestFixtureCollectionName)]9    public class RootOptionTests : PuppeteerPageBaseTest10    {11        public RootOptionTests(ITestOutputHelper output) : base(output)12        {13        }1415        [Fact]16        public async Task ShouldWorkAButton()17        {18            await Page.SetContentAsync("<button>My Button</button>");1920            var button = await Page.QuerySelectorAsync("button");21            Assert.Equal(22                new SerializedAXNode23                {24                    Role = "button",25                    Name = "My Button"26                },27                await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions { Root = button }));28        }2930        [Fact]31        public async Task ShouldWorkAnInput()32        {33            await Page.SetContentAsync("<input title='My Input' value='My Value'>");3435            var input = await Page.QuerySelectorAsync("input");36            Assert.Equal(37                new SerializedAXNode38                {39                    Role = "textbox",40                    Name = "My Input",41                    Value = "My Value"42                },43                await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions { Root = input }));44        }4546        [Fact]47        public async Task ShouldWorkAMenu()48        {49            await Page.SetContentAsync(@"50            <div role=""menu"" title=""My Menu"" >51              <div role=""menuitem"">First Item</div>52              <div role=""menuitem"">Second Item</div>53              <div role=""menuitem"">Third Item</div>54            </div>55            ");5657            var menu = await Page.QuerySelectorAsync("div[role=\"menu\"]");58            Assert.Equal(59                new SerializedAXNode60                {61                    Role = "menu",62                    Name = "My Menu",63                    Children = new[]64                    {65                        new SerializedAXNode66                        {67                            Role = "menuitem",68                            Name = "First Item"69                        },70                        new SerializedAXNode71                        {72                            Role = "menuitem",73                            Name = "Second Item"74                        },75                        new SerializedAXNode76                        {77                            Role = "menuitem",78                            Name = "Third Item"79                        }80                    }81                },82                await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions { Root = menu }));83        }8485        [Fact]86        public async Task ShouldReturnNullWhenTheElementIsNoLongerInDOM()87        {88            await Page.SetContentAsync("<button>My Button</button>");89            var button = await Page.QuerySelectorAsync("button");90            await Page.EvaluateFunctionAsync("button => button.remove()", button);91            Assert.Null(await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions { Root = button }));92        }9394        [Fact]95        public async Task ShouldSupportTheInterestingOnlyOption()96        {97            await Page.SetContentAsync("<div><button>My Button</button></div>");98            var div = await Page.QuerySelectorAsync("div");99            Assert.Null(await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions100            {101                Root = div102            }));103            Assert.Equal(104                new SerializedAXNode105                {106                    Role = "GenericContainer",107                    Name = "",108                    Children = new[]109                    {110                        new SerializedAXNode111                        {112                            Role = "button",113                            Name = "My Button"114                        }115                    }116                },117                await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions118                {119                    Root = div,120                    InterestingOnly = false121                }));122        }123    }124}
...

Full Screen

Full Screen

Accessibility.cs

Source:Accessibility.cs Github

copy

Full Screen

1using System;2using System.Collections.Generic;3using System.Threading.Tasks;4using PuppeteerSharp.Messaging;5namespace PuppeteerSharp.PageAccessibility6{7    /// <summary>8    /// The Accessibility class provides methods for inspecting Chromium's accessibility tree. 9    /// The accessibility tree is used by assistive technology such as screen readers or switches.10    /// 11    /// Accessibility is a very platform-specific thing. On different platforms, there are different screen readers that might have wildly different output.12    /// Blink - Chrome's rendering engine - has a concept of "accessibility tree", which is than translated into different platform-specific APIs. 13    /// Accessibility namespace gives users access to the Blink Accessibility Tree.14    /// Most of the accessibility tree gets filtered out when converting from Blink AX Tree to Platform-specific AX-Tree or by assistive technologies themselves. 15    /// By default, Puppeteer tries to approximate this filtering, exposing only the "interesting" nodes of the tree.16    /// </summary>17    public class Accessibility18    {19        private readonly CDPSession _client;20        /// <summary>21        /// Initializes a new instance of the <see cref="PuppeteerSharp.PageAccessibility.Accessibility"/> class.22        /// </summary>23        /// <param name="client">Client.</param>24        public Accessibility(CDPSession client) => _client = client;25        /// <summary>26        /// Snapshots the async.27        /// </summary>28        /// <returns>The async.</returns>29        /// <param name="options">Options.</param>30        public async Task<SerializedAXNode> SnapshotAsync(AccessibilitySnapshotOptions options = null)31        {32            var response = await _client.SendAsync<AccessibilityGetFullAXTreeResponse>("Accessibility.getFullAXTree").ConfigureAwait(false);33            var nodes = response.Nodes;34            int? backendNodeId = null;35            if (options?.Root != null)36            {37                var node = await _client.SendAsync<DomDescribeNodeResponse>("DOM.describeNode", new DomDescribeNodeRequest38                {39                    ObjectId = options.Root.RemoteObject.ObjectId40                }).ConfigureAwait(false);41                backendNodeId = node.Node.BackendNodeId;42            }43            var defaultRoot = AXNode.CreateTree(nodes);44            var needle = defaultRoot;45            if (backendNodeId.HasValue)46            {...

Full Screen

Full Screen

AccessibilitySnapshotOptions.cs

Source:AccessibilitySnapshotOptions.cs Github

copy

Full Screen

1namespace PuppeteerSharp.PageAccessibility2{3    /// <summary>4    /// <see cref="Accessibility.SnapshotAsync(AccessibilitySnapshotOptions)"/>5    /// </summary>6    /// <seealso cref="Page.Accessibility"/>7    public class AccessibilitySnapshotOptions8    {9        /// <summary>10        /// Prune uninteresting nodes from the tree. Defaults to true.11        /// </summary>12        public bool InterestingOnly { get; set; } = true;13        /// <summary>14        /// The root DOM element for the snapshot. Defaults to the whole page.15        /// </summary>16        public ElementHandle Root { get; set; }17    }...

Full Screen

Full Screen

CheckedState.cs

Source:CheckedState.cs Github

copy

Full Screen

1namespace PuppeteerSharp.PageAccessibility2{3    /// <summary>4    /// Three-state boolean. See <seealso cref="SerializedAXNode.Checked"/> and <seealso cref="SerializedAXNode.Pressed"/>5    /// </summary>6    public enum CheckedState7    {8        /// <summary>9        /// Flse.10        /// </summary>11        False = 0,12        /// <summary>13        /// True.14        /// </summary>15        True,...

Full Screen

Full Screen

Accessibility

Using AI Code Generation

copy

Full Screen

1using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))2{3    var page = await browser.NewPageAsync();4    var accessibility = await page.Accessibility;5    var snapshot = await accessibility.SnapshotAsync();6    Console.WriteLine(snapshot);7}8using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))9{10    var page = await browser.NewPageAsync();11    var accessibility = await page.Accessibility;12    var snapshot = await accessibility.SnapshotAsync();13    Console.WriteLine(snapshot);14}15I am trying to build a simple C# console application that will take a screenshot of a web page. I am using the PuppeteerSharp package to do this. The code is below. I am using the latest version of the package. I am running this on a Windows 10 machine.When I run the code, the browser opens and navigates to the page. I can see the page load in the browser. However, the screenshot is not saved to the folder. I don't get any errors or exceptions. The code just stops running.What am I doing wrong?using PuppeteerSharp;using System;using System.Threading.Tasks;namespace PuppeteerSharpTestnam

Full Screen

Full Screen

Accessibility

Using AI Code Generation

copy

Full Screen

1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using PuppeteerSharp;7using PuppeteerSharp.PageAccessibility;8{9    {10        static void Main(string[] args)11        {12            MainAsync().Wait();13        }14        static async Task MainAsync()15        {16            var browser = await Puppeteer.LaunchAsync(new LaunchOptions17            {18            });19            var page = await browser.NewPageAsync();20            var accessibility = await page.Accessibility.SnapshotAsync();21            Console.WriteLine(accessibility);22            await browser.CloseAsync();23        }24    }25}26using System;27using System.Collections.Generic;28using System.Linq;29using System.Text;30using System.Threading.Tasks;31using PuppeteerSharp;32using PuppeteerSharp.PageAccessibility;33{34    {35        static void Main(string[] args)36        {37            MainAsync().Wait();38        }39        static async Task MainAsync()40        {41            var browser = await Puppeteer.LaunchAsync(new LaunchOptions42            {43            });44            var page = await browser.NewPageAsync();45            var accessibility = await page.Accessibility.SnapshotAsync();46            System.IO.File.WriteAllText(@"C:\Users\abc\Desktop\accessibility.json", accessibility.ToString());47            await browser.CloseAsync();48        }49    }50}51using System;52using System.Collections.Generic;53using System.Linq;54using System.Text;55using System.Threading.Tasks;56using PuppeteerSharp;57using PuppeteerSharp.PageAccessibility;58{59    {

Full Screen

Full Screen

Accessibility

Using AI Code Generation

copy

Full Screen

1var accessibility = await page.Accessibility;2var snapshot = await accessibility.SnapshotAsync();3Console.WriteLine(snapshot);4var accessibility = await page.Accessibility;5var snapshot = await accessibility.QueryAXTreeAsync();6Console.WriteLine(snapshot);7var pageAccessibility = new PageAccessibility(page);8var snapshot = await pageAccessibility.QueryAXTreeAsync();9Console.WriteLine(snapshot);10var snapshot = await pageAccessibility.QueryAXTreeAsync();11Console.WriteLine(snapshot);

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

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

Most used methods in Accessibility

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful