PracticeQAAutomation logoPracticeQAAutomation
Pw

TypeScript · @playwright/test

Healthcare with Playwright

Pick a specialty, filter doctors, choose a day (Sundays closed) and a free time slot, fill new or existing patient details, then reschedule or cancel.

App under test

🩺 MediCare+

URL
/apps/clinic
Existing patient
P-1001
Video consult
20% off
Closed
Sundays

Scenarios to automate

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

  1. 1

    Specialty & filters

    Beginner

    Toggle specialty-*, combine filter-gender, filter-fee and filter-available-today; assert doctor-count.

  2. 2

    Sort order

    Intermediate

    sort-doctors “Lowest fee” must order doctor-fee values ascending.

  3. 3

    Disabled dates

    Intermediate

    Sunday chips in appointment-day are disabled; pick the first enabled day with :not([disabled]).

  4. 4

    Booked slots

    Intermediate

    Slots with data-available="false" are disabled; choose a free one and check slot-summary.

  5. 5

    Existing patient lookup

    Intermediate

    patient-existing + P-1001 shows patient-found; any other ID shows patient-not-found.

  6. 6

    Conditional insurance fields

    Beginner

    has-insurance reveals insurance-provider and policy-number, both validated.

  7. 7

    Reschedule

    Advanced

    Move an appointment in reschedule-modal and assert appointment-slot changed.

  8. 8

    Cancel

    Advanced

    cancel-appt-<id> → confirm-cancel-appointment sets appointment-status to Cancelled.

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
medicare-plus.spec.ts
import { test, expect } from '@playwright/test';

// playwright.config.ts → use: { baseURL: 'https://www.practiceqaautomation.com' }
// Locators in this suite: getByRole ×2 · getByLabel ×3 · CSS ×3 · XPath ×1 · getByTestId ×9
test('books a video consultation', async ({ page }) => {
  await page.goto('/apps/clinic');
  await page.getByTestId('specialty-cardiology').click();
  await expect(page.getByTestId('doctor-count')).toContainText('2 doctors');
  await page.getByTestId('book-doctor').nth(0).click();
  await expect(page.getByTestId('doctor-title')).toContainText('Ananya Rao');
  await page.getByTestId('type-video').click();

  // First open day (Sundays are disabled), then the first free slot
  await page.locator('[data-testid="appointment-day"]:not([disabled])').first().click();
  await page.locator('[data-testid="slot"][data-available="true"]').first().click();
  await expect(page.getByTestId('slot-summary')).toContainText('Video');
  await page.getByRole('button', { name: 'Continue' }).click();
  await page.getByTestId('patient-new').click();
  await page.getByLabel('Full name').fill('Amir Khan');
  await page.locator('#patient-age').fill('36');
  await page.getByRole('combobox', { name: 'Gender' }).selectOption('male');
  await page.getByLabel('Phone').fill('9876543210');
  await page.locator('#patient-email').fill('amir@example.com');
  await page.getByLabel('Symptoms / reason for visit').fill('Occasional chest discomfort after exercise');
  await page.locator('#consent').check();
  await page.locator('xpath=//button[normalize-space()="Confirm appointment"]').click();
  await expect(page.getByTestId('appointment-confirmed')).toBeVisible();
  await expect(page.getByTestId('appointment-id')).toContainText('APT-');
  await expect(page.getByTestId('appointment-type')).toContainText('Video consult');
});

Practicing another tool?