← Back to CV

Playwright TypeScript

E2E test automation framework for SlotsOne iGaming platform — built with Playwright, TypeScript, and modern QA best practices

pyavchik/slotsone-playwright
25+spec files
7epics
15page objects
4test projects
CI/CDJenkins
2reporters
1

Page Object Model (POM) PATTERN

Every page or major component has a dedicated class in pages/ that encapsulates locators and interaction methods. Tests never reference raw selectors — they call descriptive methods on page objects, making tests readable and maintenance trivial when the UI changes.

15 page objects covering public site, admin panel, and game screens:

Public Site /cv # CV landing — title, avatar, document links /login # Login / register forms /slots # Game lobby — cards, filters, header /slots/:slug # Slots gameplay — canvas, bets, HUD, paytable /history # Game history table with filters /history/:id # Round detail + provably fair verification /roulette # European roulette /american-roulette # American roulette Admin Panel /admin/login # Admin authentication /admin # Dashboard — widgets & charts /admin/players # Player management table /admin/players/:id # Individual player view & top-up /admin/transactions # Transaction ledger /admin/bonuses # Bonus & promotion management ... # + /admin/kyc, /admin/risk, /admin/reports, /admin/settings, /admin/games

Example — GamePage class:

export class GamePage {
  readonly spinButton: Locator;
  readonly balance: Locator;
  readonly errorToast: Locator;

  constructor(private page: Page) {
    this.spinButton = page.getByRole('button', { name: /spin/i });
    this.balance    = page.getByTestId('hud-balance');
    this.errorToast = page.locator('.slots-error-toast');
  }

  async goto(slug: string) { await this.page.goto(`/slots/${slug}`); }
  async spin() { await this.spinButton.click(); }
}
2

Custom Base Fixtures ARCHITECTURE

A custom base.fixture.ts extends Playwright's built-in test object. Every spec imports test and expect from this fixture rather than from @playwright/test directly. This central point injects Allure metadata (epic & feature labels) and captures failure screenshots automatically.
export const test = base.extend({
  page: async ({ page }, use, testInfo) => {
    // Auto-label for Allure Behaviors tab
    const dir  = relPath.split(path.sep)[0];
    const file = path.basename(testInfo.file);

    if (EPICS[dir])    await allure.parentSuite(EPICS[dir]);
    if (FEATURES[file]) await allure.suite(FEATURES[file]);

    await use(page);

    // Auto-attach screenshot on failure
    if (testInfo.status !== testInfo.expectedStatus) {
      const screenshot = await page.screenshot().catch(() => null);
      if (screenshot) await testInfo.attach('screenshot', { body: screenshot });
    }
  },
});

Why it matters: zero Allure boilerplate in specs, consistent failure artifacts, and a single place to add cross-cutting concerns (logging, performance marks, etc.).

3

API Mocking & Route Interception ISOLATION

Tests use Playwright's context.route() to intercept API calls and return deterministic mock responses. This decouples E2E UI tests from backend availability, making the suite fast, reliable, and runnable without a live server.

fixtures/helpers.ts provides composable mock functions that can be combined per test scenario:

// Individual mocks
await mockAuth(context);       // auth/refresh → 200
await mockGameInit(context);   // game/init → valid session
await mockSpin(context);       // spin → winning result (auto-increments spin_id)
await mockSpinError(context);  // spin → 500 server error

// Convenience bundles
await mockGameApis(context);   // auth + init + spin + images
await mockRouletteApis(context);
await mockHistoryApis(context);

fixtures/mock-data.ts contains typed factory functions (makeGameInitResponse, makeSpinResponse, etc.) with override support for edge-case testing:

// Default winning spin
makeSpinResponse();

// Custom: no-win spin
makeNoWinSpinResponse();

// Custom: big win (12x multiplier)
makeBigWinSpinResponse(bet);

// Override any field
makeSpinResponse({ balance: { amount: 0, currency: 'USD' } });
4

Project-Based Test Organization CONFIG

playwright.config.ts defines four test projects with dependency chains. The admin setup project runs first to save storageState, which downstream admin specs reuse — avoiding repeated login flows while maintaining proper test isolation.
projects: [
  { name: 'Public Site',  testIgnore: '**/admin/**' },
  { name: 'Admin Setup',  testMatch: '**/admin.setup.ts' },
  { name: 'Admin Login',  testMatch: '**/admin/login.spec.ts' },
  {
    name: 'Admin Panel',
    dependencies: ['Admin Setup'],
    use: { storageState: '.auth/admin.json' },
  },
]

Auth setup logs in via the real admin UI, then saves browser state to .auth/admin.json. All authenticated admin tests inherit this state without any extra login steps.

5

Jenkins CI/CD Pipeline CI/CD

A declarative Jenkinsfile automates the full test lifecycle: install dependencies, install Chromium, run tests, generate Allure reports, and publish both Allure and Playwright HTML reports as build artifacts.
pipeline {
  stages {
    stage('Clean')   { sh 'rm -rf allure-results allure-report playwright-report' }
    stage('Install') { sh 'npm ci'; sh 'npx playwright install chromium' }
    stage('Run Tests') { sh 'npx playwright test' }
  }
  post {
    always {
      sh 'allure generate allure-results -o allure-report --clean'
      publishHTML(reportName: 'Allure Report')
      publishHTML(reportName: 'Playwright Report')
    }
  }
}

Key CI settings: forbidOnly: !!process.env.CI prevents accidental .only commits; retries: 2 in CI for flake resilience; workers: 1 for deterministic execution on shared agents.

6

Dual Reporting: Allure + Playwright HTML REPORTS

Tests emit data to two parallel reporters. Allure provides rich Behaviors-tab grouping (Epic → Feature → Story) thanks to auto-labeling in the base fixture. Playwright HTML serves as a lightweight backup with built-in trace viewer.
reporter: [
  ['list'],                            // terminal output
  ['html', { open: 'never' }],         // Playwright HTML report
  ['allure-playwright'],               // Allure integration
]

Environment metadata is written to allure-results/environment.properties at config time, so every report shows the browser, base URL, and CI vs. local context.

7

Smart Test Configuration TYPESCRIPT

The config leverages dotenv for environment variables, conditional CI settings, and built-in Playwright features like screenshot-on-every-test, video-on-failure, and trace-on-first-retry for maximum debuggability.
use: {
  baseURL: 'https://pyavchik.space',
  actionTimeout: 10_000,
  screenshot: 'on',               // every test gets a screenshot
  video: 'retain-on-failure',      // video saved only when test fails
  trace: 'on-first-retry',         // trace captured on retry for debugging
}

.env.example documents required variables (ADMIN_EMAIL, ADMIN_PASSWORD), keeping secrets out of the repository while making setup straightforward for new contributors.

Test Coverage Overview

25+ spec files organized by feature domain across 7 epics

/slots/:slug

  • Gameplay & spin flow
  • Paytable overlay
  • Keyboard controls
  • Error handling & retry
  • Win overlay animations

/slots

  • Game cards & navigation
  • Lobby filters
  • Header & branding

/login

  • Login & register flows

/cv

  • Landing page elements

/history

  • Game history table
  • Round detail & provably fair

/roulette

  • European roulette
  • American roulette

/admin/*

  • /admin/login
  • /admin — dashboard
  • /admin/players
  • /admin/players/:id
  • /admin/transactions
  • /admin/games
  • /admin/kyc
  • /admin/bonuses
  • /admin/risk
  • /admin/reports
  • /admin/settings
  • Navigation between pages

Source Code

Full source code is available on GitHub

pyavchik/slotsone-playwright