PracticeQAAutomation logoPracticeQAAutomation
Pw

TypeScript · @playwright/test

Telecom with Playwright

Enter a number for async operator detection, browse plan tabs, compare up to 3 plans, apply a cashback promo, pay and watch the recharge status settle.

App under test

📶 SkyTel

URL
/apps/telecom
Numbers
7/8/9xxxxxxxxx
Other operator
6xxxxxxxxx
Promo
SKY20 (20% cashback)

Scenarios to automate

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

  1. 1

    Operator detection

    Beginner

    After 10 digits a spinner runs ~0.8s, then detected-operator shows the circle. 6xxxxxxxxx is rejected.

  2. 2

    Plan tabs & filter

    Beginner

    Switch plan-tab-*, apply validity-filter and assert the plan-card count.

  3. 3

    Compare limit

    Intermediate

    Tick 4 compare-* boxes: the 4th shows compare-error; compare-button opens compare-table.

  4. 4

    Promo code

    Intermediate

    SKY20 shows cashback in promo-message and summary-cashback; other codes are rejected.

  5. 5

    Payment method validation

    Intermediate

    Pay with no method, a bad UPI ID or an empty wallet to see each error-*.

  6. 6

    Async status

    Advanced

    recharge-status starts as “Pending with operator” and becomes “Successful” ~2.5s later — wait for text, not time.

  7. 7

    Toggles & progress bars

    Advanced

    On My account, read aria-valuenow of usage-* bars and flip addon-* switches (role=switch).

  8. 8

    Complaint form

    Intermediate

    A description under 20 chars fails; a valid one shows complaint-ticket with an SR number.

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

// playwright.config.ts → use: { baseURL: 'https://www.practiceqaautomation.com' }
// Locators in this suite: getByRole ×2 · getByLabel ×1 · getByPlaceholder ×1 · CSS ×1 · XPath ×1 · getByTestId ×9
test('recharges a prepaid number', async ({ page }) => {
  await page.goto('/apps/telecom');
  await page.getByLabel('Mobile number').fill('9876543210');
  await expect(page.getByTestId('detected-operator')).toContainText('SkyTel Prepaid');
  await page.getByRole('tab', { name: 'Unlimited' }).click();
  await page.getByTestId('select-plan-u2').click();
  await expect(page.getByTestId('selected-plan')).toContainText('₹399.00');
  await page.locator('xpath=//button[normalize-space()="Proceed to pay"]').click();
  await expect(page).toHaveURL(/\/apps\/telecom\/checkout/);
  await page.getByPlaceholder('Promo code', { exact: true }).fill('SKY20');
  await page.getByRole('button', { name: 'Apply' }).click();
  await expect(page.getByTestId('promo-message')).toContainText('cashback');
  await page.getByTestId('pay-upi').click();
  await page.locator('#upi-id').fill('amir@okbank');
  await page.getByTestId('pay-now').click();
  await expect(page.getByTestId('recharge-success')).toBeVisible();

  // The operator confirms asynchronously
  await expect(page.getByTestId('recharge-status')).toContainText('Successful');
  await expect(page.getByTestId('recharge-cashback')).toContainText('₹50.00');
});

Practicing another tool?