Локатор - це контракт, а не координата
CSS і XPath часто описують розташування кнопки, а не її призначення. Ролі, підписи та тестові ідентифікатори задають чіткіший контракт для Playwright.

Перекладне видання. Технічні ідентифікатори залишаються в оригінальній формі.
page.locator('.panel > div:nth-child(3) > button.primary') працює сьогодні. Завтра працює. Він продовжує працювати, доки дизайнер не перемістить кнопку на один слот ліворуч, а потім у вашому наборі виходить з ладу функція, яку ніхто не порушував. Ви не написали контрольну роботу. Ви написали фотографію DOM.
Що насправді рекомендує драматург
Документація Playwright є надзвичайно прямою щодо цього. Посібник із локаторів рекомендує розставляти пріоритети для призначених для користувача атрибутів і явних контрактів: getByRole, getByLabel, getByText, getByPlaceholder, getByTestId. Локатори ролей відображають те, як користувачі та допоміжні технології сприймають сторінку. Тестові ідентифікатори створюють окремий явний контракт ціною того, що вони невидимі для користувачів. Вони залишаються стабільними, лише якщо розробники дотримуються цього контракту. Селектори CSS і XPath задокументовані як крихкі, оскільки вони прив'язані до структури DOM, а структура DOM - це те, що змінюється.
Дві властивості фреймворку винагороджують хорошу звичку. Локатори повторно вирішуються перед кожною дією, тому повторне рендеринг між двома кроками не залишає вас утримувати застарілий елемент. І локатори суворі: якщо ваш селектор збігається з двома елементами, дія виконується замість тихого клацання першого. Сувора помилка в CI дратує півдня. Неправильний клік у неправильному діалоговому вікні - це звіт про помилку з вашим іменем.
Чому генератори першими тягнуться до шкідливої звички
Згенерований набір може досягти селектора, який вирішує поточну сторінку, не враховуючи, що змінить редизайн. Це ризик перегляду, а не доказ щодо даних навчання конкретної моделі. Тести, пов'язані з макетом, можуть бути успішними в перший день і зазнавати невдачі після зміни інтерфейсу з причин, не пов'язаних з поведінкою продукту.
Невдача дорого обходиться певним чином: комплект кричить вовком під час кожного редизайну, команда вчиться ігнорувати червоні збірки, а єдина справжня регресія пропливає крізь стіну знайомого шуму.
П'ятнадцятихвилинний аудит будь-якого набору
Grep ваші тести для page.locator з рядками CSS або XPath, а також для getByText, що використовується в інтерактивних елементах. Для кожного звернення задайте одне запитання: чи цей селектор називає, що таке елемент, або де він знаходиться? Замініть координати контрактами:
- Кнопки та посилання:
getByRoleз доступною назвою. - Поля форми:
getByLabelабоgetByPlaceholderяк запасний варіант. - Повторюваний або динамічний вміст:
data-testidузгоджено з розробниками. getByText: корисно для текстового вмісту; віддавати перевагу ролі та доступній назві під час натискання елемента керування.
У вас залишиться кілька справді неоднозначних елементів керування. Це не тестова проблема. Вони є проблемою доступності, яку тести щойно знайшли безкоштовно.
Пастка суворості, і when first() - це зізнання
Локатори драматурга суворі: дія над селектором, який відповідає двом елементам, кидає порушення замість вгадування. Розглядайте кожну помилку строгого режиму як питання дизайну. Якщо вам потрібен .first(), щоб пакет пройшов, одна з двох речей вірна: сторінка відображає дублікати елементів керування, які повинні мати різні доступні імена, або ваш селектор занадто широкий. І те, і інше є знахідками, а не незручностями. Виправлення полягає в тому, щоб звузити іменований контракт, відфільтрувати за стабільним батьківським або запитати тестовий ідентифікатор. Прагнення до .nth(1) через те, що другий збіг цього тижня виявився правильним, - це те, як пакети вчаться натискати неправильне діалогове вікно після наступного випуску.
Є один законний аварійний люк. locator.or() існує для випадків, коли сторінка чесно показує один із двох станів, як-от форма входу чи банер із уже виконаним входом. Використовуйте його навмисно, з обома названими альтернативами, і це читається як гілка. Використовуйте його, щоб подолати двозначність, і це буде сприйматися як знизування плечима.
Де підходять агенти
Дозвольте агенту вивчити та створити проект; локатори - це місце, де живе ваш відгук. Згенерований тест із getByRole('button', { name: 'Save' }) повідомляє вам, що, на його думку, робить сторінка. Згенерований тест за допомогою div:nth-child(3) не говорить вам нічого, крім того, що DOM виглядав так колись. Зберігайте перший вид. Перепишіть другу, перш ніж вона досягне CI, тому що кожен крихкий локатор, який ви приймаєте, є майбутньою помилковою тривогою, за яку ви вже заплатили.
Загальні запитання
Яка стратегія пошуку в Playwright є найнадійнішою?
Playwright рекомендує атрибути, які відкриваються користувачам, і явні контракти: атрибути getByRole, getByLabel, getByText і data-testid. Селектори CSS і XPath задокументовані як крихкі, оскільки вони поєднують тести зі структурою DOM.
Чи атрибути data-testid кращі за локатори ролей?
Вони вирішують різні проблеми. Тестові ідентифікатори зберігають будь-які візуальні чи структурні зміни, але нічого не говорять про те, що бачить користувач. Локатори ролей служать легкою перевіркою доступності. Більшість зрілих пакетів спочатку використовують ролі та мітки, перевіряють ідентифікатори для повторного або створеного вмісту.
Чому інструменти ШІ так часто генерують селектори CSS?
Генератор може вибрати селектор, який працює на поточній сторінці, не перевіряючи його стабільність під час редизайну. Причина залежить від інструменту; перевіряти вихідні дані, а не робити припущення щодо даних навчання.