Ramki (frames) są często wykorzystywane w nowoczesnych aplikacjach webowych, umożliwiając osadzanie jednej strony HTML w innej. Dzięki nim można między innymi ładować treści z różnych źródeł bez potrzeby przeładowywania całej strony. Mimo że ramki są przydatne, mogą też sprawiać trudności, zwłaszcza przy automatyzacji testów. Playwright, popularne narzędzie do testowania aplikacji webowych, oferuje funkcje do pracy z ramkami, ale ich efektywne użycie może wymagać pewnej praktyki.
W tym artykule omówimy podstawowe, jak i bardziej zaawansowane techniki pracy z ramkami w Playwright. Przedstawimy, jak prawidłowo wybierać ramki w testach, jak radzić sobie z ramkami ładowanymi dynamicznie oraz jak korzystać z zaawansowanych narzędzi, takich jak frameLocator() i evaluate(). Zrozumienie tych metod ułatwi radzenie sobie z wyzwaniami w pracy z ramkami, co pozwoli na bardziej efektywne testowanie aplikacji w różnych scenariuszach. To z kolei umożliwi wcześniejsze wykrywanie potencjalnych problemów, co pozytywnie wpłynie na jakość dostarczanego oprogramowania.
Podstawowe metody pracy z ramkami
Otwieranie strony z ramkami
Pierwszym krokiem w pracy z ramkami jest załadowanie strony, która zawiera te elementy. Playwright oferuje prostą metodę goto(), która umożliwia nawigację do wybranej strony. Jest to punkt wyjścia dla wszystkich operacji związanych z ramkami, ponieważ najpierw musimy załadować stronę, zanim będziemy mogli zacząć pracę z jej zawartością.
await page.goto('https://example.com/page-with-frames');
Wybieranie ramki
Aby rozpocząć pracę z konkretną ramką, w pierwszej kolejności musimy ją wybrać. Playwright oferuje kilka metod pozwalających na dostęp do ramki, w zależności od tego, jak jest ona zidentyfikowana w kodzie HTML. Możemy wybrać ramkę poprzez jej nazwę, selektor CSS lub indeks.
const frame = page.frame({ name: 'frameName' });
Alternatywnie, możemy skorzystać z selektora CSS:
const frame = page.frame({ url: /frame-url/ });
Interakcje z elementami w ramce
Po wybraniu ramki, możemy wykonywać na niej różne operacje, takie jak kliknięcia, wypełnianie formularzy czy oczekiwanie na elementy. Przykładowo, poniższy kod demonstruje wypełnienie pola tekstowego oraz kliknięcie przycisku w obrębie wybranej ramki.
await frame.click('button#submit');
await frame.fill('input[name="username"]', 'testuser');

Zaawansowane techniki pracy z ramkami
Obsługa dynamicznie ładowanych ramek
W niektórych aplikacjach ramki są dynamicznie ładowane po załadowaniu strony głównej. Oznacza to, że ramka pojawia się z pewnym opóźnieniem, co może być wyzwaniem dla testów automatycznych. W takich przypadkach konieczne jest użycie metody waitForFrame(), która umożliwia oczekiwanie na załadowanie ramki przed podjęciem dalszych działań.
const frame = await page.waitForFrame(frame => frame.url().includes('dynamic-frame-url'));
Przechodzenie między ramkami
Niektóre strony zawierają wiele ramek, co może wymagać przełączania się między nimi w trakcie testów. Playwright pozwala na łatwe przełączanie się między ramkami, co jest szczególnie przydatne w bardziej złożonych scenariuszach testowych.
const mainFrame = page.mainFrame();
const nestedFrame = mainFrame.childFrames()[0];
await nestedFrame.click('button#submit');
Praca z ramkami osadzonymi w innych ramkach
Gdy mamy do czynienia z ramkami osadzonymi wewnątrz innych ramek, praca staje się bardziej skomplikowana. Musimy najpierw uzyskać dostęp do ramki nadrzędnej, a dopiero potem do ramki podrzędnej. Poniższy kod pokazuje, jak to zrobić:
const parentFrame = page.frame({ name: 'parentFrame' });
const childFrame = parentFrame.frame({ name: 'childFrame' });
await childFrame.fill('input[name="email"]', 'example@example.com');
Inne przydatne metody pracy z ramkami
Metoda frameLocator()
Gdy mamy do czynienia z dynamicznie generowanymi stronami, nazwy ramek mogą być niestabilne lub trudne do przewidzenia. W takich sytuacjach przydatne jest użycie metody frameLocator(), która pozwala na odnalezienie ramki na podstawie bardziej złożonych kryteriów, takich jak właściwości elementów wewnątrz ramki.
Przykładowe zastosowanie metody frameLocator():
const frameLocator = page.frameLocator('iframe[src*="dynamic-frame"]');
const frame = await frameLocator.locate();
await frame.click('button#dynamic-button');
W powyższym przykładzie używamy frameLocator(), aby znaleźć ramkę zawierającą element <iframe> z atrybutem src, który zawiera frazę „dynamic-frame”. Następnie wykonujemy na niej kliknięcie na przycisku o ID „dynamic-button”. Ta metoda umożliwia elastyczne i precyzyjne lokalizowanie ramek nawet w przypadku zmieniającej się struktury dokumentu.
Metoda evaluate()
Metoda evaluate() umożliwia wykonywanie kodu JavaScript w kontekście ramki, co jest przydatne przy bardziej złożonych operacjach, takich jak manipulacja DOM-em lub wykonywanie niestandardowych akcji wewnątrz ramki.
await frame.evaluate(() => {
document.querySelector('button#submit').click();
});
Przykład testu z ramkami
Poniżej znajduje się przykład pełnego testu, który demonstruje użycie różnych metod pracy z ramkami w praktyce. Test ten sprawdza, czy po wypełnieniu formularza wewnątrz ramki użytkownik widzi odpowiedni komunikat sukcesu.
const { test, expect } = require('@playwright/test');
test('test form submission inside a frame', async ({ page }) => {
await page.goto('https://example.com/page-with-frames');
const frame = await page.waitForFrame(frame => frame.name() === 'formFrame');
await frame.fill('input[name="username"]', 'testuser');
await frame.fill('input[name="password"]', 'password123');
await frame.click('button[type="submit"]');
const successMessage = await frame.waitForSelector('.success');
expect(await successMessage.textContent()).toBe('Form submitted successfully');
});
W powyższym przykładzie test logowania sprawdza, czy po zalogowaniu użytkownik widzi odpowiedni komunikat sukcesu. Test ten wykorzystuje metody waitForFrame(), fill() oraz click(), aby symulować rzeczywiste działania użytkownika.

Podsumowanie
Opanowanie pracy z ramkami w Playwright jest kluczowe dla tworzenia solidnych i niezawodnych testów automatycznych. Ramki, jako elementy mogące dynamicznie zmieniać zawartość, stanowią szczególne wyzwanie, ale dzięki odpowiednim narzędziom możemy skutecznie nim zarządzać. Wprowadzenie zaawansowanych technik, takich jak waitForFrame() czy evaluate(), umożliwia tworzenie bardziej kompleksowych testów, które nie tylko sprawdzają funkcjonalność, ale również zachowanie aplikacji w różnych scenariuszach.
Tworzenie skutecznych testów automatycznych z wykorzystaniem ramek jest istotnym elementem współczesnego rozwoju oprogramowania, ponieważ pozwala na wcześniejsze wykrywanie błędów i systematyczną poprawę jakości aplikacji. Ramki mogą być stosowane na różne sposoby, dlatego warto poeksperymentować z różnymi metodami ich obsługi i dostosować je do specyficznych wymagań swojego projektu. W ten sposób można w pełni wykorzystać możliwości, jakie oferuje Playwright, co w dłuższej perspektywie przełoży się na lepsze i bardziej dopracowane oprogramowanie.
2 Comments
Ewelina Zaradzka
Super artykuł, akurat przydał mi się do pisania własnych testów z ramkami! 🙂
Paulina Jankowska
bardzo pomocny artykuł