Home | RU | EN

Locators Cheat Sheet XPath & CSS — Selenide / Selenium / Playwright (Python)

Схемы, примеры, и варианты кода. В колонке Selenide даны несколько наиболее удобных способов.

XPath

Rule Schema Example Comment Selenide (варианты) Selenium Playwright (python)
tag & attribute //tag[@attribute="value"] //input[@placeholder="Username"] Находит элемент по тэгу и атрибуту $(byXpath("//input[@placeholder='Username']")) driver.findElement(By.xpath("//input[@placeholder='Username']")) page.locator("xpath=//input[@placeholder='Username']")
page.get_by_placeholder("Username")
text() //tag[text()="value"] //button[text()="Login"] Полное совпадение прямого текстового узла элемента. Не сматчит текст внутри вложенных тегов (<button><span>Login</span></button>). Для устойчивости к пробелам и вложениям используют normalize-space(.)="…" или просто .="…". $(byText("Login"))
$$("button").findBy(text("Login"))
$(byXpath("//button[text()='Login']"))
driver.findElement(By.xpath("//button[text()='Login']")) page.get_by_text("Login", exact=True)
page.locator("xpath=//button[text()='Login']")
contains() (text) //tag[contains(text(),"value")] //div[contains(text(),"Error")] Частичное совпадение прямого текстового узла. Текст внутри вложенных тегов так не находится; для «всего текста элемента» — contains(., "Error") или contains(normalize-space(.), "Error"). $(withText("Error"))
Генерирует примерно такой XPath: .//*[contains(normalize-space(.),'Error')]
$(byXpath("//div[contains(text(),'Error')]"))
driver.findElement(By.xpath("//div[contains(text(),'Error')]")) page.get_by_text("Error")
page.locator("xpath=//div[contains(text(),'Error')]")
contains() (attr) //tag[contains(@attribute,"value")] //input[contains(@placeholder,"Usern")] Частичное совпадение значения атрибута $(byXpath("//input[contains(@placeholder,'Usern')]")) driver.findElement(By.xpath("//input[contains(@placeholder,'Usern')]")) page.locator("xpath=//input[contains(@placeholder,'Usern')]")
multiple attributes //tag[rule1][rule2] //input[@type="text"][@name="login"] Несколько условий $("input[type='text'][name='login']")
$(byCssSelector("input[type='text'][name='login']"))
$(byXpath("//input[@type='text'][@name='login']"))
driver.findElement(By.xpath("//input[@type='text'][@name='login']")) page.locator("input[type='text'][name='login']")
page.locator("xpath=//input[@type='text'][@name='login']")
moving through the tree //parent/child //div/span Прямой потомок (один уровень вниз). В XPath / — строго дочерний шаг; для «любой глубины» нужно //div//span. CSS-эквивалент — div > span, а не div span. $("div > span")
$(byXpath("//div/span"))
driver.findElement(By.xpath("//div/span")) page.locator("div > span")
page.locator("xpath=//div/span")
not() //tag[not(contains(@attr,"v"))] //input[not(contains(@type,"hidden"))] Исключение по условию $(byXpath("//input[not(contains(@type,'hidden'))]")) driver.findElement(By.xpath("//input[not(contains(@type,'hidden'))]")) page.locator("xpath=//input[not(contains(@type,'hidden'))]")
indexing (//tag[@attr="v"])[N] (//input[@type="text"])[2] N‑й элемент в выборке. Нумерация в XPath начинается с 1; в Selenide-коллекциях $$().get(i) — с 0, поэтому get(1)(…)[2]. $$("input[type='text']").get(1)
$(byXpath("(//input[@type='text'])[2]"))
driver.findElement(By.xpath("(//input[@type='text'])[2]")) page.locator("input[type='text']").nth(1)
page.locator("xpath=(//input[@type='text'])[2]")
parent //tag/.. //input/.. Переход к родителю $(byXpath("//input/..")) driver.findElement(By.xpath("//input/..")) page.locator("xpath=//input/..")
following-sibling //tag/following-sibling::tag2 //label/following-sibling::input Все подходящие среди следующих братьев на том же уровне. Ось following-sibling::… сама по себе значит: «все подходящие tag2 среди следующих братьев», а не «первый попавшийся». $(byXpath("//label/following-sibling::input")) driver.findElement(By.xpath("//label/following-sibling::input")) page.locator("xpath=//label/following-sibling::input")
preceding-sibling //tag/preceding-sibling::tag2 //input/preceding-sibling::label Все подходящие среди предыдущих братьев на том же уровне. Ось preceding-sibling::… сама по себе значит: «все подходящие tag2 среди предыдущих братьев», а не «ближайший слева». $(byXpath("//input/preceding-sibling::label")) driver.findElement(By.xpath("//input/preceding-sibling::label")) page.locator("xpath=//input/preceding-sibling::label")
ancestor //tag/ancestor::X //span/ancestor::form Все подходящие предки выше по дереву (а не «один любой»). Для ближайшего предка — ancestor::form[1]. $(byXpath("//span/ancestor::form")) driver.findElement(By.xpath("//span/ancestor::form")) page.locator("xpath=//span/ancestor::form")

CSS Selectors (у CSS нет функций text() и contains())

Rule Schema Example Comment Selenide (варианты) Selenium Playwright (python)
tag & attribute tag[attribute="value"] input[aria-label="Search"] По тегу и точному значению атрибута $("input[aria-label='Search']")
$(byAttribute("aria-label","Search"))
$(byCssSelector("input[aria-label='Search']"))
driver.findElement(By.cssSelector("input[aria-label='Search']")) page.locator("input[aria-label='Search']")
id #id #loginBtn По id $("#loginBtn")
$(byId("loginBtn"))
driver.findElement(By.id("loginBtn")) page.locator("#loginBtn")
page.locator("[id='loginBtn']")
class name .className .btn-primary По классу $(".btn-primary")
$(byClassName("btn-primary"))
driver.findElement(By.className("btn-primary")) page.locator(".btn-primary")
multiple class names .class1.class2 .btn.large Два класса одновременно $(".btn.large")
$(byCssSelector(".btn.large"))
driver.findElement(By.cssSelector(".btn.large")) page.locator(".btn.large")
attribute *= [attribute*="value"] input[placeholder*="user"] Атрибут содержит подстроку. byAttribute(name, value) сюда не подходит — он генерирует точное совпадение [name="value"]. $("input[placeholder*='user']")
$(byCssSelector("input[placeholder*='user']"))
driver.findElement(By.cssSelector("input[placeholder*='user']")) page.locator("input[placeholder*='user']")
attribute ^= [attribute^="value"] input[placeholder^="user"] Атрибут начинается с $("input[placeholder^='user']")
$(byCssSelector("input[placeholder^='user']"))
driver.findElement(By.cssSelector("input[placeholder^='user']")) page.locator("input[placeholder^='user']")
attribute $= [attr$="value"] img[src$=".png"] Атрибут заканчивается на $("img[src$='.png']")
$(byCssSelector("img[src$='.png']"))
driver.findElement(By.cssSelector("img[src$='.png']")) page.locator("img[src$='.png']")
name / link text (полезно знать) a:contains(text) - (нет в чистом CSS) Ссылки по тексту В CSS нет поиска по тексту - используем API $(byLinkText("Home"))
$(byPartialLinkText("Hom"))
driver.findElement(By.linkText("Home"))
driver.findElement(By.partialLinkText("Hom"))
page.get_by_role("link", name="Home")
page.locator("a").filter(has_text="Hom")

Импорты (Selenide): import static com.codeborne.selenide.Selenide.*;, import static com.codeborne.selenide.Selectors.*;, import static com.codeborne.selenide.Condition.*;

Playwright (Python): в примерах используется объект page из playwright.sync_api (например после browser.new_page()).