{"flag":true,"single":true,"pageTitle":"Locators | Find elements and get there data","post":{"id":295,"user_id":"1","slug":"locators-find-elements-and-get-there-data-luao","title":"Locators | Find elements and get there data","body":"<p>Locators are the central piece of Playwright's auto-waiting and retry-ability. <a href=\"https:\/\/playwright.dev\/python\/docs\/locators\">https:\/\/playwright.dev\/python\/docs\/locators<\/a><\/p>\r\n<p style=\"text-align: center;\"><span style=\"font-size: 18pt;\"><strong>FIND ELEMENTS&nbsp;<\/strong><\/span><\/p>\r\n<p style=\"text-align: left;\"><strong><span style=\"text-decoration: underline;\"><span style=\"font-size: 18pt;\">1. FIND BY ROLE<\/span><\/span><\/strong><\/p>\r\n<p style=\"text-align: left;\"><strong><span style=\"text-decoration: underline;\">Locate by role&nbsp;<\/span> only use when you know clear roles ie don't use it for div finding<\/strong><br>When locating by role, you should usually pass the accessible name as well, so that the locator pinpoints the exact element.<\/p>\r\n<pre class=\"language-markup\"><code>page.getByRole(role{string}, options{object})<\/code><\/pre>\r\n<p>ie<\/p>\r\n<table style=\"border-collapse: collapse; width: 99.9988%;\" border=\"1\"><colgroup><col style=\"width: 49.9431%;\"><col style=\"width: 49.9431%;\"><\/colgroup>\r\n<tbody>\r\n<tr>\r\n<td>\r\n<pre class=\"language-markup\"><code>&lt;h3&gt;Sign up&lt;\/h3&gt;\r\n&lt;label&gt;\r\n  &lt;input type=\"checkbox\" \/&gt; Subscribe\r\n&lt;\/label&gt;\r\n&lt;br\/&gt;\r\n&lt;button&gt;Submit&lt;\/button&gt;<\/code><\/pre>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();\r\nawait page.getByRole('checkbox', { name: 'Subscribe' }).check();\r\nawait page.getByRole('button', { name: \/submit\/i }).click();<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p>&nbsp;<\/p>\r\n<table style=\"border-collapse: collapse; width: 99.9988%; height: 156.771px;\" border=\"1\"><colgroup><col style=\"width: 24.9716%;\"><col style=\"width: 24.9716%;\"><col style=\"width: 24.9716%;\"><col style=\"width: 24.9716%;\"><\/colgroup>\r\n<tbody>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>Role<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">ie<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>Role<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">ie<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>button<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Clickable button<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>combobox<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Dropdown<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>link &nbsp; &nbsp;<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">&lt;a&gt; link<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>list<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">&lt;ul&gt; \/ &lt;ol&gt;<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>heading &nbsp; &nbsp;<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">&lt;h1&gt; to &lt;h6&gt;<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>listitem<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">&lt;li&gt;<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>textbox<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Input field<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>dialog<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Modal<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>checkbox<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Checkbox<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>img<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Image<\/td>\r\n<\/tr>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\"><strong>radio<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Radio button<\/td>\r\n<td style=\"height: 22.3958px;\"><strong>table<\/strong><\/td>\r\n<td style=\"height: 22.3958px;\">Table<\/td>\r\n<\/tr>\r\n<tr>\r\n<td><strong>row<\/strong><\/td>\r\n<td>Table row<\/td>\r\n<td><strong>cell<\/strong><\/td>\r\n<td>Table cell<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p><strong>OPTIONS<\/strong><\/p>\r\n<table style=\"border-collapse: collapse; width: 99.9988%; height: 22.3958px;\" border=\"1\"><colgroup><col style=\"width: 14.0145%;\"><col style=\"width: 52.6948%;\"><col style=\"width: 33.3547%;\"><\/colgroup>\r\n<tbody>\r\n<tr style=\"height: 22.3958px;\">\r\n<td style=\"height: 22.3958px;\">name<\/td>\r\n<td style=\"height: 22.3958px;\">Text visible to users&nbsp;<br>Visible text<br>aria-label<br>aria-labelledby<br>associated &lt;label&gt;<\/td>\r\n<td style=\"height: 22.3958px;\">\r\n<pre class=\"language-markup\"><code>&lt;button&gt;Submit&lt;\/button&gt;\r\n&lt;button aria-label=\"Submit\"&gt;&lt;\/button&gt;<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>exact<\/td>\r\n<td>Match exact text (no partial match), ??? Matches: Submit<br>??? Not match: Submit Form<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>{ name: 'Submit', exact: true }<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>level<\/td>\r\n<td>\r\n<p>Specifies heading level (h1 &rarr; 1, h2 &rarr; 2)<\/p>\r\n<p>Only level works for headings,<br>page.getByRole('heading', { name: 'Dashboard' })<\/p>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>await page.getByRole('heading', { level: 1 })<\/code><\/pre>\r\n<p>It finds h1 only not h2<\/p>\r\n<pre class=\"language-markup\"><code>&lt;h1&gt;Welcome&lt;\/h1&gt;<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>checked<\/td>\r\n<td>\r\n<p>Filters checked checkbox\/radio<\/p>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.getByRole('checkbox', { checked: true })<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>selected<\/td>\r\n<td>\r\n<p>For selected option in dropdown\/list<\/p>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.getByRole('option', { selected: true })<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>disabled<\/td>\r\n<td>\r\n<p>Finds disabled elements<\/p>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.getByRole('button', { disabled: true })<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p><br><strong>EXAMPLE: <\/strong><\/p>\r\n<p><strong>heading &rarr; role , level: 1 &rarr; &lt;h1&gt; ,checking text = Welcome<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>await expect(page.getByRole('heading', { level: 1 })).toHaveText('Welcome');<\/code><\/pre>\r\n<p><strong>Buttons:<br><\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.getByRole('button', { name: 'Login' })\r\npage.getByRole('button', { name: \/login\/i }) \/\/ regex (case insensitive)\r\npage.getByRole('button', { name: 'Save', exact: true })<\/code><\/pre>\r\n<p><strong>Inputs:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.getByRole('textbox', { name: 'Email' })\r\npage.getByRole('textbox', { name: 'Search' })\r\npage.getByRole('textbox').nth(0) \/\/ if no label<\/code><\/pre>\r\n<p><strong><span style=\"text-decoration: underline;\"><span style=\"font-size: 18pt;\">1. FIND BY LOCATOR<\/span><\/span><\/strong><\/p>\r\n<p>&nbsp;It creates a <strong>Locator <\/strong>object that targets elements using a selector.&nbsp;<\/p>\r\n<pre class=\"language-markup\"><code>locator = page.locator(\"CSS selector, text selector, XPath\")<\/code><\/pre>\r\n<table style=\"border-collapse: collapse; width: 99.9988%;\" border=\"1\"><colgroup><col style=\"width: 33.3333%;\"><col style=\"width: 33.3333%;\"><col style=\"width: 33.3333%;\"><\/colgroup>\r\n<tbody>\r\n<tr>\r\n<td>CSS LOCATOR<\/td>\r\n<td>TEXT<\/td>\r\n<td>XPATH<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.locator(\"button\")\r\npage.locator(\"#login\")\r\npage.locator(\".card\")\r\npage.locator(\"div &gt; span\")\r\npage.locator(\"input[type='text']\")<\/code><\/pre>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.locator(\"text=Submit\")<\/code><\/pre>\r\n<\/td>\r\n<td>\r\n<pre class=\"language-markup\"><code>page.locator(\"\/\/button[text()='Submit']\")<\/code><\/pre>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p>Advance locators :&nbsp;<\/p>\r\n<pre class=\"language-markup\"><code>page.locator(\"div:has-text('Hello')\")\r\npage.locator(\"div:has(button)\")\r\npage.locator(\"button:visible\")\r\npage.locator(\"button\").nth(0)<\/code><\/pre>\r\n<p><strong>Locator is LAZY (VERY IMPORTANT)&nbsp;<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator = page.locator(\"button\") #??? No DOM query yet, ??? No error even if element doesn&rsquo;t exist\r\nlocator.click() #Only runs when<\/code><\/pre>\r\n<p><strong>Locator is Strict Mode ??? Error if multiple elements&nbsp;<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.locator(\"button\").click() #WRONG\r\npage.locator(\"button\").first.click()\r\npage.locator(\"button\").nth(1).click()<\/code><\/pre>\r\n<p><strong>Chaining Locators (VERY POWERFUL) means, Find all div =&gt;&nbsp;Inside them find button<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.locator(\"div\").locator(\"button\")<\/code><\/pre>\r\n<p><strong>Multiple Elements Handling<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.count()\r\nlocator.nth(0)\r\nlocator.first\r\nlocator.last<\/code><\/pre>\r\n<pre class=\"language-markup\"><code>profile_link = question_box.locator('a[href*=\"\/profile\/\"]').first \r\nawait profile_link.wait_for(state=\"visible\", timeout=3000) #MAX WAIT<\/code><\/pre>\r\n<p><strong>Locator Actions:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.click()\r\nlocator.fill(\"text\")\r\nlocator.type(\"text\")\r\nlocator.hover()\r\nlocator.press(\"Enter\")\r\nlocator.check()\r\nlocator.uncheck()\r\n\r\nlocator.wait_for(state=\"visible\") #attached , detached , visible , hidden<\/code><\/pre>\r\n<p><strong>Find single element:&nbsp;<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locater = page.get_by_placeholder(\"e.g Cheetos\")\r\nlocater = page.get_by_text(\"Bitcoin in Islam\")  # working for all page text any where, or inside any element<\/code><\/pre>\r\n<p><strong>Find Multiple Elements:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>articles = page.get_by_role(\"article\") # all articles \r\nfor i in range(articles.count()):\r\n    article = articles.nth(i)\r\n    text = article.text_content()[:100]  # First 100 chars for brevity\r\n    print(f\"Article {i}: {text}...\")<\/code><\/pre>\r\n<p><strong>By Place Holder:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locater = page.get_by_placeholder(\"e.g Cheetos\")<\/code><\/pre>\r\n<p><strong>Find element by text:<br><\/strong># working for all page text any where, or inside any element<strong><br><\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locater = page.get_by_text(\"Bitcoin in Islam\")  <\/code><\/pre>\r\n<p><strong>Find By alt text:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.get_by_alt_text(\"My image 1\")<\/code><\/pre>\r\n<p><strong>Locate By CSS\/xpath:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.locator(\"css=button\").click()\r\npage.locator(\"xpath=\/\/button\").click()<\/code><\/pre>\r\n<pre class=\"language-markup\"><code>page.locator(\r\n    \"#tsf &gt; div:nth-child(2) &gt; div.A8SBwf &gt; div.RNNXgb &gt; div &gt; div.a4bIc &gt; input\"\r\n).click()<\/code><\/pre>\r\n<p><strong>If multiple items, First find it and then use it Filter<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.get_by_role(\"listitem\").filter(has_text=\"Product 2\").get_by_role(\r\n    \"button\", name=\"Add to cart\"\r\n).click()<\/code><\/pre>\r\n<p><strong>Wait for locaters<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>order_sent = page.locator(\"#order-sent\")\r\norder_sent.wait_for() #\"attached\" present in DOM| \"detached\" not present| \"visible\" (default) | \"hidden\" (optional)<\/code><\/pre>\r\n<p><strong>Find Element with multiple conditions<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>button = page.get_by_role(\"button\").and_(page.getByTitle(\"Subscribe\")) #Locator, <\/code><\/pre>\r\n<p style=\"text-align: center;\">&nbsp;<\/p>\r\n<p># 1. profile link (VERY specific)<br>#FIND<br>profile_link = question_box.locator('a[href*=\"\/profile\/\"]').first&nbsp;<\/p>\r\n<p>#ASSERT<br>await profile_link.wait_for(state=\"visible\", timeout=3000)<br>#get attribute<br>profile_url = await profile_link.get_attribute('href')<br>print(\"Profile URL:\", profile_url)<br>#get text of element<br>profile_name = await profile_name_el.inner_text()<\/p>\r\n<p>await profile_link.click()<\/p>\r\n<p style=\"text-align: center;\"><span style=\"font-size: 18pt;\"><strong>Play with Finded Elements<\/strong><\/span><\/p>\r\n<p style=\"text-align: left;\">&nbsp;<\/p>\r\n<p><strong>For Multiple Items loop<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>for row in page.get_by_role(\"listitem\").all():\r\n    print(row.text_content())<\/code><\/pre>\r\n<p><strong>Inner Text : # <\/strong>Returns an array of <strong>node.innerText<\/strong> list values<\/p>\r\n<pre class=\"language-markup\"><code>texts = page.get_by_role(\"link\").all_inner_texts() <\/code><\/pre>\r\n<p><strong>All Text Contents: #<\/strong>Returns an array of <strong>node.textContent<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>texts = page.get_by_role(\"link\").all_text_contents() <\/code><\/pre>\r\n<p><strong>Get Attribute:<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.get_attribute(name)<\/code><\/pre>\r\n<p><strong>Highlight the element: #################<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.get_by_role(\"button\").highlight()<\/code><\/pre>\r\n<p><strong>Inner Html<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.inner_html()<\/code><\/pre>\r\n<p><strong>Only Visible text: return string<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.inner_text()<\/code><\/pre>\r\n<p><strong>Outer HTML<\/strong><\/p>\r\n<pre class=\"language-markup\"><code> outer_html = su.evaluate(\"element =&gt; element.outerHTML\") <\/code><\/pre>\r\n<p><strong>First Element find<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>banana = page.get_by_role(\"listitem\").nth(0)<\/code><\/pre>\r\n<pre class=\"language-markup\"><code>banana = page.get_by_role(\"listitem\").last\r\napple = page.get_by_role(\"listitem\").first<\/code><\/pre>\r\n<p><strong>Screenshoot<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>page.get_by_role(\"link\").screenshot()<\/code><\/pre>\r\n<p><strong>Text Of Element<\/strong><\/p>\r\n<pre class=\"language-markup\"><code>locator.text_content()<\/code><\/pre>\r\n<p>&nbsp;<\/p>","category_id":"37","is_private":"0","created_at":"2025-03-06T00:19:43.000000Z","updated_at":"2026-04-06T00:05:29.000000Z","category":{"id":37,"user_id":"1","name":"Playwright","slug":"playwright-c2zf","parent_id":null,"created_at":"2025-03-05T22:35:12.000000Z","updated_at":"2025-03-05T22:35:12.000000Z"},"user":{"id":1,"name":"R GONDAL","email":"rizikmw@gmail.com","email_verified_at":null,"two_factor_confirmed_at":null,"current_team_id":"1","profile_photo_path":null,"created_at":"2023-03-12T10:49:33.000000Z","updated_at":"2025-01-10T12:59:00.000000Z","profile_photo_url":"https:\/\/ui-avatars.com\/api\/?name=R+G&color=7F9CF5&background=EBF4FF"}},"pageDesc":"Locators are the central piece of Playwright's auto-waiting and retry-ability. https:\/\/playwright.dev\/python\/docs\/locators FIND ELEMENTS&nbs - Locators | Find elements and get there data (Updated: April 6, 2026) - Read more about Locators | Find elements and get there data at my programming site [SITE]","categories":[]}