TypeScript · @playwright/test
Agriculture with Playwright
Three tools in tabs: a sortable mandi price table with price alerts, a fertiliser calculator that turns soil-test levels into urea/DAP/MOP bag counts, and equipment rental with dates and day steppers.
App under test
🌾 FarmMart
- URL
- /apps/agri
- Login
- not required
- Bags
- 50 kg each
- Prices
- ₹ per quintal (fictional)
Scenarios to automate
Work top to bottom — each one adds a new technique.
- 1
Tab switching
Beginneragri-tab-* are role=tab with aria-selected; only the active panel is rendered.
- 2
Sort a column
Beginnersort-modal-price toggles descending/ascending; aria-sort on the header changes too.
- 3
Dependent data
IntermediateChanging price-state or price-crop reloads price-row rows and alert-market options.
- 4
Alert logic
IntermediateSetting an alert below the current price says “already above”; above it says “we'll notify you”.
- 5
Calculator maths
AdvancedWheat, 5 acres, soil N low / P medium / K high → urea 12, DAP 6, MOP 2 bags.
- 6
Calculator validation
BeginnerMissing crop/soil or area outside 0–100 shows fert-error.
- 7
Rental totals
Intermediaterental-total = per-day rate × rental-days; book-rental stays disabled until equipment and date are chosen.
Sample Playwright suite
A working starting point that finds elements every way Playwright can — by role, label, text, id, name, CSS, XPath and data-testid — so you practice them all. Pick your language, switch to data-testid only to compare, or try your own in the Locator Playground.
import { test, expect } from '@playwright/test';
// playwright.config.ts → use: { baseURL: 'https://www.practiceqaautomation.com' }
// Locators in this suite: getByRole ×5 · getByLabel ×3 · CSS ×3 · XPath ×3 · getByTestId ×10
test('checks prices, doses fertiliser and rents a tractor', async ({ page }) => {
await page.goto('/apps/agri');
await page.getByRole('combobox', { name: 'State' }).selectOption('Punjab');
await page.locator('#price-crop').selectOption('wheat');
await expect(page.getByTestId('modal-price').nth(0)).toContainText('2,490');
await page.getByTestId('sort-modal-price').click();
await expect(page.getByTestId('modal-price').nth(0)).toContainText('2,175');
await page.getByLabel('Alert me for').selectOption('Ludhiana');
await page.locator('#alert-price').fill('2400');
await page.locator('xpath=//button[normalize-space()="Set alert"]').click();
await expect(page.getByTestId('alert-message')).toContainText('already above');
await page.getByTestId('agri-tab-fertiliser').click();
await page.getByRole('combobox', { name: 'Crop' }).selectOption('wheat');
await page.getByLabel('Area (acres)').fill('5');
await page.getByRole('combobox', { name: 'Nitrogen (N)' }).selectOption('low');
await page.getByLabel('Phosphorus (P)').selectOption('medium');
await page.locator('#soil-k').selectOption('high');
await page.locator('xpath=//button[normalize-space()="Calculate"]').click();
await expect(page.getByTestId('fert-urea-bags')).toContainText('12');
await expect(page.getByTestId('fert-dap-bags')).toContainText('6');
await expect(page.getByTestId('fert-mop-bags')).toContainText('2');
await page.getByTestId('agri-tab-rental').click();
await page.getByTestId('equipment-tractor').click();
await page.getByTestId('rental-start').nth(0).click();
await page.getByRole('button', { name: 'Increase Days' }).click();
await page.getByRole('button', { name: 'Increase Days' }).click();
await expect(page.getByTestId('rental-total')).toContainText('₹3,600');
await page.locator('xpath=//button[normalize-space()="Book equipment"]').click();
await expect(page.getByTestId('rental-booked')).toContainText('RNT-');
});