Powrót do: Praktyczne wprowadzenie do testów automatycznych z Playwright
Rozwiązanie – agregujemy akcje
TIP: Ta lekcja jest częścią rozwijanego Programu Testy Automatyczne z Playwright 🎭
Dodatkowe materiały
Rozwiązanie prezentowane w tej lekcji zajdziesz w naszym repozytorium: L11_pom_solution
Zawartość pulpit.page.ts:
import { Page } from '@playwright/test'; import { SideMenuComponent } from '../component/side-menu.component'; export class PulpitPage { constructor(private page: Page) {} sideMenuComponent = new SideMenuComponent(this.page); transferReceiverInput = this.page.locator('#widget_1_transfer_receiver'); transferAmountInput = this.page.locator('#widget_1_transfer_amount'); transferTitleInput = this.page.locator('#widget_1_transfer_title'); transferButton = this.page.getByRole('button', { name: 'wykonaj' }); actionCloseButton = this.page.getByTestId('close-button'); messageText = this.page.locator('#show_messages'); topUpReceiverInput = this.page.locator('#widget_1_topup_receiver'); topUpAmountInput = this.page.locator('#widget_1_topup_amount'); topUpAgreementCheckbox = this.page.locator( '#uniform-widget_1_topup_agreement span' ); topUpExecuteButton = this.page.getByRole('button', { name: 'doładuj telefon', }); moneyValueText = this.page.locator('#money_value'); userNameText = this.page.getByTestId('user-name'); async executeQuickPayment( receiverId: string, transferAmount: string, transferTitle: string ): Promise<void> { await this.transferReceiverInput.selectOption(receiverId); await this.transferAmountInput.fill(transferAmount); await this.transferTitleInput.fill(transferTitle); await this.transferButton.click(); await this.actionCloseButton.click(); } async executeMobileTopUp( topUpReceiver: string, topUpAmount: string ): Promise<void> { await this.topUpReceiverInput.selectOption(topUpReceiver); await this.topUpAmountInput.fill(topUpAmount); await this.topUpAgreementCheckbox.click(); await this.topUpExecuteButton.click(); await this.actionCloseButton.click(); } }
Zawartość pulpit.spec.ts:
import { test, expect } from '@playwright/test'; import { loginData } from '../test-data/login.data'; import { LoginPage } from '../pages/login.page'; import { PulpitPage } from '../pages/pulpit.page'; test.describe('Pulpit tests', () => { let pulpitPage: PulpitPage; test.beforeEach(async ({ page }) => { const userId = loginData.userId; const userPassword = loginData.userPassword; await page.goto('/'); const loginPage = new LoginPage(page); await loginPage.login(userId, userPassword); pulpitPage = new PulpitPage(page); }); test('quick payment with correct data', async ({ page }) => { // Arrange const receiverId = '2'; const transferAmount = '150'; const transferTitle = 'pizza'; const expectedTransferReceiver = 'Chuck Demobankowy'; // Act await pulpitPage.executeQuickPayment( receiverId, transferAmount, transferTitle ); // Assert await expect(pulpitPage.messageText).toHaveText( `Przelew wykonany! ${expectedTransferReceiver} - ${transferAmount},00PLN - ${transferTitle}` ); }); test('successful mobile top-up', async ({ page }) => { // Arrange const topUpReceiver = '500 xxx xxx'; const topUpAmount = '50'; const expectedMessage = `Doładowanie wykonane! ${topUpAmount},00PLN na numer ${topUpReceiver}`; // Act await pulpitPage.executeMobileTopUp(topUpReceiver, topUpAmount); // Assert await expect(pulpitPage.messageText).toHaveText(expectedMessage); }); test('correct balance after successful mobile top-up', async ({ page }) => { // Arrange const topUpReceiver = '500 xxx xxx'; const topUpAmount = '50'; const initialBalance = await pulpitPage.moneyValueText.innerText(); const expectedBalance = Number(initialBalance) - Number(topUpAmount); // Act await pulpitPage.executeMobileTopUp(topUpReceiver, topUpAmount); // Assert await expect(pulpitPage.moneyValueText).toHaveText(`${expectedBalance}`); }); });
A jak najlepiej uruchamiać jedną serię testów dla różnych userów (różne uprawnienia) tak aby nie dublować kodu?
Hej,
Dobre pytanie 🙂
Tu sporo zależy od konkretnych scenariuszów oraz testowanej aplikacji.
Tu się pojawiają dwie kwestie – uruchomienie testów z różnymi użytkownikami i implementacja testów, logiki i POM 🙂
Implementacja POM – tutaj można pójść prosto, czyli zaimplementować reprezentacje stron z punktu widzenia użytkownika, który może wykonać każdą operacje.
Plusem tego rozwiązani jest – prostota implementacji i brak dodatkowej logiki i duplikacji kodu w obiektach stron.
Minusem – my z poziomu testów musimy wiedzieć co dany użytkownik o danych uprawnieniach może wykonać, a czego nie może.
Bardziej skomplikowaną wersją jest dodanie dziedziczenia, ze stronami pochodnymi implementującymi akcje,w zależności od roli. To rozwiązanie zdejmuje z nas potrzebę pamiętania w testach co dany użytkownik może wykonać, natomiast może bardzo skomplikować implementacje samych page objectów.
Kwestia testów – inne testy będą dla użytkowników, którzy moga wejść na stronę X i zrobić Y, niz dla użytkowników, którzy nie mają dostępu do strony X.
Mozna je pogrupować w katalogi, albo tagi, a później możemy uruchamiać nasze testy z różnymi zestawami danych 🙂
Temat ten planujemy poruszyć w zaawansowanej części Programu o Playwright 🙂
Natomiast testy na różnych środowiskach (z wykorzystaniem różnych danych) opisujemy ogólnie w naszym poście: https://playwright.info/playwright-testy-na-roznych-srodowiskach – pokazujemy tam wykorzystanie projects w Playwright i biblioteki dotenv (którą też dokładnie omawiamy w części zaawansowanej).
Super artykuł dzięki. To było moje kolejne pytanie o różne środowiska. A jak w takim wypadku ustawia się różne dane logowania dla poszczególnych środowisk?
To dokładnie pokrywa punkt Sposób 2 (rozszerzony) z tego posta 😀
W dużym skrócie – możemy przygotować klika plików ze zmiennymi środowiskowymi, z których korzystamy w testach.
Każdy plik będzie odpowiadał danemu środowisku.
W kodzie dodajemy możliwość wyboru dowolnego pliku ze zmiennymi środowiskowymi 🙂
Później możemy np. podczas uruchamiania testów podac parametr, który mówi z jakim plikiem/na jakim środowisku chcemy puszczać testy np.:
a zmienne w testach (adresy, dane użytkowników etc) będą automatycznie pobierane z podanego przez nas pliku 🙂
Dzięki za odpowiedź Krzysiek, teraz wiem z której strony to ugryźć.
w kilku miejscach w kodzie na stronie macie:
): Promise$lt;void> {
Dzięki za zgłoszenie – wkradła mi się literówka/błąd w formatowaniu – poprawione! 🙂