Məzmuna keç

Modul 1: QA üçün JavaScript və TypeScript

Bu modul Playwright testlərini yazmaq üçün lazım olan TypeScript və JavaScript biliklərini verir — nə çox, nə az. Əgər daha əvvəl kod yazmamısınızsa, problem deyil. Əgər daha əvvəl JS yazmısınızsa, bu modul gündəlik istifadə edəcəyiniz şablonları möhkəmləndirəcək.

Kurs boyu TypeScript istifadə edirik — Modul 0-da npm init playwright@latest bunu sizin üçün qurub. TypeScript ixtiyari tiplərlə JavaScript-dir, ona görə də aşağıdakı hər bir JavaScript nümunəsi eyni zamanda etibarlı TypeScript-dir.

🎬 Video tezliklə əlavə olunacaq


constletvar heç vaxt istifadə etməyin

Bölmə: “const və let — var heç vaxt istifadə etməyin”

Hər test faylında iki dəyişən açar sözü görəcəksiniz: constlet.

const baseURL = 'http://localhost:3000'; // yenidən mənimsədilməyəcək
let retryCount = 0; // sonra dəyəri dəyişəcək

Qayda: standart olaraq const istifadə edin. Dəyişənə yeni dəyər mənimsətməli olduqda let-ə keçin.

// ✅ Düzgün
const TIMEOUT = 30000;
let attempts = 0;
attempts = attempts + 1; // yaxşıdır — let yenidən mənimsətməyə icazə verir
// ❌ Xəta verir
const MAX = 5;
MAX = 10; // TypeError: Assignment to constant variable

Vacib bir məqam: const dəyişməzlik demək deyil. Obyekt xüsusiyyətlərini dəyişdirmək mümkündür:

const config = { retries: 1 };
config.retries = 2; // ✅ buna icazə verilir
config = { retries: 3 }; // ❌ buna icazə verilmir — referansı yenidən mənimsədə bilməzsiniz

var haqqında: mövcuddur, amma çaşdırıcı scope xətaları yaradır. Bütün müasir linter-lər bunu işarələyir. Playwright layihəsində heç vaxt var-a ehtiyac olmayacaq.

constlet blok-scoped-dır — yalnız elan edildikləri { } blokunun daxilindən əlçatandır. Aşağıdakı nümunədə message yalnız if bloku daxilindədir; blokundan kənarda ReferenceError atılır:

if (true) {
let message = 'Salam!';
}
console.log(message); // ❌ ReferenceError: message is not defined

Tapşırıq 1-də məhz bu xətanı düzəldəcəksiniz.


Tapşırıqları Necə İşlətməli Slaydlar — yeni pəncərədə açılır

Bütün tapşırıqlar sadə Node.js ilə işləyir — brauzerlərə ehtiyac yoxdur.

  1. Modul 0-da qurduğunuz Playwright layihəsini VS Code-da açın.
  2. Layihənin kökündə exercises/mod1/ qovluğunu yaradın (Explorer panelində sağ klik → New Folder).
  3. Hər tapşırıq üçün ayrı fayl yaradın: exercise-1.ts, exercise-2.tsexercise-6.ts.
  4. İnteqrasiya olunmuş terminalı açın (Ctrl + `) — yolun layihə kökü olduğundan əmin olun.
  5. Faylı işlədin: npx tsx exercises/mod1/exercise-1.ts

tsx tapılmırsa: npm install -D tsx


Tapşırıq 1: Dəyişənlər — xətaları tapın

Bölmə: “Tapşırıq 1: Dəyişənlər — xətaları tapın”

Aşağıdakı kodda bir neçə problem var. Onları düzəldin və faylı işlədin.

// ❌ Bu kodda problemlər var. Düzəldin.
var baseURL = 'http://localhost:3000';
const TIMEOUT = 30000;
TIMEOUT = 50000; // Bu icazəlidirmi?
const user = { email: '[email protected]', role: 'admin' };
user = { email: '[email protected]', role: 'admin' }; // Bu işləyəcəkmi?
if (true) {
let message = 'Salam!';
}
console.log(message); // Niyə xəta var?
console.log('Tapşırıq 1 tamamlandı');

Addımlar:

  • var baseURLconst ilə əvəzləyin
  • TIMEOUT yenidən mənimsətməni düzəldin — yeni dəyişən istifadə edin (məs. TIMEOUT_EXTENDED)
  • user = {...}const dəyişəninə mənimsətmə xətasıdır; let user ilə elan edin
  • message scope xətasını düzəldin — console.log-u blokun içinə köçürün
  • Düzəldilmiş faylı işlədin və xəta olmadığını yoxlayın

Gözlənilən nəticə:

Salam!
Tapşırıq 1 tamamlandı

Bu üç primitiv tip test fayllarında istifadə edəcəklərinizin böyük hissəsini əhatə edir.

const url = 'http://localhost:3000/login';
const selector = '#email-input';
// Template literal (backtick) — dəyər yerləşdirəndə bunları istifadə edin
const message = `Keçildi: ${url}`;
const fullSelector = `[data-testid="${selector}"]`;

Template literal-lar (backtick-li string-lər) Playwright-də çox istifadə olunur — konfiqurasiya fayllarında, page object-lərdə və iddia ifadələrində.

const timeout = 5000; // millisaniyə
const retries = 3;
const price = 19.99;

Tip çevrilmələrinə diqqət edin (aşağıdakı nümunələr xalis JavaScript davranışını göstərir — TypeScript tipləri yoxdur):

'5' - 3 // → 2 (JS string-i rəqəmə çevirir)
'5' + 3 // → '53' (JS 3-ü string-ə çevirir — tələ!)

Praktikada açıq çevirmədən istifadə edin: Number('5') və ya parseInt('5', 10).

const isLoggedIn = true;
const hasErrors = false;
// Həmişə === (ciddi bərabərlik), heç vaxt ==
'5' === 5 // → false (fərqli tiplər)
'5' == 5 // → true (tip çevrilməsi — bundan qaçın)

Playwright-də boolean-lar iddia ifadələrində (expect(isVisible).toBe(true)) və konfiqurasiyada (headless: true) görünür.


const browsers = ['chromium', 'firefox', 'webkit'];
const prices = [9.99, 14.99, 29.99];
// Ümumi əməliyyatlar
browsers.length; // 3
browsers[0]; // 'chromium'
browsers.push('electron'); // sona əlavə edir
browsers.filter(b => b !== 'webkit'); // 'webkit' olmadan yeni array qaytarır
browsers.map(b => b.toUpperCase()); // ['CHROMIUM', 'FIREFOX', 'WEBKIT']
const user = {
password: 'customer123',
role: 'admin',
};
// Xüsusiyyətlərə giriş
user.email; // '[email protected]'
user['role']; // 'admin' — dinamik açarlar üçün mötərizə notasiyası

Destructuring, obyekt və array-lərdən dəyərləri təmiz şəkildə çıxarmağa imkan verir:

const { email, password } = user;
// eyni məna daşıyır: const email = user.email; const password = user.password;
const [first, second] = browsers;
// eyni məna daşıyır: const first = browsers[0]; const second = browsers[1];

Playwright-də bunu daim görəcəksiniz — məsələn, freymvorkdan testexpect-i çıxararkən:

import { test, expect } from '@playwright/test';

Spread operatoru (...) obyekt və array-ləri kopyalayır və birləşdirir:

const defaultOptions = { headless: true, slowMo: 0 };
const debugOptions = { ...defaultOptions, headless: false, slowMo: 500 };
// → { headless: false, slowMo: 500 }

Test konfiqurasiyalarını birləşdirmək və dəyişdirilmiş test data obyektləri qurmaq üçün geniş istifadə olunur.


Tapşırıq 2: Test data obyektlərini qurun

Bölmə: “Tapşırıq 2: Test data obyektlərini qurun”

testData obyektini tamamlayın:

const testData = {
validCustomer: {
password: 'customer123',
name: 'Test Müştərisi',
},
validAdmin: {
// TODO: bu xüsusiyyətləri əlavə edin:
// email: '[email protected]', password: 'admin123', name: 'Test Admini'
},
newProduct() {
// TODO: { name: `Test Məhsulu ${Date.now()}`, price: 19.99, category: 'aksesuarlar' } qaytarın
},
shippingDetails() {
// TODO: { name: '...', address: '...', city: '...', zip: '...' } qaytarın — öz test dəyərlərinizi istifadə edin
},
};
console.log('Müştəri:', testData.validCustomer);
console.log('Admin:', testData.validAdmin);
console.log('Məhsul:', testData.newProduct());
console.log('Göndərmə:', testData.shippingDetails());

Gözlənilən nəticə:

Müştəri: { email: '[email protected]', password: 'customer123', name: 'Test Müştərisi' }
Admin: { email: '[email protected]', password: 'admin123', name: 'Test Admini' }
Məhsul: { name: 'Test Məhsulu 1712345678901', price: 19.99, category: 'aksesuarlar' }
Göndərmə: { name: '...', address: '...', city: '...', zip: '...' }

Funksiyalar və arrow funksiyalar

Bölmə: “Funksiyalar və arrow funksiyalar”
function formatPrice(price: number): string {
return `$${price.toFixed(2)}`;
}

price-dakı : number annotasiyası və mötərizələrdən sonrakı : string TypeScript tipləridir — onlar redaktora nəyin daxil ola biləcəyini və nəyin çıxdığını bildirir. Onları hər yerdə görəcəksiniz.

Arrow funksiyalar daha qısa, müasir sintaksisdir — Playwright-də hər yerdə görünür:

const formatPrice = (price: number): string => `$${price.toFixed(2)}`;
// Çox sətirli arrow funksiya { } və açıq return tələb edir
const generateUser = (role: string) => {
const timestamp = Date.now();
return { email: `${role}_${timestamp}@test.io`, role };
};

Hər Playwright testi arrow funksiyadan istifadə edir:

test('istifadəçi daxil ola bilər', async ({ page }) => {
await page.goto('/login');
// ...
});

Nəyi nə vaxt istifadə etməli:

  • Arrow funksiyalar: callback-lər, test gövdələri, qısa köməkçi funksiyalar
  • Adi function: class metodları (məsələn, this istifadə edən Page Object metodları)

Tək ifadəli arrow funksiyalar dəyəri gizli qaytarır — return açar sözü lazım deyil:

const double = x => x * 2; // gizli return — x * 2 qaytarır
const triple = x => { x * 3 }; // ❌ return yoxdur — undefined qaytarır
const triple = x => { return x * 3 }; // ✅ açıq return

Tapşırıq 3: Köməkçi funksiyalar yazın

Bölmə: “Tapşırıq 3: Köməkçi funksiyalar yazın”

Bu dörd arrow funksiyanı ehtiva edən exercise-3.ts hazırlayın:

// 1. formatPrice(price) — $ və 2 onluq rəqəm ilə string qaytarır
// formatPrice(19.99) → "$19.99"
// 2. isEmail(email) — string '@' və '.' ehtiva edirsə true qaytarır
// isEmail('[email protected]') → true
// isEmail('e-poçt-deyil') → false
// 3. generateUser(role) — timestamp-li email ilə obyekt qaytarır
// generateUser('admin') → { email: '[email protected]', role: 'admin' }
// 4. filterByCategory(products, category) — array-i kateqoriyaya görə süzür
// filterByCategory([{name:'Siçan',category:'aksesuarlar'},...], 'aksesuarlar')
// → [{name:'Siçan',category:'aksesuarlar'}]

İpuclar: template literal, .toFixed(2), .includes(), Date.now(), .filter() istifadə edin. Hər parametrə əsas tip annotasiyası əlavə edin.

Gözlənilən nəticə:

$19.99
true
false
{ email: '[email protected]', role: 'admin' }
[ { name: 'Siçan', category: 'aksesuarlar' } ]

Playwright ES modulları (ESM) istifadə edir — import / export sintaksisi. Yazacağınız hər .ts faylı ən azı bir import ilə başlayacaq.

// Moduldan adlandırılmış export-ları import et
import { test, expect } from '@playwright/test';
// Bir neçə şeyi import edin
import { chromium, firefox } from '@playwright/test';
// Öz faylınızı import edin (default export)
import LoginPage from './pages/LoginPage';
// Öz faylınızı import edin (adlandırılmış export)
import { LoginPage } from './pages/LoginPage';

Qeyd: öz faylınızı import edəndə yola .ts uzantısı əlavə etmirsiniz.

// LoginPage.ts — adlandırılmış export
import { Page } from '@playwright/test';
export class LoginPage {
constructor(public page: Page) {}
}
// LoginPage.ts — default export (fayl başına yalnız bir dənə)
import { Page } from '@playwright/test';
class LoginPage {
constructor(public page: Page) {}
}
export default LoginPage;

export açar sözünü unutsanız, import undefined qaytaracaq və TypeError: LoginPage is not a constructor kimi xətalar görəcəksiniz.

CommonJS-i hələ də görə bilərsiniz

Bölmə: “CommonJS-i hələ də görə bilərsiniz”

Köhnə Node.js və Playwright nümunələri CommonJS sintaksisindən istifadə edir — const { test } = require('@playwright/test')module.exports = LoginPage. Hər iki üsul Node.js-də işləyir, amma rəsmi Playwright generatoru və bu kurs hər yerdə ESM import / export istifadə edir. Bir təlimatda ya köhnə repo-da require() görsəniz, eyni ideya, fərqli sintaksis kimi qəbul edin.


async/await — Niyə Vacibdir? Slaydlar — yeni pəncərədə açılır

Bu bölmə flaky testlərdən qaçmaq üçün ən vacibdir. await unutmaq test uğursuzluqlarının 1 nömrəli səbəbidir.

Asinxron əməliyyatları anlamaq üçün qəhvə sifariş etməyi təsəvvür edin: kassaya pul verirsiniz və çek alırsınız — bu sizin Promise-inizdir. await isə piştaxtanın yanında dayanıb qəhvə hazır olana qədər gözləməkdir. Çek (Promise) dərhal əlinizdədir, nəticə isə bir az sonra gəlir.

Promise hələ mövcud olmayan bir dəyəri təmsil edir — asinxron əməliyyatın nəticəsidir. Playwright demək olar ki, hər əməliyyatdan Promise qaytarır:

// page.goto() Promise qaytarır
const promise = page.goto('/login'); // naviqasiyanı başladır amma gözləmir
async function login() {
await page.goto('/login'); // naviqasiyanın tamamlanmasını gözləyir
await page.fill('#email', '...'); // doldurmağın tamamlanmasını gözləyir
await page.click('button'); // klikləmənin tamamlanmasını gözləyir
}

await olmadan test əməliyyat bitmədən növbəti sətirə keçir:

// ❌ await yoxdur — test dərhal davam edir
page.goto('/login');
page.fill('#email', '[email protected]'); // səhifə hələ yüklənməyib ola bilər!
expect(page).toHaveURL('/dashboard'); // login olmadan işləyir!

await istifadə edən hər funksiya async ilə elan edilməlidir:

// ✅ Düzgün
async function runTest() {
await page.goto('/');
}
// Arrow funksiya kimi də işləyir
const runTest = async () => {
await page.goto('/');
};

async funksiya həmişə Promise qaytarır. Əgər async funksiyadan 'salam' qaytarsanız, çağıran tərəf Promise<string> alır — onlar da await etməlidir.

Promise.all — paralel əməliyyatlar

Bölmə: “Promise.all — paralel əməliyyatlar”

Eyni anda bir neçə şeyi gözləmək lazım olduqda:

// Naviqasiya VƏ başqa bir şeyi eyni anda gözləyin
const [response] = await Promise.all([
page.waitForResponse('/api/login'),
page.click('button[type="submit"]'),
]);

Bu, klik etdikdə şəbəkə sorğusunu gözləmək lazım olan naviqasiya şablonları üçün istifadə olunur.


Tapşırıq 4: Xətalı asinxron kodu düzəldin

Bölmə: “Tapşırıq 4: Xətalı asinxron kodu düzəldin”

Aşağıdakı kodda 6 əksik await açar sözü var. Onları tapın və düzəldin.

const fakePage = {
goto: (url: string) => new Promise<void>(r =>
setTimeout(() => { console.log(`Keçildi: ${url}`); r(); }, 50)),
fill: (selector: string, value: string) => new Promise<void>(r =>
setTimeout(() => { console.log(`${selector} dolduruldu: ${value}`); r(); }, 50)),
click: (selector: string) => new Promise<void>(r =>
setTimeout(() => { console.log(`Klik edildi: ${selector}`); r(); }, 50)),
waitForSelector: (selector: string) => new Promise<void>(r =>
setTimeout(() => { console.log(`Gözlənildi: ${selector}`); r(); }, 50)),
screenshot: () => new Promise<void>(r =>
setTimeout(() => { console.log('Ekran görüntüsü alındı'); r(); }, 50)),
};
async function runTest() {
console.log('Test başlayır...');
fakePage.goto('/auth/login'); // ❌ await yoxdur
console.log('Login səhifəsinə keçildi');
fakePage.waitForSelector('#email'); // ❌ await yoxdur
fakePage.fill('#email', '[email protected]'); // ❌ await yoxdur
fakePage.fill('#password', 'customer123'); // ❌ await yoxdur
fakePage.click('button[type="submit"]'); // ❌ await yoxdur
console.log('Login formu göndərildi');
fakePage.screenshot(); // ❌ await yoxdur
console.log('Test tamamlandı!');
}
runTest();

Əvvəlcə xətalı versiyanı işlədin — çıxış sırasının yanlış olduğunu görəcəksiniz. Sonra await əlavə edib yenidən işlədin.


Bu modul boyu artıq TypeScript yazırsınız — hər annotasiya edilmiş parametr (price: number, role: string) iş başında olan TypeScript-dir. Bu bölmə sadəcə “tip annotasiyaları olan JS” hissələri bir araya gətirmir: interface-lər, istəyə bağlı xüsusiyyətlər və JSDoc.

Tiplər kodu işlətməzdən əvvəl xətaları aşkar edir:

// JavaScript — xəta yalnız işləmə zamanı baş verir
function formatPrice(price) {
return `$${price.toFixed(2)}`;
}
formatPrice('rəqəm-deyil'); // işləmə zamanı çöküş
// TypeScript — xəta dərhal redaktorda görünür
function formatPrice(price: number): string {
return `$${price.toFixed(2)}`;
}
formatPrice('rəqəm-deyil'); // ❌ TypeScript xətası: Argument of type 'string' is not assignable to parameter of type 'number'

VS Code-dakı qırmızı dalğalı xətt — siqnaldır. İşə salmadan öncə xətanı düzəldirsiniz.

Interface-lər obyektin formasını təsvir edir. Test data üçün istifadə edin:

interface User {
email: string;
password: string;
role: 'admin' | 'customer'; // union type — yalnız bu iki dəyər
}
interface Product {
name: string;
price: number;
category: string;
}
const user: User = {
password: 'customer123',
role: 'customer',
};

İstəyə bağlı xüsusiyyətlər

Bölmə: “İstəyə bağlı xüsusiyyətlər”

Xüsusiyyəti istəyə bağlı etmək üçün ? əlavə edin:

interface ShippingDetails {
name: string;
address: string;
city: string;
zip: string;
country?: string; // istəyə bağlı — undefined ola bilər
}

JSDoc — .ts faylları olmadan TypeScript faydaları

Bölmə: “JSDoc — .ts faylları olmadan TypeScript faydaları”

Sadə .js faylında tip yoxlaması lazım olarsa, JSDoc annotasiyalarından istifadə edin. VS Code onları oxuyur və sizə avtomatik tamamlama və tip xətaları göstərir — TypeScript kimi, amma heç bir build addımı olmadan.

/**
* @param {number} price
* @returns {string}
*/
const formatPrice = (price) => `$${price.toFixed(2)}`;
class LoginPage {
/** @param {import('@playwright/test').Page} page */
constructor(page) {
this.page = page;
}
}

Tez-tez ehtiyacınız olmayacaq — kurs .ts faylları istifadə edir — amma köhnə kod bazalarında görəcəksiniz.


Xətaları və stack trace-ləri oxumaq

Bölmə: “Xətaları və stack trace-ləri oxumaq”

Test uğursuz olduqda, xəta mesajı nə baş verdiyini dəqiq deyir — əgər oxumağı bilsəniz.

Playwright xətasının anatomiyası

Bölmə: “Playwright xətasının anatomiyası”
1) [chromium] › login.spec.ts:10:3 › admin can login to dashboard ───────────
TypeError: Cannot read properties of undefined (reading 'click')
16 | async login(email: string, password: string) {
17 | await this.emailInput.fill(email);
> 18 | await this.loginButton.click();
| ^
19 | }
at LoginPage.login (tests/pages/LoginPage.ts:18:28)
at tests/login.spec.ts:15:12

Yuxarıdan aşağı oxuyun:

  1. Test başlığı[chromium] › login.spec.ts:10:3 › admin can login to dashboard brauzer proyektini, testin başladığı fayl və sətri, və test adını göstərir.
  2. Xəta tipi və mesajıTypeError: Cannot read properties of undefined (reading 'click'). Bir şey undefined-dir və siz onun üzərində .click() çağırmağa cəhd etdiniz.
  3. Kod çərçivəsi — xətanın ətrafındakı sətirlər. 18-ci sətirdəki > oxu uğursuz sətri işarələyir; ^ işarəsi tam olaraq pozulan ifadəni göstərir — burada this.loginButton undefined-dir.
  4. Stack sətirləri — hər çağırışın öz fayllarınızda haradan gəldiyi. Stack-in başı — xətanın baş verdiyi yer; aşağıda — onu çağıran kod.

node_modules stack sətirlərinə məhəl qoymayın — bunlar Playwright-in daxili işləridir. Öz fayllarınıza diqqət edin.

XətaMənaHəll
Cannot read properties of null (reading 'click')Bir dəyişən və ya handle null-dur — gözlənilən obyekt tapılmadıDəyişənin düzgün başladıldığını və selector-un düzgün yazıldığını yoxlayın
Cannot read properties of undefinedDəyişən mənimsədilməyibImport-ları, dəyişən scope-unu yoxlayın
ReferenceError: X is not definedDəyişən scope-da elan edilməyibYazılışı, elan yerini yoxlayın
TypeError: X is not a functionYanlış şey import edilib ya export unudulubconsole.log(typeof X) yoxlayın
Nəticə sırası yanlışdırawait yoxdurAsinxron çağırışlardan əvvəl await əlavə edin

Tapşırıq 5: Stack trace-i oxuyun

Bölmə: “Tapşırıq 5: Stack trace-i oxuyun”

Bu xətanı oxuyun və aşağıdakı sualları cavablayın:

1) [chromium] › login.spec.ts:10:3 › admin can login to dashboard ───────────
TypeError: Cannot read properties of undefined (reading 'click')
16 | async login(email: string, password: string) {
17 | await this.emailInput.fill(email);
> 18 | await this.loginButton.click();
| ^
19 | }
at LoginPage.login (tests/pages/LoginPage.ts:18:28)
at tests/login.spec.ts:15:12

Suallar:

  1. Xəta faktiki olaraq harada baş verdi? (fayl, sətir, sütun)
  2. Uğursuz olan testin adı nədir?
  3. “Cannot read properties of undefined” bu kontekstdə nə deməkdir — nə undefined-dir?
  4. Bunu düzəltmək üçün ilk nəyi yoxlayardınız?

Cavablarınızı exercise-5.ts faylında şərh kimi yazın.


URL-ləri, parolları və ya tokenləri test fayllarına heç vaxt birbaşa yazmayın. Bunun əvəzinə mühit dəyişənlərindən istifadə edin.

const baseURL = process.env.BASE_URL;
const adminEmail = process.env.ADMIN_EMAIL;

Standart dəyərlər və məcburi dəyişənlər

Bölmə: “Standart dəyərlər və məcburi dəyişənlər”
function getConfig() {
const baseUrl = process.env.BASE_URL ?? 'http://localhost:3000'; // standart dəyər
const adminEmail = process.env.ADMIN_EMAIL;
if (!adminEmail) {
throw new Error('ADMIN_EMAIL mühit dəyişəni tələb olunur');
}
const isCI = process.env.CI === 'true'; // string-i boolean-a çevir
return { baseUrl, adminEmail, isCI };
}

Layihə kökündə .env faylı hazırlayın:

BASE_URL=http://localhost:3000
ADMIN_PASSWORD=admin123
CI=false

Sonra konfiqurasiyanın başında yükləyin:

import 'dotenv/config';
// İndi process.env.BASE_URL, process.env.ADMIN_EMAIL və s. mövcuddur

.env-i həmişə .gitignore-a əlavə edin — sirrləri heç vaxt version control-a göndərməyin.

Bu şablonu playwright.config.ts-də görəcəksiniz:

playwright.config.ts
import { defineConfig } from '@playwright/test';
import 'dotenv/config';
export default defineConfig({
use: {
baseURL: process.env.BASE_URL ?? 'http://localhost:3000',
},
forbidOnly: !!process.env.CI, // !! string-i boolean-a çevirir
});

Tapşırıq 6: Mühit dəyişənləri

Bölmə: “Tapşırıq 6: Mühit dəyişənləri”

process.env-dən oxuyan getConfig() funksiyasını tətbiq edin:

// dotenv-i simulyasiya edirik
process.env.BASE_URL = 'http://localhost:3000';
process.env.ADMIN_EMAIL = '[email protected]';
process.env.ADMIN_PASSWORD = 'admin123';
process.env.CI = 'true';
function getConfig() {
// Qaytarın:
// - baseUrl (BASE_URL-dən, standart 'http://localhost:3000')
// - adminEmail (ADMIN_EMAIL-dən, yoxdursa Error at)
// - adminPassword (ADMIN_PASSWORD-dən, yoxdursa Error at)
// - isCI (CI-dən, 'true' string-ini boolean true-ya çevirin)
}
console.log(getConfig());

Bonus: process.env.ADMIN_EMAIL-i silin və xətanı try/catch ilə idarə edin.


Yapışqan kağıza yazacağınız dörd qayda:

  1. Standart olaraq const, yenidən mənimsətmək üçün let, heç vaxt var
  2. Hər Playwright əməliyyatını await edinawait unudulması = flaky test
  3. Stack trace-ləri yuxarıdan aşağı oxuyun — başlıq, xəta mesajı, kod çərçivəsi, sonra öz fayllarınıza işarə edən stack sətirləri
  4. Sirrləri heç vaxt kodda yazmayınprocess.env.env fayllarından istifadə edin

Modul 2-də bu modulun hər bir anlayışı real Page Object class-larında istifadə olunacaq.