👨💻 Kod / Programowanie
Jak przetestować kliknięcie w link otwierający nowe okno (i uniknąć niepotrzebnych akcji)
Pokażę Ci jak możesz przetestować w izolacji kliknięcie w link, który otwiera nową zakładkę w przeglądarce.
Motywacja
Gdy potrzebujemy wykonać pewne akcje w testach czasem warto wyciszyć wszystkie zbędne akcje aby skupić się atomowo na danym efekcie.
Dodatkowo może się zdarzyć tak, że kliknięcie w link uruchamia procesy, których chcemy uniknąć.
Przykładowy scenariusz:
Kliknięcie w ikonę GitHub na stronie playwright.dev otwiera nową kartę ze stroną repozytorium Playwright w GitHub.
Implementacja kliknięcia bez izolacji
Poniższy test, różni się od najprostszych testów jedynie przechwyceniem nowego okna po kliknięciu w link.
import { expect, test } from '@playwright/test'; test('verify link in new tab', async ({ page }) => { await page.goto('https://playwright.dev/'); // start waiting for new tab const newTabPromise = page.waitForEvent('popup'); await page.getByRole('link', { name: 'GitHub repository' }).click(); // resolve waiting for new tab, get new tab (it is treated as new page) const newTab = await newTabPromise; await expect(newTab).toHaveURL('https://github.com/microsoft/playwright'); }
Efekt: nowa zakładka jest w pełni działająca, wszystkie procesy są uruchamiane wraz z przejściem pod nowy adres.
Po wykonaniu takiej akcji generujemy tyle ruchu:
Przyznaj, że 90 zapytań i 2.5MB to całkiem sporo jak na jeden test 😀
W dodatku te dane nam nie są potrzebne gdyż nie testujemy tutaj GitHub tylko chcemy sprawdzić czy kliknęliśmy prawidłowy link.
Implementacja z izolacją
Poniżej dodałem komentarze aby opisać dane kroki
test('should redirect user to new tab after using clicking link', async ({ page, context }) => { // Arrange const expectedUrl = 'https://github.com/microsoft/playwright'; await page.goto('https://playwright.dev/'); await page.waitForLoadState(); // wait for new tab const newTabPromise = page.waitForEvent('popup'); // drop all network traffic from now (we don't need it) await context.route('**/*', (route) => route.abort()); // prepare variable to store url of actiion after clicking link let observedURL = 'unknown'; // listen for action what will be triggered after link clicking context.on('request', (request) => { observedURL = request.url(); }); // Act await page.getByRole('link', { name: 'GitHub repository' }).click(); // resolve waitng for new tab const newTab = await newTabPromise; // Assert // chcek if correct url was used expect(observedURL).toContain(expectedUrl); // check if new tab appeared expect(newTab.isClosed()).toBe(false); });
Tym razem po kliknięciu w link sprawdzamy wyłącznie uruchomienie nowej zakładki i użyty w tym procesie link.
Cały ruch sieciowy jest pomijany więc uzyskujemy spore oszczędności.
Docelowy serwis nie wie, że próbowaliśmy do niego przejść💪
Omówmy najciekawsze kawałki kodu
1.
await context.route("**/*", (route) => route.abort());
Od momentu dodatnia tego kodu do testu ignorujemy wszystkie akcje przeglądarki związane z ruchem sieciowym.
2.
context.on("request", (request) => {
observedURL = request.url();
});
W tym przypadku pobieramy adres url z napotkanego zapytania. Testowana strona nie wytwarza ruchu sieciowego po załadowaniu więc możemy tutaj w spokoju nasłuchiwać kliknięcia w link.
W przypadku stron, które wysyłają zapytania po zakończonym ładowaniu (np Google, lub GitHub) trzeba by było tę metodę rozszerzyć o filtrowanie zapytań po jakimś unikalnym wzorcu.
3.
expect(newTab.isClosed()).toBe(false);
Na koniec sprawdzamy czy tab nie jest zamknięty, gdyż jest to najszybsza metoda do sprawdzenia czy tab jest aktywny. Z powodu ignorowania ruchu sieciowego Playwright nie jest w stanie wyciągnąć więcej informacji z tej zakładki.
To wszytko na dzisiaj👇
❤️ Podobało się? Wrzuć like na 🔗 GitHub
💡 Chcesz coś dodać? Wrzuć nam taska na 🔗 GitHub
Linki
Oficjalna dokumentacja do zarządzania nowymi oknami: