Powrót do: Playwright Elements – Kluczowe koncepcje automatyzacji testów
Rozwiązanie – Chaining, filtrowanie i parametry w lokatorach
TIP: Cały kod testów z poszczególnych lekcji znajdziesz w specjalnie przygotowanym repozytorium:
jaktestowac/playwright-elements-locators
TIP: Ta lekcja jest częścią rozwijanego Programu Testy Automatyczne z Playwright
Przykładowe rozwiązanie
Rozwiązanie
import { test, expect } from "@playwright/test";
test.describe("Reservation", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/practice/simple-reservation-v1.html");
});
test("simple reservation with one feature", async ({ page }) => {
// Arrange:
const expectedMessage =
"Reservation for 23.10.2024 with features: Food for total price: 150$";
const resultsTestId = "dti-results";
const rowRole = "row";
const buttonRole = "button";
const checkboxRole = "checkbox";
const featureText = "Food";
const reservationDate = "23.10.2024";
const checkoutButtonText = "Checkout";
const resultsLocator = page.getByTestId(resultsTestId);
const checkboxLocator = page
.getByRole(rowRole, { name: featureText })
.getByRole(checkboxRole);
const reserveButtonLocator = page
.getByRole(rowRole, { name: reservationDate })
.getByRole(buttonRole);
const checkoutButtonLocator = page
.getByRole(buttonRole)
.filter({ hasText: checkoutButtonText });
// Act:
await checkboxLocator.check();
await reserveButtonLocator.click();
await checkoutButtonLocator.click();
// Assert:
await expect(resultsLocator).toHaveText(expectedMessage);
});
});
import { test, expect } from "@playwright/test";
test.describe("Reservation", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/practice/simple-reservation-v1.html");
});
test("simple reservation with one feature", async ({ page }) => {
// Arrange:
const expectedMessage =
"Reservation for 23.10.2024 with features: Food for total price: 150$";
const resultsTestId = "dti-results";
const rowRole = "row";
const buttonRole = "button";
const checkboxRole = "checkbox";
const featureText = "Food";
const reservationDate = "23.10.2024";
const checkoutButtonText = "Checkout";
const resultsLocator = page.getByTestId(resultsTestId);
const checkboxLocator = page
.getByRole(rowRole, { name: featureText })
.getByRole(checkboxRole);
const reserveButtonLocator = page
.getByRole(rowRole, { name: reservationDate })
.getByRole(buttonRole);
const checkoutButtonLocator = page
.getByRole(buttonRole)
.filter({ hasText: checkoutButtonText });
// Act:
await checkboxLocator.check();
await reserveButtonLocator.click();
await checkoutButtonLocator.click();
// Assert:
await expect(resultsLocator).toHaveText(expectedMessage);
});
});
import { test, expect } from "@playwright/test"; test.describe("Reservation", () => { test.beforeEach(async ({ page }) => { await page.goto("/practice/simple-reservation-v1.html"); }); test("simple reservation with one feature", async ({ page }) => { // Arrange: const expectedMessage = "Reservation for 23.10.2024 with features: Food for total price: 150$"; const resultsTestId = "dti-results"; const rowRole = "row"; const buttonRole = "button"; const checkboxRole = "checkbox"; const featureText = "Food"; const reservationDate = "23.10.2024"; const checkoutButtonText = "Checkout"; const resultsLocator = page.getByTestId(resultsTestId); const checkboxLocator = page .getByRole(rowRole, { name: featureText }) .getByRole(checkboxRole); const reserveButtonLocator = page .getByRole(rowRole, { name: reservationDate }) .getByRole(buttonRole); const checkoutButtonLocator = page .getByRole(buttonRole) .filter({ hasText: checkoutButtonText }); // Act: await checkboxLocator.check(); await reserveButtonLocator.click(); await checkoutButtonLocator.click(); // Assert: await expect(resultsLocator).toHaveText(expectedMessage); }); });
Hej, czy szukanie po nazwie jest wedlug was ok? Do utrzymania testow, nie lepiej byloby uzywac dokladniejszej sciezki, np nth?
Hej,
Bardzo dobre pytanie!
Wstępnie wspomnieliśmy o tym w lekcji Selektory i lokatory w Playwright – jak znajdować elementy na stronie https://jaktestowac.pl/lesson/pw5s01l03/#O_czym_warto_pamietac
Tak jak słusznie zauważyłeś – szukanie po nazwie (a technicznie – po tekście) może być mało odporne na zmiany (tekst czasem ulega zmianie, a w przypadku testów na różnych językach staje się problematyczne).
Dlatego naszym zdaniem znacznie lepiej szukać po ID lub data-testid.
Jedyną trudnością w tym przypadku – jest dodawanie takich atrybutów do elementów po stronie front-endu (nie w kazdym projekcie jest stosowana ta praktyka – warto przemyśleć wprowadzenie jej).