PracticeQAAutomation logoPracticeQAAutomation
Pw

TypeScript · @playwright/test

Legal with Playwright

Filter lawyers by practice area, city and language and book a consultation; then generate a rental agreement through a wizard with a live document preview, cross-field rules, typed e-signatures and a stamp-duty calculation.

App under test

⚖️ LexDesk

URL
/apps/legal
Deposit cap
6 × monthly rent
Stamp duty
0.25% (min ₹100)
Consult days
closed Sundays

Scenarios to automate

Work top to bottom — each one adds a new technique.

  1. 1

    Directory filters

    Beginner

    area-*, lawyer-city, lawyer-language and lawyer-sort change lawyer-count and order.

  2. 2

    Booking modal validation

    Intermediate

    confirm-consult without mode/day/time or with a short description shows consult-error.

  3. 3

    Live preview

    Intermediate

    Typing in the wizard updates preview-* fields immediately; blanks show underscores.

  4. 4

    Cross-field rules

    Advanced

    Deposit above 6 months' rent and landlord = tenant are rejected with specific error-* messages.

  5. 5

    Exact-match signatures

    Intermediate

    landlord-signature / tenant-signature must match the names exactly (case and spaces).

  6. 6

    Stamp duty maths

    Intermediate

    ₹25,000 × 11 months + ₹1,50,000 deposit → stamp-duty ₹1,063.

  7. 7

    Wizard navigation

    Beginner

    doc-back keeps entered values; the stepper marks completed steps.

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.

Language
lexdesk.spec.ts
import { test, expect } from '@playwright/test';

// playwright.config.ts → use: { baseURL: 'https://www.practiceqaautomation.com' }
// Locators in this suite: getByRole ×4 · getByLabel ×5 · CSS ×6 · XPath ×2 · getByTestId ×13
test('books a lawyer and signs a rental agreement', async ({ page }) => {
  await page.goto('/apps/legal');
  await page.getByRole('button', { name: 'Property' }).click();
  await expect(page.getByTestId('lawyer-count')).toContainText('2 lawyers');
  await page.locator('#lawyer-sort').selectOption('fee');
  await page.getByTestId('book-l4').click();
  await page.locator('xpath=//button[normalize-space()="Video"]').click();
  await page.locator('[data-testid="consult-day"]:not([disabled])').first().click();
  await page.getByLabel('Time').selectOption('12:00');
  await page.getByLabel('Your matter').fill('Need a review of my rental agreement before signing.');
  await page.getByTestId('confirm-consult').click();
  await expect(page.getByTestId('consult-booked')).toContainText('LX-');

  // Generate a rental agreement
  await page.getByRole('link', { name: 'Create agreement' }).click();
  await page.locator('#landlord-name').fill('Meera Kulkarni');
  await page.getByLabel('Tenant (licensee) full name').fill('Amir Khan');
  await expect(page.getByTestId('preview-tenant')).toContainText('Amir Khan');
  await page.getByTestId('doc-next').click();
  await page.locator('#property-address').fill('Flat 12B, Palm Residency, Baner');
  await page.getByRole('combobox', { name: 'City' }).selectOption('Pune');
  await page.getByTestId('doc-next').click();
  await page.locator('#monthly-rent').fill('25000');
  await page.locator('#security-deposit').fill('150000');
  await page.getByRole('combobox', { name: 'Term' }).selectOption('11');
  await page.getByTestId('agreement-start').nth(0).click();
  await expect(page.getByTestId('preview-rent')).toContainText('₹25,000');
  await expect(page.getByTestId('duty-estimate')).toContainText('₹1,063');
  await page.getByTestId('doc-next').click();
  await page.getByLabel('Landlord signature (Meera Kulkarni)').fill('Meera Kulkarni');
  await page.getByLabel('Tenant signature (Amir Khan)').fill('Amir Khan');
  await page.locator('#esign-consent').check();
  await page.locator('xpath=//button[normalize-space()="Sign agreement"]').click();
  await expect(page.getByTestId('agreement-id')).toContainText('AGR-');
  await expect(page.getByTestId('stamp-duty')).toContainText('₹1,063');
  await expect(page.getByTestId('preview-signed')).toContainText('Signed electronically');
});

Practicing another tool?