How to use AXNode class of PuppeteerSharp.PageAccessibility package

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

AccessibilityTests.cs

Source:AccessibilityTests.cs Github

copy

Full Screen

...34                    <option>First Option</option>35                    <option>Second Option</option>36                </select>37            </body>");38            var nodeToCheck = new SerializedAXNode39            {40                Role = "WebArea",41                Name = "Accessibility Test",42                Children = new SerializedAXNode[]43                    {44                        new SerializedAXNode45                        {46                            Role = "text",47                            Name = "Hello World"48                        },49                        new SerializedAXNode50                        {51                            Role = "heading",52                            Name = "Inputs",53                            Level = 154                        },55                        new SerializedAXNode{56                            Role = "textbox",57                            Name = "Empty input",58                            Focused = true59                        },60                        new SerializedAXNode{61                            Role = "textbox",62                            Name = "readonly input",63                            Readonly = true64                        },65                        new SerializedAXNode{66                            Role = "textbox",67                            Name = "disabled input",68                            Disabled= true69                        },70                        new SerializedAXNode{71                            Role = "textbox",72                            Name = "Input with whitespace",73                            Value= "  "74                        },75                        new SerializedAXNode{76                            Role = "textbox",77                            Name = "",78                            Value= "value only"79                        },80                        new SerializedAXNode{81                            Role = "textbox",82                            Name = "placeholder",83                            Value= "and a value"84                        },85                        new SerializedAXNode{86                            Role = "textbox",87                            Name = "placeholder",88                            Value= "and a value",89                            Description= "This is a description!"},90                        new SerializedAXNode{91                            Role= "combobox",92                            Name= "",93                            Value= "First Option",94                            Children= new SerializedAXNode[]{95                                new SerializedAXNode96                                {97                                    Role = "menuitem",98                                    Name = "First Option",99                                    Selected= true100                                },101                                new SerializedAXNode102                                {103                                    Role = "menuitem",104                                    Name = "Second Option"105                                }106                            }107                        }108                    }109            };110            await Page.FocusAsync("[placeholder='Empty input']");111            var snapshot = await Page.Accessibility.SnapshotAsync();112            Assert.Equal(nodeToCheck, snapshot);113        }114        [Fact]115        public async Task ShouldReportUninterestingNodes()116        {117            await Page.SetContentAsync("<textarea autofocus>hi</textarea>");118            await Page.FocusAsync("textarea");119            Assert.Equal(120                new SerializedAXNode121                {122                    Role = "textbox",123                    Name = "",124                    Value = "hi",125                    Focused = true,126                    Multiline = true,127                    Children = new SerializedAXNode[]128                    {129                        new SerializedAXNode130                        {131                            Role = "GenericContainer",132                            Name = "",133                            Children = new SerializedAXNode[]134                            {135                                new SerializedAXNode136                                {137                                    Role = "text",138                                    Name = "hi"139                                }140                            }141                        }142                    }143                },144                FindFocusedNode(await Page.Accessibility.SnapshotAsync(new AccessibilitySnapshotOptions145                {146                    InterestingOnly = false147                })));148        }149        [Fact]150        public async Task RoleDescription()151        {152            await Page.SetContentAsync("<div tabIndex=-1 aria-roledescription='foo'>Hi</div>");153            var snapshot = await Page.Accessibility.SnapshotAsync();154            Assert.Equal("foo", snapshot.Children[0].RoleDescription);155        }156        [Fact]157        public async Task Orientation()158        {159            await Page.SetContentAsync("<a href='' role='slider' aria-orientation='vertical'>11</a>");160            var snapshot = await Page.Accessibility.SnapshotAsync();161            Assert.Equal("vertical", snapshot.Children[0].Orientation);162        }163        [Fact]164        public async Task AutoComplete()165        {166            await Page.SetContentAsync("<input type='number' aria-autocomplete='list' />");167            var snapshot = await Page.Accessibility.SnapshotAsync();168            Assert.Equal("list", snapshot.Children[0].AutoComplete);169        }170        [Fact]171        public async Task MultiSelectable()172        {173            await Page.SetContentAsync("<div role='grid' tabIndex=-1 aria-multiselectable=true>hey</div>");174            var snapshot = await Page.Accessibility.SnapshotAsync();175            Assert.True(snapshot.Children[0].Multiselectable);176        }177        [Fact]178        public async Task KeyShortcuts()179        {180            await Page.SetContentAsync("<div role='grid' tabIndex=-1 aria-keyshortcuts='foo'>hey</div>");181            var snapshot = await Page.Accessibility.SnapshotAsync();182            Assert.Equal("foo", snapshot.Children[0].KeyShortcuts);183        }184        [Fact]185        public async Task ShouldNotReportTextNodesInsideControls()186        {187            await Page.SetContentAsync(@"188            <div role='tablist'>189                <div role='tab' aria-selected='true'><b>Tab1</b></div>190                <div role='tab'>Tab2</div>191            </div>");192            Assert.Equal(193                new SerializedAXNode194                {195                    Role = "WebArea",196                    Name = "",197                    Children = new SerializedAXNode[]198                    {199                        new SerializedAXNode200                        {201                            Role = "tab",202                            Name = "Tab1",203                            Selected = true204                        },205                        new SerializedAXNode206                        {207                            Role = "tab",208                            Name = "Tab2"209                        }210                    }211                },212                await Page.Accessibility.SnapshotAsync());213        }214215        [Fact]216        public async Task RichTextEditableFieldsShouldHaveChildren()217        {218            await Page.SetContentAsync(@"219            <div contenteditable='true'>220                Edit this image: <img src='fakeimage.png' alt='my fake image'>221            </div>");222            Assert.Equal(223                new SerializedAXNode224                {225                    Role = "GenericContainer",226                    Name = "",227                    Value = "Edit this image: ",228                    Children = new SerializedAXNode[]229                    {230                        new SerializedAXNode231                        {232                            Role = "text",233                            Name = "Edit this image:"234                        },235                        new SerializedAXNode236                        {237                            Role = "img",238                            Name = "my fake image"239                        }240                    }241                },242                (await Page.Accessibility.SnapshotAsync()).Children[0]);243        }244245        [Fact]246        public async Task RichTextEditableFieldsWithRoleShouldHaveChildren()247        {248            await Page.SetContentAsync(@"249            <div contenteditable='true' role='textbox'>250                Edit this image: <img src='fakeimage.png' alt='my fake image'>251            </div>");252            Assert.Equal(253                new SerializedAXNode254                {255                    Role = "textbox",256                    Name = "",257                    Value = "Edit this image: ",258                    Children = new SerializedAXNode[]259                    {260                        new SerializedAXNode261                        {262                            Role = "text",263                            Name = "Edit this image:"264                        },265                        new SerializedAXNode266                        {267                            Role = "img",268                            Name = "my fake image"269                        }270                    }271                },272                (await Page.Accessibility.SnapshotAsync()).Children[0]);273        }274275        [Fact]276        public async Task PlainTextFieldWithRoleShouldNotHaveChildren()277        {278            await Page.SetContentAsync("<div contenteditable='plaintext-only' role='textbox'>Edit this image:<img src='fakeimage.png' alt='my fake image'></div>");279            Assert.Equal(280                new SerializedAXNode281                {282                    Role = "textbox",283                    Name = "",284                    Value = "Edit this image:"285                },286                (await Page.Accessibility.SnapshotAsync()).Children[0]);287        }288289        [Fact]290        public async Task PlainTextFieldWithTabindexAndWithoutRoleShouldNotHaveContent()291        {292            await Page.SetContentAsync("<div contenteditable='plaintext-only' role='textbox' tabIndex=0>Edit this image:<img src='fakeimage.png' alt='my fake image'></div>");293            Assert.Equal(294                new SerializedAXNode295                {296                    Role = "textbox",297                    Name = "",298                    Value = "Edit this image:"299                },300                (await Page.Accessibility.SnapshotAsync()).Children[0]);301        }302303        [Fact]304        public async Task PlainTextFieldWithoutRoleShouldNotHaveContent()305        {306            await Page.SetContentAsync(307                "<div contenteditable='plaintext-only'>Edit this image:<img src='fakeimage.png' alt='my fake image'></div>");308            var snapshot = await Page.Accessibility.SnapshotAsync();309            Assert.Equal("GenericContainer", snapshot.Children[0].Role);310            Assert.Equal(string.Empty, snapshot.Children[0].Name);311        }312313        [Fact]314        public async Task NonEditableTextboxWithRoleAndTabIndexAndLabelShouldNotHaveChildren()315        {316            await Page.SetContentAsync(@"317            <div role='textbox' tabIndex=0 aria-checked='true' aria-label='my favorite textbox'>318                this is the inner content319                <img alt='yo' src='fakeimg.png'>320            </div>");321            Assert.Equal(322                new SerializedAXNode323                {324                    Role = "textbox",325                    Name = "my favorite textbox",326                    Value = "this is the inner content "327                },328                (await Page.Accessibility.SnapshotAsync()).Children[0]);329        }330331        [Fact]332        public async Task CheckboxWithAndTabIndexAndLabelShouldNotHaveChildren()333        {334            await Page.SetContentAsync(@"335            <div role='checkbox' tabIndex=0 aria-checked='true' aria-label='my favorite checkbox'>336                this is the inner content337                <img alt='yo' src='fakeimg.png'>338            </div>");339            Assert.Equal(340                new SerializedAXNode341                {342                    Role = "checkbox",343                    Name = "my favorite checkbox",344                    Checked = CheckedState.True345                },346                (await Page.Accessibility.SnapshotAsync()).Children[0]);347        }348349        [Fact]350        public async Task CheckboxWithoutLabelShouldNotHaveChildren()351        {352            await Page.SetContentAsync(@"353            <div role='checkbox' aria-checked='true'>354                this is the inner content355                <img alt='yo' src='fakeimg.png'>356            </div>");357            Assert.Equal(358                new SerializedAXNode359                {360                    Role = "checkbox",361                    Name = "this is the inner content yo",362                    Checked = CheckedState.True363                },364                (await Page.Accessibility.SnapshotAsync()).Children[0]);365        }366        private SerializedAXNode FindFocusedNode(SerializedAXNode serializedAXNode)367        {368            if (serializedAXNode.Focused)369            {370                return serializedAXNode;371            }372            foreach (var item in serializedAXNode.Children)373            {374                var focusedChild = FindFocusedNode(item);375                if (focusedChild != null)376                {377                    return focusedChild;378                }379            }380            return null;381        }382    }383}...

Full Screen

Full Screen

AXNode.cs

Source:AXNode.cs Github

copy

Full Screen

...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();48        }49        private bool IsPlainTextField()50            => !_richlyEditable && (_editable || _role == "textbox" || _role == "ComboBox" || _role == "searchbox");51        private bool IsTextOnlyObject()52            => _role == "LineBreak" ||53                _role == "text" ||54                _role == "InlineTextBox";55        private bool HasFocusableChild()56        {57            if (!_cachedHasFocusableChild.HasValue)58            {59                _cachedHasFocusableChild = Children.Any(c => c.Focusable || c.HasFocusableChild());60            }61            return _cachedHasFocusableChild.Value;62        }63        internal AXNode Find(Func<AXNode, bool> predicate)64        {65            if (predicate(this))66            {67                return this;68            }69            foreach (var child in Children)70            {71                var result = child.Find(predicate);72                if (result != null)73                {74                    return result;75                }76            }77            return null;78        }79        internal bool IsLeafNode()80        {81            if (Children.Count == 0)82            {83                return true;84            }85            // These types of objects may have children that we use as internal86            // implementation details, but we want to expose them as leaves to platform87            // accessibility APIs because screen readers might be confused if they find88            // any children.89            if (IsPlainTextField() || IsTextOnlyObject())90            {91                return true;92            }93            // Roles whose children are only presentational according to the ARIA and94            // HTML5 Specs should be hidden from screen readers.95            // (Note that whilst ARIA buttons can have only presentational children, HTML596            // buttons are allowed to have content.)97            switch (_role)98            {99                case "doc-cover":100                case "graphics-symbol":101                case "img":102                case "Meter":103                case "scrollbar":104                case "slider":105                case "separator":106                case "progressbar":107                    return true;108            }109            // Here and below: Android heuristics110            if (HasFocusableChild())111            {112                return false;113            }114            if (Focusable && !string.IsNullOrEmpty(_name))115            {116                return true;117            }118            if (_role == "heading" && !string.IsNullOrEmpty(_name))119            {120                return true;121            }122            return false;123        }124        internal bool IsControl()125        {126            switch (_role)127            {128                case "button":129                case "checkbox":130                case "ColorWell":131                case "combobox":132                case "DisclosureTriangle":133                case "listbox":134                case "menu":135                case "menubar":136                case "menuitem":137                case "menuitemcheckbox":138                case "menuitemradio":139                case "radio":140                case "scrollbar":141                case "searchbox":142                case "slider":143                case "spinbutton":144                case "switch":145                case "tab":146                case "textbox":147                case "tree":148                    return true;149                default:150                    return false;151            }152        }153        internal bool IsInteresting(bool insideControl)154        {155            if (_role == "Ignored" || _hidden)156            {157                return false;158            }159            if (Focusable || _richlyEditable)160            {161                return true;162            }163            // If it's not focusable but has a control role, then it's interesting.164            if (IsControl())165            {166                return true;167            }168            // A non focusable child of a control is not interesting169            if (insideControl)170            {171                return false;172            }173            return IsLeafNode() && !string.IsNullOrEmpty(_name);174        }175        internal SerializedAXNode Serialize()176        {177            var properties = new Dictionary<string, JToken>();178            foreach (var property in Payload.Properties)179            {180                properties[property.Name.ToLower()] = property.Value.Value;181            }182            if (Payload.Name != null)183            {184                properties["name"] = Payload.Name.Value;185            }186            if (Payload.Value != null)187            {188                properties["value"] = Payload.Value.Value;189            }190            if (Payload.Description != null)191            {192                properties["description"] = Payload.Description.Value;193            }194            var node = new SerializedAXNode195            {196                Role = _role,197                Name = properties.GetValueOrDefault("name")?.ToObject<string>(),198                Value = properties.GetValueOrDefault("value")?.ToObject<string>(),199                Description = properties.GetValueOrDefault("description")?.ToObject<string>(),200                KeyShortcuts = properties.GetValueOrDefault("keyshortcuts")?.ToObject<string>(),201                RoleDescription = properties.GetValueOrDefault("roledescription")?.ToObject<string>(),202                ValueText = properties.GetValueOrDefault("valuetext")?.ToObject<string>(),203                Disabled = properties.GetValueOrDefault("disabled")?.ToObject<bool>() ?? false,204                Expanded = properties.GetValueOrDefault("expanded")?.ToObject<bool>() ?? false,205                // WebArea"s treat focus differently than other nodes. They report whether their frame  has focus,206                // not whether focus is specifically on the root node.207                Focused = properties.GetValueOrDefault("focused")?.ToObject<bool>() == true && _role != "WebArea",208                Modal = properties.GetValueOrDefault("modal")?.ToObject<bool>() ?? false,...

Full Screen

Full Screen

SerializedAXNode.cs

Source:SerializedAXNode.cs Github

copy

Full Screen

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 = new SerializedAXNode[] { };1415        /// <summary>16        /// The <see fref="https://www.w3.org/TR/wai-aria/#usage_intro">role</see>.17        /// </summary>18        public string Role { get; set; }19        /// <summary>20        /// A human readable name for the node.21        /// </summary>22        public string Name { get; set; }23        /// <summary>24        /// The current value of the node.25        /// </summary>26        public string Value { get; set; }27        /// <summary>28        /// An additional human readable description of the node.29        /// </summary>30        public string Description { get; set; }31        /// <summary>32        /// Keyboard shortcuts associated with this node.33        /// </summary>34        public string KeyShortcuts { get; set; }35        /// <summary>36        /// A human readable alternative to the role.37        /// </summary>38        public string RoleDescription { get; set; }39        /// <summary>40        /// A description of the current value.41        /// </summary>42        public string ValueText { get; set; }43        /// <summary>44        /// Whether the node is disabled.45        /// </summary>46        public bool Disabled { get; set; }47        /// <summary>48        /// Whether the node is expanded or collapsed.49        /// </summary>50        public bool Expanded { get; set; }51        /// <summary>52        /// Whether the node is focused.53        /// </summary>54        public bool Focused { get; set; }55        /// <summary>56        /// Whether the node is <see href="https://en.wikipedia.org/wiki/Modal_window">modal</see>.57        /// </summary>58        public bool Modal { get; set; }59        /// <summary>60        /// Whether the node text input supports multiline.61        /// </summary>62        public bool Multiline { get; set; }63        /// <summary>64        /// Whether more than one child can be selected.65        /// </summary>66        public bool Multiselectable { get; set; }67        /// <summary>68        /// Whether the node is read only.69        /// </summary>70        public bool Readonly { get; set; }71        /// <summary>72        /// Whether the node is required.73        /// </summary>74        public bool Required { get; set; }75        /// <summary>76        /// Whether the node is selected in its parent node.77        /// </summary>78        public bool Selected { get; set; }79        /// <summary>80        /// Whether the checkbox is checked, or "mixed".81        /// </summary>82        public CheckedState Checked { get; set; }83        /// <summary>84        /// Whether the toggle button is checked, or "mixed".85        /// </summary>86        public CheckedState Pressed { get; set; }87        /// <summary>88        /// The level of a heading.89        /// </summary>90        public int Level { get; set; }91        /// <summary>92        /// The minimum value in a node.93        /// </summary>94        public int ValueMin { get; set; }95        /// <summary>96        /// The maximum value in a node.97        /// </summary>98        public int ValueMax { get; set; }99        /// <summary>100        /// What kind of autocomplete is supported by a control.101        /// </summary>102        public string AutoComplete { get; set; }103        /// <summary>104        /// What kind of popup is currently being shown for a node.105        /// </summary>106        public string HasPopup { get; set; }107        /// <summary>108        /// Whether and in what way this node's value is invalid.109        /// </summary>110        public string Invalid { get; set; }111        /// <summary>112        /// Whether the node is oriented horizontally or vertically.113        /// </summary>114        public string Orientation { get; set; }115        /// <summary>116        /// Child nodes of this node, if any.117        /// </summary>118        public SerializedAXNode[] Children { get; set; }119        /// <inheritdoc/>120        public bool Equals(SerializedAXNode other)121            => ReferenceEquals(this, other) ||122                (123                    Role == other.Role &&124                    Name == other.Name &&125                    Value == other.Value &&126                    Description == other.Description &&127                    KeyShortcuts == other.KeyShortcuts &&128                    RoleDescription == other.RoleDescription &&129                    ValueText == other.ValueText &&130                    AutoComplete == other.AutoComplete &&131                    HasPopup == other.HasPopup &&132                    Orientation == other.Orientation &&133                    Disabled == other.Disabled &&134                    Expanded == other.Expanded &&135                    Focused == other.Focused &&136                    Modal == other.Modal &&137                    Multiline == other.Multiline &&138                    Multiselectable == other.Multiselectable &&139                    Readonly == other.Readonly &&140                    Required == other.Required &&141                    Selected == other.Selected &&142                    Checked == other.Checked &&143                    Pressed == other.Pressed &&144                    Level == other.Level &&145                    ValueMin == other.ValueMin &&146                    ValueMax == other.ValueMax &&147                    (Children == other.Children || Children.SequenceEqual(other.Children))148                );149        /// <inheritdoc/>150        public override bool Equals(object obj) => obj is SerializedAXNode s && Equals(s);151        /// <inheritdoc/>152        public override int GetHashCode()153            => Role.GetHashCode() ^154                Name.GetHashCode() ^155                Value.GetHashCode() ^156                Description.GetHashCode() ^157                KeyShortcuts.GetHashCode() ^158                RoleDescription.GetHashCode() ^159                ValueText.GetHashCode() ^160                AutoComplete.GetHashCode() ^161                HasPopup.GetHashCode() ^162                Orientation.GetHashCode() ^163                Disabled.GetHashCode() ^164                Expanded.GetHashCode() ^
...

Full Screen

Full Screen

RootOptionTests.cs

Source:RootOptionTests.cs Github

copy

Full Screen

...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

...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            {47                needle = defaultRoot.Find(node => node.Payload.BackendDOMNodeId == backendNodeId);48                if (needle == null)49                {50                    return null;51                }52            }53            if (options?.InterestingOnly == false)54            {55                return SerializeTree(needle)[0];56            }57            var interestingNodes = new List<AXNode>();58            CollectInterestingNodes(interestingNodes, defaultRoot, false);59            if (!interestingNodes.Contains(needle))60            {61                return null;62            }63            return SerializeTree(needle, interestingNodes)[0];64        }65        private void CollectInterestingNodes(List<AXNode> collection, AXNode node, bool insideControl)66        {67            if (node.IsInteresting(insideControl))68            {69                collection.Add(node);70            }71            if (node.IsLeafNode())72            {73                return;74            }75            insideControl = insideControl || node.IsControl();76            foreach (var child in node.Children)77            {78                CollectInterestingNodes(collection, child, insideControl);79            }80        }81        private SerializedAXNode[] SerializeTree(AXNode node, List<AXNode> whitelistedNodes = null)82        {83            var children = new List<SerializedAXNode>();84            foreach (var child in node.Children)85            {86                children.AddRange(SerializeTree(child, whitelistedNodes));87            }88            if (whitelistedNodes?.Contains(node) == false)89            {90                return children.ToArray();91            }92            var serializedNode = node.Serialize();93            if (children.Count > 0)94            {95                serializedNode.Children = children.ToArray();96            }97            return new[] { serializedNode };...

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,16        /// <summary>17        /// Mixed.18        /// </summary>...

Full Screen

Full Screen

AXNode

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp;2using PuppeteerSharp.PageAccessibility;3using System;4using System.Collections.Generic;5using System.Linq;6using System.Text;7using System.Threading.Tasks;8{9    {10        static async Task Main(string[] args)11        {12            {13            };14            var browser = await Puppeteer.LaunchAsync(options);15            var page = await browser.NewPageAsync();16            var AXTree = await page.Accessibility.SnapshotAsync();17            var AXNode = AXTree.Nodes.FirstOrDefault(x => x.Role == AXRole.RootWebArea);18            var AXNode2 = AXNode.Children.FirstOrDefault(x => x.Role == AXRole.Search);19            var AXNode3 = AXNode2.Children.FirstOrDefault(x => x.Role == AXRole.TextField);20            await AXNode3.FocusAsync();21            await page.Keyboard.TypeAsync("Hello World");22            await page.ScreenshotAsync("screenshot.png");23            await browser.CloseAsync();24        }25    }26}27using PuppeteerSharp;28using PuppeteerSharp.PageAccessibility;29using System;30using System.Collections.Generic;31using System.Linq;32using System.Text;33using System.Threading.Tasks;34{35    {36        static async Task Main(string[] args)37        {38            {39            };40            var browser = await Puppeteer.LaunchAsync(options);41            var page = await browser.NewPageAsync();42            var AXTree = await page.Accessibility.SnapshotAsync();43            var AXNode = AXTree.Nodes.FirstOrDefault(x => x.Role == AXRole.RootWebArea);44            var AXNode2 = AXNode.Children.FirstOrDefault(x => x.Role == AXRole.Search);45            var AXNode3 = AXNode2.Children.FirstOrDefault(x => x.Role == AXRole.TextField);46            await AXNode3.FocusAsync();47            await page.Keyboard.TypeAsync("Hello World");48            await page.ScreenshotAsync("screenshot.png");49            await browser.CloseAsync();50        }51    }52}53using PuppeteerSharp;54using PuppeteerSharp.PageAccessibility;

Full Screen

Full Screen

AXNode

Using AI Code Generation

copy

Full Screen

1using System;2using System.IO;3using PuppeteerSharp;4using PuppeteerSharp.PageAccessibility;5{6    {7        static void Main(string[] args)8        {9            MainAsync(args).GetAwaiter().GetResult();10        }11        static async System.Threading.Tasks.Task MainAsync(string[] args)12        {13            var options = new LaunchOptions { Headless = true };14            using (var browser = await Puppeteer.LaunchAsync(options))15            {16                using (var page = await browser.NewPageAsync())17                {18                    var root = await page.Accessibility.SnapshotAsync();19                    await SaveAXTreeToFileAsync("AXTree.txt", root);20                }21            }22        }23        static async System.Threading.Tasks.Task SaveAXTreeToFileAsync(string fileName, AXNode node)24        {25            using (StreamWriter sw = new StreamWriter(fileName))26            {27                await sw.WriteLineAsync(node.ToString());28                if (node.Children != null)29                {30                    foreach (var child in node.Children)31                    {32                        await SaveAXTreeToFileAsync(fileName, child);33                    }34                }35            }36        }37    }38}

Full Screen

Full Screen

AXNode

Using AI Code Generation

copy

Full Screen

1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5    {6        static void Main(string[] args)7        {8            MainAsync().Wait();9        }10        static async Task MainAsync()11        {12            {13            };14            using (var browser = await Puppeteer.LaunchAsync(options))15            {16                using (var page = await browser.NewPageAsync())17                {18                    var tree = await page.Accessibility.SnapshotAsync();19                    Console.WriteLine(tree.ToString());20                }21            }22        }23    }24}25AXNode {26    AXNode {

Full Screen

Full Screen

AXNode

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;7{8    {9        static void Main(string[] args)10        {11            MainAsync().Wait();12        }13        static async Task MainAsync()14        {15            var browser = await Puppeteer.LaunchAsync(new LaunchOptions16            {17            });18            var page = await browser.NewPageAsync();19            var AXTree = await page.Accessibility.SnapshotAsync();20            PrintTree(AXTree, 0);21            Console.ReadLine();22        }23        static void PrintTree(AXNode node, int level)24        {25            string spaces = "";26            for (int i = 0; i < level; i++)27            {28                spaces += " ";29            }30            Console.WriteLine(spaces + node.Role);31            if (node.Children != null)32            {33                foreach (var child in node.Children)34                {35                    PrintTree(child, level + 1);36                }37            }38        }39    }40}41var links = AXTree.Children.Where(n => n.Role == "link");42foreach (var link in links)43{44}45var AXTree = await page.Accessibility.SnapshotAsync();46at PuppeteerSharp.CDPSession.SendAsync(String method, Object args, Boolean waitForCallback, Int32 timeout) in C:\projects\puppeteer-sharp\lib\PuppeteerSharp\CDPSession.cs:line 78

Full Screen

Full Screen

AXNode

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;8using System.IO;9using System.Threading;10{11    {12        static void Main(string[] args)13        {14            new Program().MainAsync().GetAwaiter().GetResult();15        }16        async Task MainAsync()17        {18            var options = new LaunchOptions { Headless = true };19            using (var browser = await Puppeteer.LaunchAsync(options))20            using (var page = await browser.NewPageAsync())21            {22                await page.WaitForSelectorAsync("input[name='q']");23                var accessibility = await page.Accessibility.SnapshotAsync();24                var tree = new AXNode(accessibility);25                Console.WriteLine(tree.Name);26                foreach (var child in tree.Children)27                {28                    Console.WriteLine(child.Name);29                }30            }31        }32    }33}34using System;35using System.Collections.Generic;36using System.Linq;37using System.Text;38using System.Threading.Tasks;39using PuppeteerSharp;40using PuppeteerSharp.PageAccessibility;41{42    {43        static void Main(string[] args)44        {45            new Program().Main

Full Screen

Full Screen

AXNode

Using AI Code Generation

copy

Full Screen

1using System;2using System.IO;3using System.Text;4using System.Threading.Tasks;5using PuppeteerSharp;6using PuppeteerSharp.PageAccessibility;7{8    {9        static async Task Main(string[] args)10        {11            {12                Args = new string[] { "--no-sandbox" }13            };14            var browser = await Puppeteer.LaunchAsync(options);15            var page = await browser.NewPageAsync();16            await page.GoToAsync(url);17            var tree = await page.GetAccessibilityTreeAsync();18            var writer = new StreamWriter("tree.txt");19            writer.WriteLine("using PuppeteerSharp.PageAccessibility;");20            writer.WriteLine("using System;");21            writer.WriteLine("using System.Collections.Generic;");22            writer.WriteLine("using System.Text;");23            writer.WriteLine("using Xunit;");24            writer.WriteLine("namespace PuppeteerSharp.PageAccessibility");25            writer.WriteLine("{");26            writer.WriteLine("    public class TestTree");27            writer.WriteLine("    {");28            writer.WriteLine("        [Fact]");29            writer.WriteLine("        public void Test()");30            writer.WriteLine("        {");31            writer.WriteLine("            var tree = new AXNode()");32            writer.WriteLine("            {");33            writer.WriteLine("                Role = AXRole.Document,");34            writer.WriteLine("                Name = \"\",");35            writer.WriteLine("                Value = null,");36            writer.WriteLine("                Description = null,");37            writer.WriteLine("                KeyShortcuts = null,");38            writer.WriteLine("                Roledescription = null,");39            writer.WriteLine("                Disabled = false,");40            writer.WriteLine("                Expanded = false,");41            writer.WriteLine("                Modal = false,");42            writer.WriteLine("                Selected = false,");43            writer.WriteLine("                Checked = AXValueUndefined.Undefined,");44            writer.WriteLine("                Pressed = AXValueUndefined.Undefined,");45            writer.WriteLine("                Level = null,");46            writer.WriteLine("                Valuemin = null,");47            writer.WriteLine("                Valuemax = null,");48            writer.WriteLine("                Valuetext = null,");

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.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful