Powrót do: Playwright Elements – Kluczowe koncepcje automatyzacji testów
Operacje na listach lokatorów
Prezentacja
👉jaktestowac/playwright-elements-locators
Sprawdzenie liczby znalezionych elementów
Lokatory są potężnym narzędziem do znajdowania elementów na stronie.
Lokatory mogą znajdować jeden lub więcej elementów.
Aby sprawdzić liczbę znalezionych elementów możemy skorzystać z metody count():
await elementLocator.count();
Przykładowy kod testu, w którym sprawdzamy, czy na stronie jest 7 elementów typu button:
test("All buttons on page", async ({ page }) => {
// Arrange:
const elementRole = "button";
// we can define the locator for the element
const buttonLocator = page.getByRole(elementRole);
// print the count of buttons on the page
console.log("buttonLocator", await buttonLocator.count());
// Assert:
// check if number of buttons is 7
await expect(buttonLocator).toHaveCount(7);
});
Częsty błąd w testach
W przypadku jeśli lokator wskazuje na więcej elementów, a my chcemy wykonać akcję na jednym z nich, to musimy precyzyjnie określić na którym elemencie chcemy wykonać daną akcję.
Jeśli tego nie zrobimy, to metoda do interakcji z elementami na stronie (np. click()) zwróci nam taki błąd:
Error: locator.click: Error: strict mode violation: getByRole('button') resolved to 7 elements:
1) aka getByTestId('open-practice')
2) aka getByRole('button', { name: 'Click me!' })
...
Zwróć uwagę, że w powyższym błędzie Playwright dokładnie określa ile elementów zostało znalezionych.
Również zauważ, że wypisana jest podpowiedź, jaki lokator/selektor zastosować, aby znaleźć dany pojedynczy element. Zwróć uwagę na ten fragment:
...aka getByTestId('open-practice')
...aka getByRole('button', { name: 'Click me!' })
Kod do lekcji
Początkowy kod
Początkowa zawartość pliku locator-lists.spec.ts:
import { test, expect } from "@playwright/test";
test.describe("Locator lists", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/practice/simple-multiple-elements-no-ids.html");
});
test("All buttons on page", async ({ page }) => {
// TODO:
});
test("action on nth button", async ({ page }) => {
// TODO:
});
test("action on multiple buttons", async ({ page }) => {
// TODO:
});
});
Finalny kod
Finalna zawartość pliku locator-lists.spec.ts:
import { test, expect } from "@playwright/test";
test.describe("Locator lists", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/practice/simple-multiple-elements-no-ids.html");
});
test("All buttons on page", async ({ page }) => {
// Arrange:
const elementRole = "button";
const expectedElementsCount = 7;
// we can define the locator for the element
const buttonLocator = page.getByRole(elementRole);
// print the count of buttons on the page
console.log("number of button elements:", await buttonLocator.count());
// Assert:
// check if number of buttons is 7
await expect(buttonLocator).toHaveCount(expectedElementsCount);
});
// unskip to see the error during test run
test.skip("❌ SHOULD FAIL ❌ - try clicking button (when multiple buttons are on page)", async ({
page,
}) => {
// Arrange:
const elementRole = "button";
// we can define the locator for the element
const buttonLocator = page.getByRole(elementRole);
// print the count of buttons on the page
console.log("number of button elements:", await buttonLocator.count());
// Assert:
// check if number of buttons is 7
await expect(buttonLocator).toHaveCount(7);
// ❌ because there are multiple buttons on the page
// ❌ following line will return an error:
await buttonLocator.click();
// ❌ with following error on console:
// Error: locator.click: Error: strict mode violation: getByRole('button') resolved to 7 elements:
// 1) aka getByTestId('open-practice')
// 2) aka getByRole('button', { name: 'Click me!' })
// 3) aka getByRole('button', { name: 'Click me too!' })
// 4) aka getByRole('button', { name: 'Click here!' })
// 5) aka getByRole('row', { name: 'Row 1 X Click!' }).getByRole('button')
// 6) aka getByRole('row', { name: 'Row 2 Y Click!' }).getByRole('button')
// 7) aka getByRole('row', { name: 'Row 3 Z Click!' }).getByRole('button')
});
test("action on nth button", async ({ page }) => {
// Arrange:
const elementRole = "button";
const resultsTestId = "dti-results";
const expectedMessage = "You clicked the button! (Second one!)";
const buttonLocator = page.getByRole(elementRole);
const resultsLocator = page.getByTestId(resultsTestId);
// print the count of buttons on the page
console.log("number of button elements:", await buttonLocator.count());
// Act:
// click on the 3rd button (we count from 0)
await buttonLocator.nth(2).click();
// display the text content of the results element
// console.log("results text content:", await resultsLocator.textContent());
// Assert:
await expect(resultsLocator).toHaveText(expectedMessage);
});
test("action on multiple buttons", async ({ page }) => {
// Arrange:
const elementRole = "button";
const elementText = "Click!";
const resultsTestId = "dti-results";
const buttonLocator = page.getByRole(elementRole, { name: elementText });
const resultsLocator = page.getByTestId(resultsTestId);
// print the count of buttons on the page
console.log("number of button elements:", await buttonLocator.count());
// Act:
// await buttonLocator.nth(0).click();
// console.log(await resultsLocator.textContent());
// await buttonLocator.nth(1).click();
// console.log(await resultsLocator.textContent());
// await buttonLocator.nth(2).click();
// console.log(await resultsLocator.textContent());
// usage of count() method
const numberOfFoundButtons = await buttonLocator.count();
for (let i = 0; i < numberOfFoundButtons; i++) {
await buttonLocator.nth(i).click();
// display the text content of the results element
console.log("results text content:", await resultsLocator.textContent());
}
// usage of all() method
for (const button of await buttonLocator.all()) {
await button.click();
console.log("results text content:", await resultsLocator.textContent());
}
// TODO: add assertions
});
});
Zewnętrzne linki i zasoby
- Nasza aplikacja 🦎GAD do testów: Aplikacja do testów – gdzie będziemy testować koncepty automatyzacji? lekcja o pobraniu, instalacji i uruchomieniu
- Oficjalnym repozytorium: GitHub / 🦎GAD
- Mini kurs, w którym opowiadamy szczegółowo o naszej aplikacji do testów: GAD - poznaj naszą autorską aplikację do nauki automatyzacji (🔒Tylko dla członków Programu Automatyzacja z Playwright)
- Strona do testów: [aplikacja GAD musi być uruchomiona lokalnie!] simple-multiple-elements-no-ids.html
- Oficjalna dokumentacja: Locator methods










A czemu tak?
Zmienne deklarowane jako const są stałe, co poprawia czytelność kodu i jasno pokazuje, że wartość nie powinna ulec zmianie.
Używanie const jest dobrą praktyką wszę
Pełna zgoda! 😀
Prawdopodobnie tutaj z rozpędu wykorzystałem
let😉 Zaktualizowałem kod – dzięki!