QA 9: Web qanday ishlaydi — Client-Server, HTTP, DNS, Cookie, Cache va Chrome DevTools
🧪 QA Engineer — Zero to Hero
QA 9: Web qanday ishlaydi — Client-Server, HTTP, DNS, Cookie, Cache va Chrome DevTools
Holat: 2026-yil oktabr. Bu dars web'ning "ichki kuxnyasi"ni QA ko'zi bilan ochadi: so'rov brauzerdan serverga qanday yetadi, holat (cookie, storage) qayerda saqlanadi, kesh va CORS qanday bug'larga olib keladi va Chrome DevTools bilan bularning hammasini qanday ko'rish mumkin. Barcha
curlmisollari jonli amaliyot saytlarida (jsonplaceholder, restful-booker, saucedemo) ishga tushirib tekshirilgan.
Bu darsdan keyin siz: web ilovadagi istalgan muammoni "front-end'mi, back-end'mi yoki infratuzilmami?" degan savolga dalil bilan javob bera olasiz.
- URL, DNS, TCP/TLS va HTTP so'rov-javobning tuzilishini tushuntira olasiz;
- cookie, localStorage, sessionStorage farqini va ularga bog'liq bug'larni bilasiz;
- kesh (
Cache-Control,ETag,304) va CORS xatolarini taniy olasiz; - Chrome DevTools'ning Elements, Console, Network, Application, Device Mode, Lighthouse panellarida ishlay olasiz;
- bug report'ga HAR, cURL va
X-Request-IDkabi kuchli dalillarni qo'sha olasiz.
Mundarija
- Client–server modeli
- URL anatomiyasi
- DNS, TCP va TLS — so'rov serverga qanday yetadi
- HTTP so'rov va javob
- Holat: cookie, session va brauzer xotirasi
- Kesh (caching) va kesh bug'lari
- CORS — QA nimani ko'radi
- Front-end'mi, back-end'mi? Bug'ni lokalizatsiya qilish
- Chrome DevTools — QA'ning asosiy quroli
- Cross-browser va responsive testlash
- Web testlash checklisti
- Amaliy mashqlar
- Xulosa
- Manbalar
1. Client–server modeli {#client-server}
Web ilova kamida ikki tomondan iborat:
- Client (mijoz) — foydalanuvchi qurilmasidagi dastur: brauzer, iOS yoki Android ilova. U so'rov yuboradi va javobni chiroyli qilib ko'rsatadi.
- Server — internetdagi kompyuter(lar). So'rovni qabul qiladi, biznes mantiqni bajaradi, ma'lumotlar bazasidan o'qiydi yoki yozadi va javob qaytaradi.
Oddiy o'xshatish — choyxona. Mijoz (brauzer) menyudan tanlaydi, ofitsiant (HTTP) buyurtmani oshxonaga (server) olib boradi, oshpaz omborxonadan (ma'lumotlar bazasi) masalliq oladi, tayyor taom (javob) yana ofitsiant orqali qaytadi. Taom sovuq kelsa, kim aybdor: ofitsiantmi, oshpazmi yoki ombormi? QA'ning ishi — aynan shuni dalil bilan aniqlash.
So'rovning hayot yo'li: brauzer, DNS, server va ma'lumotlar bazasi o'rtasidagi qadamlar va curl bilan o'lchangan vaqtlar
Zamonaviy web ilovalar (DemoBozor ham) odatda SPA (Single Page Application) bo'ladi: sahifa bir marta yuklanadi, keyin JavaScript orqasida fetch bilan API'ga so'rovlar yuboradi va faqat kerakli qismni yangilaydi. Shu sababli QA uchun "sahifa" emas, sahifa ortidagi so'rovlar muhimroq.
| Qatlam | DemoBozor'da nima | Bug qayerda ko'rinadi | Qanday tekshiramiz |
|---|---|---|---|
| Front-end (client) | React web, iOS, Android ilova | Noto'g'ri ko'rinish, tugma ishlamaydi, JS xato | DevTools: Elements, Console |
| Tarmoq | DNS, HTTPS, CDN, proxy | Sayt ochilmaydi, sekin, sertifikat xatosi | DevTools: Network, curl -v, dig |
| Back-end (API) | Node.js REST API | Noto'g'ri ma'lumot, 4xx/5xx, sekin javob | Network, Postman, loglar |
| Ma'lumotlar bazasi | PostgreSQL | Ma'lumot saqlanmagan, dublikat, eski qiymat | SQL (QA 12) |
🎯 Intervyuda: "Brauzerga manzil yozib Enter bosganda nima sodir bo'ladi?" — DNS orqali IP topiladi, TCP ulanish va TLS handshake o'rnatiladi, HTTP so'rov yuboriladi, server (va DB) ishlab javob qaytaradi, brauzer HTML/CSS/JS'ni yuklab sahifani chizadi (render). Har bosqichni bir gap bilan aytsangiz — kuchli javob.
2. URL anatomiyasi {#url}
URL — resursning manzili. Bitta xayoliy DemoBozor manzilini qismlarga ajratamiz:
https://www.demobozor.example:443/api/v1/products?query=choynak&page=2#reviews
└─┬─┘ └──────┬───────┘ └┬┘└──────┬───────┘└─────────┬─────────┘└──┬───┘
scheme host port path query fragment
| Qism | Misol | Ma'nosi | QA uchun eslatma |
|---|---|---|---|
| Scheme | https | Protokol | http:// ga o'tganda HTTPS'ga yo'naltiriladimi? |
| Host | www.demobozor.example | Server nomi (subdomain + domain + TLD) | demobozor.example va www. ikkalasi ishlaydimi? |
| Port | 443 | HTTPS uchun standart port (HTTP — 80) | Odatda yozilmaydi |
| Path | /api/v1/products | Server ichidagi resurs yo'li | Katta-kichik harf, oxiridagi / |
| Query | ?query=choynak&page=2 | kalit=qiymat juftlari, & bilan ajratiladi | Filtr, sahifalash — eng ko'p bug shu yerda |
| Fragment | #reviews | Sahifa ichidagi joy | Serverga yuborilmaydi, faqat brauzerda qoladi |
URL encoding
URL'da probel, &, ?, # va lotin bo'lmagan harflar maxsus kodlanadi: probel → %20, & → %26. Masalan "choynak 2 litr" qidiruvi query=choynak%202%20litr bo'ladi. O'zbekcha oʻ harfi ham baytlarga kodlanadi.
QA uchun test g'oyalari:
- qidiruvga
&,#,%,+, probel, emoji,oʻ/o'yozib ko'ring — natija bir xilmi? - URL'ni qo'lda o'zgartiring:
page=0,page=-1,page=999,page=abc; - juda uzun query (masalan, 5000 belgi) yuboring — server nima qaytaradi?
- sahifa URL'ini nusxalab, boshqa brauzerda (yoki tizimdan chiqib) oching — xuddi shu holat ochiladimi?
💡 Maslahat: URL'dagi parametrlar bilan "o'ynash" — eng arzon test usuli. Real topilma: Toolshop API'da
GET /products?page=-1vapage=abcxato qaytarmaydi, jimgina 1-sahifani beradi (2026-yil oktabrda tekshirildi). Bu xatomi yoki qulaylikmi — talabga qarab hal qilinadi, lekin QA buni albatta qayd etadi.
3. DNS, TCP va TLS — so'rov serverga qanday yetadi {#dns-tls}
DNS — internetning "telefon kitobi"
Kompyuterlar bir-birini nom bilan emas, IP manzil bilan topadi. DNS (Domain Name System) jsonplaceholder.typicode.com kabi nomni IP'ga aylantiradi. Brauzer avval o'z keshiga, keyin operatsion tizimga, so'ng DNS serverga murojaat qiladi.
dig +short jsonplaceholder.typicode.com
# 188.114.96.1
# 188.114.97.1
nslookup jsonplaceholder.typicode.com
# Name: jsonplaceholder.typicode.com
# Address: 188.114.97.1
Ikkita IP qaytgani — sayt CDN (bu holatda Cloudflare) ortida turganini bildiradi. Sizda IP'lar boshqacha chiqishi mumkin, bu normal.
QA hayotidagi DNS holatlari:
- "Staging ochilmayapti" — ko'pincha DNS yozuvi hali tarqalmagan yoki noto'g'ri. Brauzer xatosi:
ERR_NAME_NOT_RESOLVED. - **
/etc/hostsfayli** — ba'zan jamoa test serverga nom bilan kirish uchun shu faylga qator qo'shishni so'raydi. - DNS keshi — server ko'chirilgandan keyin ba'zi foydalanuvchilar hali eski IP'ga borishi mumkin (TTL tugaguncha).
⚠️ Diqqat:
/etc/hostsfaylini o'zgartirish administrator huquqini talab qiladi va butun tizimga ta'sir qiladi. Faqat jamoa ko'rsatmasi bilan o'zgartiring va testdan keyin qatorni qaytarib o'chiring — aks holda keyin "production ochilmayapti" deb vaqt yo'qotasiz.
TCP va TLS (HTTPS)
IP topilgach, brauzer server bilan TCP ulanish o'rnatadi (SYN → SYN-ACK → ACK "qo'l berib ko'rishish"). HTTPS bo'lsa, ustidan TLS handshake bo'ladi: server sertifikat ko'rsatadi, brauzer uni tekshiradi va shifrlash kalitlari kelishiladi. HTTPS = HTTP + TLS.
curl -v bu jarayonni ko'rsatadi (qisqartirilgan, haqiqiy natija):
curl -sv -o /dev/null https://jsonplaceholder.typicode.com/posts/1
# * Connected to jsonplaceholder.typicode.com (188.114.96.1) port 443
# * ALPN: curl offers h2,http/1.1
# * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
# * ALPN: server accepted h2
# > GET /posts/1 HTTP/2
# > Host: jsonplaceholder.typicode.com
# < HTTP/2 200
QA uchun TLS bilan bog'liq tekshiruvlar: sertifikat muddati o'tmaganmi, http:// dan https:// ga yo'naltirish bormi, HTTPS sahifada http:// rasm yoki skript yuklanmayaptimi (mixed content — Console'da ogohlantirish chiqadi).
Vaqt qayerga ketdi? curl -w bilan o'lchash
"Sayt sekin" degan shikoyatni dalilga aylantirish uchun so'rov vaqtini bosqichlarga bo'lib o'lchang:
curl -s -o /dev/null -w "dns: %{time_namelookup}s\ntcp: %{time_connect}s\ntls: %{time_appconnect}s\nttfb: %{time_starttransfer}s\njami: %{time_total}s\nhttp: %{http_version}\n" \
https://jsonplaceholder.typicode.com/posts/1
# dns: 0.087438s
# tcp: 0.251127s
# tls: 0.423945s
# ttfb: 0.594272s
# jami: 0.594820s
# http: 2
Bu qiymatlar yig'ma (har biri boshidan hisoblanadi). Ayirmalar: DNS ≈ 87 ms, TCP ≈ 164 ms, TLS ≈ 173 ms, server javobini kutish ≈ 170 ms. Agar "ttfb" uzun bo'lsa — backend sekin; "dns" uzun bo'lsa — DNS muammosi; "tcp/tls" uzun bo'lsa — tarmoq yoki masofa. DevTools'ning Timing tab'i ham xuddi shu bosqichlarni ko'rsatadi (9-bo'lim).
4. HTTP so'rov va javob {#http}
HTTP — client va server gaplashadigan til. U matnli va tushunarli: so'rov ham, javob ham "boshlang'ich qator + header'lar + bo'sh qator + body" tuzilishiga ega.
Xom (raw) so'rov
GET /posts/1 HTTP/1.1
Host: jsonplaceholder.typicode.com
User-Agent: curl/8.7.1
Accept: */*
Body bilan so'rov (xayoliy DemoBozor API):
POST /api/v1/cart/items HTTP/1.1
Host: api.demobozor.example
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
Accept-Language: uz
{"productId": 1042, "quantity": 2}
Xom javob
Haqiqiy javob (curl -i https://jsonplaceholder.typicode.com/posts/1, qisqartirilgan):
HTTP/2 200
content-type: application/json; charset=utf-8
cache-control: max-age=43200
etag: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"
x-ratelimit-limit: 3600000
cf-cache-status: HIT
server: cloudflare
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit..."
}
Method'lar — qisqacha
| Method | Nima qiladi | DemoBozor misoli |
|---|---|---|
GET | O'qiydi | GET /api/v1/products?query=choynak |
POST | Yangi narsa yaratadi | POST /api/v1/orders |
PUT | To'liq almashtiradi | PUT /api/v1/profile |
PATCH | Qisman o'zgartiradi | PATCH /api/v1/cart/items/7 (quantity) |
DELETE | O'chiradi | DELETE /api/v1/cart/items/7 |
Method'larning xususiyatlari (safe, idempotent) va CRUD bilan bog'liqligi keyingi darsda batafsil: QA 10.
Status kod sinflari
| Sinf | Ma'nosi | Ko'pincha kimga qarash kerak | Misollar |
|---|---|---|---|
1xx | Ma'lumot berish | — | 101 Switching Protocols (WebSocket) |
2xx | Muvaffaqiyat | — | 200 OK, 201 Created, 204 No Content |
3xx | Yo'naltirish / kesh | Konfiguratsiya | 301, 302, 304 Not Modified |
4xx | Mijoz xatosi | So'rov (front-end yoki foydalanuvchi kiritgan ma'lumot) | 400, 401, 403, 404, 422, 429 |
5xx | Server xatosi | Back-end yoki infratuzilma | 500, 502, 503, 504 |
🧠 Esda tuting:
4xx"mijoz aybdor" degani har doim ham emas. Server mavjud mahsulot uchun404qaytarsa — bu back-end bug'i. Status kod — yo'nalish ko'rsatkichi, hukm emas.
QA uchun eng muhim header'lar
| Header | Yo'nalish | Nima uchun QA'ga kerak |
|---|---|---|
Host | So'rov | Qaysi serverga (muhitga) ketayotganini tasdiqlash |
User-Agent | So'rov | Qaysi brauzer/ilova versiyasi — bug report uchun |
Accept-Language | So'rov | Lokalizatsiya: uz, ru, en bo'yicha javob o'zgaradimi |
Content-Type | Ikkalasi | Body formati (application/json) — noto'g'ri bo'lsa, server body'ni o'qiy olmaydi |
Authorization | So'rov | Token yuborilganmi |
Cookie / Set-Cookie | So'rov / javob | Sessiya va holat (5-bo'lim) |
Cache-Control, ETag | Javob | Kesh xatti-harakati (6-bo'lim) |
Location | Javob | 201 yoki 3xx da yangi resurs/yo'naltirish manzili |
Access-Control-Allow-Origin | Javob | CORS (7-bo'lim) |
X-Request-ID (nomi jamoada farq qilishi mumkin) | Javob | So'rovning noyob ID'si — back-end logidan aynan shu so'rovni topish uchun |
💡 Maslahat: Agar loyihangizda javoblarda
X-Request-ID(yokiX-Correlation-ID,traceparent) bo'lsa, uni har bir back-end bug report'iga qo'shing. Dasturchi logdan sizning so'rovingizni bir zumda topadi. Loglar haqida: QA 13.
HTTP/1.1, HTTP/2, HTTP/3
| Versiya | Transport | Asosiy g'oya | DevTools Protocol ustunida |
|---|---|---|---|
| HTTP/1.1 | TCP | Bir ulanishda so'rovlar navbat bilan | http/1.1 |
| HTTP/2 | TCP + TLS | Binary format, bitta ulanishda ko'p so'rov parallel (multiplexing) | h2 |
| HTTP/3 | QUIC (UDP ustida) | Ulanish tezroq o'rnatiladi, paket yo'qolishiga chidamliroq | h3 |
QA uchun amaliy xulosa: versiya odatda biznes mantiqqa ta'sir qilmaydi, lekin "bir brauzerda ishlaydi, boshqasida yo'q" yoki proxy/korporativ tarmoqda g'alati xatolar chiqsa, protokol versiyasini ham bug report'ga yozing.
5. Holat: cookie, session va brauzer xotirasi {#state}
HTTP stateless — server har bir so'rovni alohida, oldingisini eslamasdan qabul qiladi. "Siz tizimga kirgansiz", "savatchada 2 ta choynak bor" kabi holatni saqlash uchun cookie va brauzer xotirasi ishlatiladi.
Cookie va uning atributlari
Server javobda Set-Cookie header'ini yuboradi, brauzer uni saqlaydi va keyingi so'rovlarda Cookie header'ida qaytarib yuboradi. GitHub bosh sahifasidan haqiqiy misol (qiymatlar qisqartirilgan):
set-cookie: _gh_sess=…; path=/; HttpOnly; secure; SameSite=Lax
set-cookie: logged_in=no; expires=Sat, 09 Oct 2027 16:48:14 GMT; domain=.github.com; path=/; HttpOnly; secure; SameSite=Lax
| Atribut | Ma'nosi | QA nimani tekshiradi |
|---|---|---|
Expires / Max-Age | Qachon o'chadi. Ikkalasi bo'lsa — Max-Age ustun | Muddat to'g'rimi; "Meni eslab qol" ishlaydimi |
| (ikkalasi ham yo'q) | Session cookie — brauzer yopilganda o'chadi (sessiyani tiklash funksiyasi buni o'zgartirishi mumkin) | Brauzerni yopib-ochganda holat |
Domain, Path | Cookie qaysi domen/yo'lga yuboriladi | Subdomain'lar orasida login saqlanadimi |
HttpOnly | JavaScript (document.cookie) o'qiy olmaydi | Sessiya cookie'sida albatta bo'lishi kerak (XSS'dan himoya) |
Secure | Faqat HTTPS orqali yuboriladi (localhost bundan mustasno) | Auth cookie'larda bo'lishi shart |
SameSite=Strict | Faqat shu saytning o'zidan kelgan so'rovlarda yuboriladi | Boshqa saytdan link bosib kelganda login "yo'qoladi" — kutilganmi? |
SameSite=Lax | + boshqa saytdan top-level GET navigatsiyada ham yuboriladi | Ko'p brauzerlarda (masalan, Chrome'da) atribut yozilmasa shu qo'llanadi |
SameSite=None | Barcha cross-site so'rovlarda yuboriladi; **Secure majburiy** | Securesiz None — brauzer cookie'ni qabul qilmaydi |
🧠 Esda tuting: Sessiya/auth cookie'si uchun oltin uchlik:
HttpOnly; Secure; SameSite=Lax(yokiStrict). Bittasi yo'qligi — xavfsizlik bo'yicha savol. Batafsil: QA 24.
localStorage, sessionStorage, IndexedDB
| Cookie | localStorage | sessionStorage | IndexedDB | |
|---|---|---|---|---|
| Serverga avtomatik yuboriladimi | Ha, har mos so'rovda | Yo'q | Yo'q | Yo'q |
| Qancha yashaydi | Expires/Max-Age yoki sessiya | O'chirilmaguncha | Tab yopilguncha (har tab — alohida) | O'chirilmaguncha |
| JS o'qiy oladimi | HttpOnly bo'lmasa — ha | Ha | Ha | Ha |
| Odatiy ishlatilishi | Sessiya, auth | Sozlamalar, savatcha, tanlangan til | Vaqtinchalik forma holati | Katta yoki offline ma'lumot |
Real misol: saucedemo holatni qayerda saqlaydi?
Saucedemo'ga standard_user bilan kirib, bitta mahsulot qo'shib, DevTools → Application panelini ochsangiz (2026-yil oktabrda tekshirildi):
- Cookies:
session-username = standard_user—HttpOnlyyo'q,Secureyo'q,SameSite=Lax, muddati kirgandan taxminan 10 daqiqa keyin tugaydi; - Local Storage:
cart-contents = [4]— savatcha butunlay brauzerda saqlanadi (4 — mahsulot ID'si).
Bu kuzatuvlardan chiqadigan QA savollari:
- Cookie
HttpOnlyemas —document.cookieuni o'qiy oladi. Demo ilova uchun mayli, real ilovada sessiya cookie'si uchun bu xavfsizlik topilmasi bo'lardi. - Savatcha localStorage'da — boshqa brauzer yoki qurilmadan kirsangiz, savatcha bo'sh bo'ladi. Talab "savatcha qurilmalar orasida sinxron" desa — bu bug.
cart-contentsni qo'lda[4, 999]ga o'zgartirsangiz nima bo'ladi? Mavjud bo'lmagan mahsulot ID'sini ilova qanday ko'taradi?
Holat bilan bog'liq test g'oyalari
- Logout'dan keyin "Orqaga" tugmasi bilan himoyalangan sahifaga qaytib bo'ladimi?
- Ikki tab: birida logout, ikkinchisida "Sotib olish" bossangiz nima bo'ladi?
- Sessiya muddati checkout'ning o'rtasida tugasa, kiritilgan manzil yo'qolib ketadimi?
- Inkognito oynada, yoki Application → Clear site data dan keyin ilova to'g'ri "toza" holatdan boshlanadimi?
6. Kesh (caching) va kesh bug'lari {#cache}
Kesh — avval yuklangan narsani qayta yuklamaslik uchun nusxa saqlash. U uch joyda bo'lishi mumkin: brauzer keshi, CDN keshi (masalan, Cloudflare) va server keshi.
| Header | Ma'nosi |
|---|---|
Cache-Control: max-age=43200 | 43 200 soniya (12 soat) davomida qayta so'ramasdan ishlatish mumkin |
Cache-Control: no-cache | Saqlash mumkin, lekin har safar server bilan tekshirib olish kerak |
Cache-Control: no-store | Umuman saqlamang (shaxsiy/maxfiy ma'lumot uchun) |
Cache-Control: private / public | Faqat foydalanuvchi brauzeri / CDN ham saqlashi mumkin |
ETag | Resurs versiyasining "barmoq izi" |
If-None-Match | Client: "menda shu ETag bor, o'zgarganmi?" |
304 Not Modified | Server: "o'zgarmagan, keshdagini ishlating" (body yuborilmaydi) |
Age, cf-cache-status: HIT | Javob CDN keshidan kelgan va qancha vaqtdan beri u yerda turibdi |
Jonli tajriba: ETag va 304
# 1) ETag'ni olamiz
curl -sI https://jsonplaceholder.typicode.com/posts/1 | grep -i etag
# etag: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"
# 2) Shu ETag bilan shartli so'rov yuboramiz
curl -s -o /dev/null -w "%{http_code}\n" https://jsonplaceholder.typicode.com/posts/1 \
-H 'If-None-Match: W/"124-yiKdLzqO5gfBrJFrcdJ8Yq0LGnU"'
# 304
ETag qiymati vaqt o'tib o'zgarishi mumkin — 1-buyruqdagi qiymatni 2-buyruqqa o'zingiz qo'ying.
Tipik kesh bug'lari
| Bug | Belgisi | Qanday tekshiramiz |
|---|---|---|
| Deploy'dan keyin eski JS/CSS | Yangi tugma ko'rinmaydi, inkognitoda ko'rinadi | Hard reload; fayl nomlarida hash bormi (app.3f9a1c.js) |
| CDN eski narxni ko'rsatadi | Admin narxni o'zgartirdi, saytda eskisi | Age, cf-cache-status header'lari |
| Shaxsiy ma'lumot umumiy keshda | A foydalanuvchi B'ning profilini ko'radi (juda jiddiy!) | Shaxsiy javoblarda private/no-store bormi |
| PATCH'dan keyin GET eski qiymat | Saqladingiz, ro'yxatda eski | Network'da GET (disk cache) dan kelyaptimi |
Keshni chetlab o'tish usullari:
- Hard reload: macOS'da
Cmd+Shift+R, Windows/Linux'daCtrl+Shift+R; - DevTools → Network → Disable cache (faqat DevTools ochiq turganda ishlaydi);
- inkognito oyna yoki Application → Clear site data.
⚠️ Diqqat: Bug'ni "kesh tufayli" deb yopishdan oldin, uni keshsiz holatda qayta tekshiring. Lekin foydalanuvchilar hard reload qilmaydi — deploy'dan keyin eski fayl ko'rsatilishining o'zi ham bug (cache-busting yo'q).
7. CORS — QA nimani ko'radi {#cors}
Same-origin policy — brauzerning xavfsizlik qoidasi: bir origindan (scheme + host + port) yuklangan sahifadagi JavaScript boshqa origin'ga so'rov yuborib, javobni o'qishi cheklangan. https://demobozor.example sahifasi https://api.demobozor.example ga murojaat qilsa — bu boshqa origin.
Ruxsat berish uchun server CORS header'larini qaytaradi. "Murakkab" so'rovlardan (masalan, Content-Type: application/json bilan POST) oldin brauzer avtomatik preflight — OPTIONS so'rov yuboradi. Jonli misol:
curl -s -i -X OPTIONS https://jsonplaceholder.typicode.com/posts \
-H "Origin: https://demobozor.example" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type"
# HTTP/2 204
# access-control-allow-credentials: true
# access-control-allow-headers: content-type
# access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
# access-control-allow-origin: https://demobozor.example
QA'ga kerakli faktlar:
- CORS xatosi Console'da ko'rinadi:
... has been blocked by CORS policy .... Network'da so'rov qizil bo'lishi yoki javob bo'sh ko'rinishi mumkin. - CORS — faqat brauzer qoidasi.
curl, Postman yoki mobil ilova uni tekshirmaydi. Shuning uchun klassik holat: "Postman'da ishlayapti, saytda ishlamayapti" → katta ehtimol bilan CORS. - Ko'pincha tuzatish back-end/infra konfiguratsiyasida bo'ladi (ruxsat etilgan origin'lar ro'yxati), ba'zan esa front-end noto'g'ri API manzilga murojaat qilayotgan bo'ladi.
⚠️ Diqqat: jsonplaceholder har qanday origin'ni qaytarib "aks ettiradi" va
allow-credentials: trueberadi. Bu ochiq demo API uchun mayli. Cookie bilan ishlaydigan real ilovada esa bunday sozlama xavfsizlik muammosi bo'ladi — QA buni QA 24 dagi checklist bo'yicha tekshiradi.
8. Front-end'mi, back-end'mi? Bug'ni lokalizatsiya qilish {#localize}
Yaxshi QA bug'ni shunchaki "ishlamayapti" deb emas, qaysi qatlamda ekanini ko'rsatib yozadi. Algoritm — avval Network:
Muammo UI'da ko'rindi
│
├─ 1. Network'da tegishli so'rov ketdimi?
│ ├─ Yo'q → FRONT-END (tugma handler'i, validatsiya, JS xato → Console'ni oching)
│ └─ Ha ↓
├─ 2. So'rov to'g'rimi? (URL, method, header'lar, Payload)
│ ├─ Yo'q → FRONT-END (noto'g'ri ma'lumot yuborilgan)
│ └─ Ha ↓
├─ 3. Status kod qanday?
│ ├─ 5xx → BACK-END / infra (X-Request-ID bilan server logini so'rang)
│ ├─ 4xx → so'rov noto'g'rimi yoki back-end qoidasi xatomi — talab bilan solishtiring
│ └─ 2xx ↓
├─ 4. Javobdagi ma'lumot to'g'rimi? (Preview / Response)
│ ├─ Yo'q → BACK-END (noto'g'ri hisob, eski kesh, noto'g'ri filtr)
│ └─ Ha ↓
└─ 5. UI javobni to'g'ri ko'rsatyaptimi?
└─ Yo'q → FRONT-END (render, format, holat boshqaruvi)
DemoBozor misoli: savatchada "Yetkazib berish: 20 000 so'm" ko'rinyapti, mahsulotlar summasi esa 300 000 so'm (qoida bo'yicha bepul bo'lishi kerak).
- Network →
GET /api/v1/cartjavobida"deliveryFee": 0→ API to'g'ri, front-end narxni o'zi noto'g'ri hisoblayapti. - Javobda
"deliveryFee": 20000→ back-end qoidani>bilan yozgan (>=o'rniga) — chegaraviy qiymat bug'i.
| Belgi | Ehtimoliy qatlam |
|---|---|
Console'da qizil TypeError, so'rov yo'q | Front-end |
net::ERR_NAME_NOT_RESOLVED, ERR_CONNECTION_REFUSED | Infra / DNS / server o'chiq |
502 Bad Gateway, 504 Gateway Timeout | Infra yoki back-end (proxy orqasidagi xizmat javob bermadi) |
500 va javobda stack trace | Back-end (+ xavfsizlik topilmasi: ichki xato tafsiloti oshkor bo'lmoqda) |
200, ma'lumot to'g'ri, ekranda noto'g'ri | Front-end |
| Faqat bitta brauzerda | Front-end (moslik) |
| Faqat mobil ilovada, web'da yo'q | Mobil client yoki u chaqiradigan boshqa endpoint (QA 15 bilan trafikni ko'ring) |
Bug report'ga nima qo'shish kerakligi haqida: QA 8.
9. Chrome DevTools — QA'ning asosiy quroli {#devtools}
DevTools'ni ochish: F12, yoki macOS'da Cmd+Option+I, Windows/Linux'da Ctrl+Shift+I. Har qanday element ustida o'ng tugma → Inspect.
Elements
- DOM daraxti va CSS'ni ko'rish. Matnni ikki marta bosib o'zgartirish mumkin — juda uzun nom (50 belgilik ism) dizaynni buzadimi, kod yozmasdan tekshirasiz.
- Force state (
:hover,:focus,:active) — sichqoncha ustida turgandagi holatni "muzlatib" ko'rish. - Yashirin elementlar,
disabledatributi,data-testkabi test atributlarini topish (avtomatlashtirishda kerak bo'ladi — QA 18).
Console
- Qizil xatolar va sariq ogohlantirishlar. Har bir test sessiyasida Console ochiq tursin — UI'da hech narsa ko'rinmasa ham, ichkarida xato bo'lishi mumkin.
- Preserve log — sahifa yangilanganda ham loglar o'chmaydi (redirect'li jarayonlar uchun).
- JavaScript ishga tushirish:
document.cookie,localStorage.getItem('cart-contents'),$0(Elements'da tanlangan element).
Network — eng muhim panel
| Imkoniyat | Qayerda | Nima uchun |
|---|---|---|
| Tur bo'yicha filtr | Fetch/XHR, Doc, JS, CSS, Img, WS… tugmalari | Faqat API so'rovlarini ko'rish |
| Xususiyat filtri | Filter maydoniga status-code:500, mime-type:…, larger-than:1K | Masalan, faqat 500'larni topish |
| Preserve log | Yuqori panel | Redirect va sahifa almashganda so'rovlar yo'qolmaydi |
| Disable cache | Yuqori panel | Birinchi tashrifni simulyatsiya qilish |
| Throttling | No throttling ro'yxati: Fast 4G, Slow 4G, 3G, Offline, Custom | Sekin internetda loading/timeout holatlari |
| So'rov tafsiloti | Headers, Payload, Preview, Response, Timing tab'lari | Nima ketdi, nima keldi, vaqt qayerga ketdi |
Protocol ustuni | Jadval sarlavhasiga o'ng tugma | h2, h3 ni ko'rish |
| Copy as cURL | So'rovga o'ng tugma → Copy | So'rovni terminalda/Postman'da aynan takrorlash |
| Replay XHR | So'rovga o'ng tugma (yoki R) | So'rovni sahifani yangilamasdan qayta yuborish |
| Export HAR | Yuqori paneldagi eksport tugmasi | Butun seansni dasturchiga yuborish |
Throttling nomlari Chrome versiyasiga qarab biroz farq qilishi mumkin — ro'yxatda nima bo'lsa, shuni ishlating.
Timing tab'idagi bosqichlar: Queueing, Stalled, DNS Lookup, Initial connection (TCP va SSL/TLS shu ichida), Request sent, Waiting (TTFB), Content Download. Waiting (TTFB) uzun bo'lsa — server sekin ishlayapti, back-end'ga yozing.
⚠️ Diqqat: HAR faylida so'rov va javoblarning hammasi bo'ladi. Chrome standart holatda sanitized HAR eksport qiladi —
Cookie,Set-CookievaAuthorizationheader'larini olib tashlaydi. To'liq variant (with sensitive data) faqat Settings → Preferences → Network'dagi maxsus sozlama yoqilganda chiqadi. Token yoki shaxsiy ma'lumotli HAR'ni ochiq chatga tashlamang.
Request blocking: DevTools drawer'idagi Network request blocking paneli (yangi versiyalarda — Request conditions) orqali biror URL'ni bloklab, masalan, rasm CDN'i yoki analitika ishlamay qolganda sahifa qanday ko'rinishini tekshirasiz.
Local overrides: so'rovga o'ng tugma → Override content (yoki Override headers). Birinchi marta DevTools fayllarni saqlash uchun papka tanlashni va ruxsat berishni so'raydi; o'zgartirilgan fayllar Sources → Overrides da turadi. Shu yo'l bilan back-end'ga tegmasdan API javobini almashtirib, "savatchada 99 ta mahsulot" yoki "narx null" kabi chekka holatlarda UI'ni tekshirasiz. Overrides yoqilganda kesh o'chadi. Mobil ilova uchun xuddi shu ishni Proxyman'ning Map Local funksiyasi qiladi: QA 15.
Application
- Cookies — ko'rish, tahrirlash, o'chirish (sessiya tugashini simulyatsiya qilish uchun sessiya cookie'sini o'chiring).
- Local Storage / Session Storage / IndexedDB — saqlangan ma'lumotlar.
- Storage → Clear site data — saytni "birinchi kirish" holatiga qaytarish.
Device Mode (responsive)
"Toggle device toolbar" tugmasi orqali yoqiladi. Responsive rejimida kenglikni qo'lda berasiz yoki Dimensions ro'yxatidan qurilma tanlaysiz; DPR, qurilma turi (touch/no touch), aylantirish (rotate) va Sensors panelidan geolokatsiya ham sozlanadi.
🧠 Esda tuting: Google'ning o'zi Device Mode'ni mobil qurilmaning "birinchi yaqinlashuvi" deb ataydi — u Chrome dvigatelida ishlaydi va mobil protsessorni simulyatsiya qila olmaydi. iPhone Safari'dagi bug'lar uchun haqiqiy qurilma yoki simulyator kerak (QA 14).
Lighthouse va Recorder
- Lighthouse — sahifani Performance, Accessibility, Best Practices, SEO bo'yicha avtomatik tekshiradi va hisobot beradi. Chuqurroq: QA 23 va QA 25.
- Recorder — foydalanuvchi oqimini yozib oladi, qayta ijro etadi va performance'ni o'lchaydi. Yozuvni JSON yoki Puppeteer skript sifatida eksport qilish mumkin. Bug report'dagi qadamlarni takrorlanadigan qilish uchun qulay.
10. Cross-browser va responsive testlash {#cross-browser}
Brauzerlar sahifani turli dvigatellar bilan chizadi:
| Brauzer | Dvigatel |
|---|---|
| Chrome, Edge, Opera, Brave | Blink (Chromium) |
| Safari (macOS, iOS) | WebKit |
| Firefox | Gecko |
iOS'da web ko'radigan ilovalar odatda WebKit'dan foydalanishi shart (App Store Review Guideline 2.5.6); muqobil dvigatellarga faqat maxsus ruxsat bilan, EU va Yaponiyada yo'l ochilgan. Ya'ni iPhone'dagi "Chrome" ko'p hollarda ichida Safari dvigateli bilan ishlaydi — Safari bug'i iPhone Chrome'da ham chiqishi mumkin.
Brauzerlar orasida ko'p farq qiladigan joylar:
- sana/vaqt input'lari (
<input type="date">ko'rinishi va formati); - yangi CSS xususiyatlari va shriftlar;
- cookie siyosati (ayniqsa uchinchi tomon cookie'lari) va video autoplay;
- klaviatura, scroll va fokus xatti-harakati.
Responsive testda bitta sahifani bir necha kenglikda tekshiring, masalan 360, 390, 768, 1024, 1280 va 1440 px (aniq ro'yxatni loyihangiz analitikasi va dizayn breakpoint'lari belgilaydi). Har kenglikda: matn kesilmayaptimi, tugmalar ustma-ust tushmayaptimi, gorizontal scroll paydo bo'lmayaptimi, menyu ochilib-yopilyaptimi.
Ko'p brauzerda avtomatik tekshirish — Playwright'ning projects imkoniyati (QA 19); real qurilmalar — device cloud'lar (QA 14).
11. Web testlash checklisti {#web-checklist}
| Soha | Tekshiruvlar |
|---|---|
| Formalar | Majburiy maydonlar, min/max uzunlik, noto'g'ri format, copy-paste, probel bilan boshlanish, Enter bilan yuborish, xato xabari aniq va maydon yonida |
| Ikki marta bosish | "Buyurtma berish"ni tez-tez 2 marta bosish — 2 ta buyurtma yaratilmaydimi |
| Navigatsiya | Orqaga/Oldinga tugmalari, sahifani yangilash (ayniqsa forma yuborilayotganda), chuqur havolani yangi tabda ochish |
| Havolalar | 404'ga olib boradigan havola yo'qmi, tashqi havolalar to'g'ri ochiladimi |
| Holat | Sessiya tugashi, ikki tab, logout'dan keyin "Orqaga", inkognito |
| Tarmoq | Offline va 3G da loading holati, timeout xabari, qayta urinish |
| Console | Asosiy oqimlarda qizil xato yo'q |
| Kesh | Deploy'dan keyin yangi versiya ko'rinadi; shaxsiy sahifalar keshlanmaydi |
| Responsive | Asosiy breakpoint'larda sahifa buzilmaydi |
| Cross-browser | Chrome, Safari, Firefox (+ loyihada kerak bo'lsa Edge) |
| Lokalizatsiya | uz/ru/en matnlari sig'adi, sana dd.mm.yyyy, narx 1 000 000 so'm |
| Xavfsizlik asoslari | HTTPS'ga yo'naltirish, cookie atributlari, xatoda stack trace chiqmaydi |
| Performance asoslari | Lighthouse'da sezilarli muammo yo'q, katta rasmlar optimallashtirilgan |
12. Amaliy mashqlar {#mashqlar}
Mashq 1: URL'ni qismlarga ajrating
Quyidagi xayoliy manzilning scheme, host, path, query parametrlari va fragment'ini yozing. Qaysi qismi serverga yuborilmaydi?
https://demobozor.example/catalog/choynaklar?sort=price_asc&min=150000&page=3#filters
<details> <summary>💡 Javobni ko'rish</summary>
| Qism | Qiymat |
|---|---|
| Scheme | https |
| Host | demobozor.example |
| Port | yozilmagan → HTTPS uchun 443 |
| Path | /catalog/choynaklar |
| Query | sort=price_asc, min=150000, page=3 |
| Fragment | filters |
Serverga fragment (#filters) yuborilmaydi — u faqat brauzerda qoladi. Test g'oyalari: sort ga noma'lum qiymat, min ga manfiy son yoki harf, page=0 berib, server va UI xatti-harakatini kuzating.
</details>
Mashq 2: Kesh header'larini o'qing
curl bilan https://jsonplaceholder.typicode.com/posts/3 ning header'larini oling. Cache-Control va ETag qiymatlarini toping, so'ng shu ETag bilan shartli so'rov yuborib 304 oling.
<details> <summary>💡 Javobni ko'rish</summary>
curl -sI https://jsonplaceholder.typicode.com/posts/3 | grep -iE "cache-control|etag"
# cache-control: max-age=43200
# etag: W/"…" ← sizdagi qiymat
curl -s -o /dev/null -w "%{http_code}\n" https://jsonplaceholder.typicode.com/posts/3 \
-H 'If-None-Match: W/"…"' # ← 1-buyruqdan olingan aniq qiymatni qo'ying
# 304
max-age=43200 — 12 soat. 304 javobida body yo'q: brauzer keshdagi nusxani ishlatadi. Agar 200 qaytsa — ETag'ni noto'g'ri nusxalagansiz (qo'shtirnoqlar va W/ prefiksi ham qiymatning bir qismi).
</details>
Mashq 3: Kimning bug'i?
Har bir holat uchun ehtimoliy qatlamni (front-end, back-end, infra) va asosiy dalilni yozing:
- "To'lash" bosilganda Network'da hech qanday so'rov yo'q, Console'da
TypeError: Cannot read properties of undefined (reading 'id'). GET /api/v1/products?query=choynak→200, javobda 12 ta mahsulot, ekranda "Hech narsa topilmadi".GET /api/v1/cart→200, javobda"subtotal": 300000, "deliveryFee": 20000.- Sayt ochilmaydi, Console/Network'da
net::ERR_NAME_NOT_RESOLVED. POST /api/v1/orders→502 Bad Gateway.
<details> <summary>💡 Javobni ko'rish</summary>
| # | Qatlam | Dalil va izoh |
|---|---|---|
| 1 | Front-end | So'rov umuman ketmagan, JS xatosi — Console screenshot'i va stack trace |
| 2 | Front-end | API to'g'ri ma'lumot berdi, UI ko'rsatmadi — Network Response + ekran screenshot'i |
| 3 | Back-end | 300 000 ≥ 300 000 → bepul bo'lishi kerak. Qoida > bilan yozilgan bo'lishi mumkin (chegaraviy qiymat) — so'rov/javob + X-Request-ID |
| 4 | Infra / DNS | Domen IP'ga aylanmayapti — dig/nslookup natijasi |
| 5 | Infra yoki back-end | Gateway (proxy) orqadagi xizmatdan to'g'ri javob ololmadi — vaqt, X-Request-ID, takrorlanish chastotasi |
</details>
Mashq 4: Cookie viktorinasi
Set-Cookie: sid=abc; Path=/; HttpOnly; Secure; SameSite=Strict— JavaScriptdocument.cookieorqali o'qiy oladimi?http://orqali yuboriladimi? Boshqa saytdagi havolani bosib kelganda yuboriladimi?Set-Cookie: theme=dark; Max-Age=31536000— qancha yashaydi? JS o'qiy oladimi?Set-Cookie: cart=7; SameSite=None— nima bo'ladi?Set-Cookie: lang=uz— bu qanday cookie?
<details> <summary>💡 Javobni ko'rish</summary>
- JS o'qiy olmaydi (
HttpOnly);http://orqali yuborilmaydi (Secure);Strictbo'lgani uchun boshqa saytdan kelgan navigatsiyada ham yuborilmaydi — foydalanuvchi "tizimdan chiqib qolgandek" ko'rinishi mumkin. - 31 536 000 soniya = 365 kun.
HttpOnlyyo'q — JS o'qiy oladi (mavzu sozlamasi uchun bu normal). SameSite=NoneuchunSecuremajburiy — brauzer bunday cookie'ni qabul qilmaydi. Bu — bug.Expiresham,Max-Ageham yo'q → session cookie, brauzer yopilganda o'chadi (sessiyani tiklash funksiyasi buni o'zgartirishi mumkin).
</details>
Mashq 5: Network jadvalini o'qing
Checkout sahifasida "Buyurtma berish" bosilgandan keyingi so'rovlar:
| # | Method | URL | Status | Vaqt |
|---|---|---|---|---|
| 1 | GET | /checkout | 200 | 180 ms |
| 2 | GET | /static/app.3f9a1c.js | 200 | (disk cache) |
| 3 | GET | /api/v1/cart | 200 | 240 ms |
| 4 | POST | /api/v1/orders | 500 | 3 100 ms |
| 5 | GET | /api/v1/orders/undefined | 404 | 90 ms |
Nechta bug bor, ular qaysi qatlamda?
<details> <summary>💡 Javobni ko'rish</summary>
Ikkita alohida bug:
- Back-end:
POST /api/v1/orders→500va 3,1 soniya. Bug report'ga Payload, Response,X-Request-IDva vaqtni qo'shing. - Front-end: xatodan keyin ilova to'xtamagan va
undefinedID bilan buyurtmani so'ragan (/orders/undefined). Front-end xato javobni ushlamayapti — foydalanuvchiga tushunarli xabar ko'rsatish o'rniga mavjud bo'lmagan buyurtmani ochmoqchi bo'lgan.
app.3f9a1c.js ning disk cache dan kelgani — normal (nomida hash bor, deploy'da nom o'zgaradi).
</details>
Mashq 6: DevTools bilan saucedemo holatini tekshiring
https://www.saucedemo.com ga standard_user / secret_sauce bilan kiring, 2 ta mahsulot qo'shing. DevTools → Application'da cookie va localStorage kalitlarini toping. So'ng cart-contents kalitini o'chirib, sahifani yangilang. Nima kuzatdingiz? Kuzatuvni qisqa "topilma" sifatida yozing.
<details> <summary>💡 Javobni ko'rish</summary>
- Cookie:
session-username = standard_user(HttpOnlyvaSecureyo'q,SameSite=Lax, taxminan 10 daqiqa yashaydi). - Local Storage:
cart-contents(masalan,[4,0]) — savatcha brauzerda saqlanadi. cart-contentso'chirilib, sahifa yangilangach savatcha belgisi yo'qoladi — server tomonda savatcha yo'q.
Topilma namunasi: _"Savatcha faqat localStorage'da saqlanadi: boshqa brauzer yoki qurilmada savatcha bo'sh. Agar talabda savatcha sinxronizatsiyasi bo'lsa — bug, bo'lmasa — product owner bilan muhokama qilinadigan risk. Qo'shimcha: sessiya cookie'si HttpOnly emas (demo ilova, real loyihada xavfsizlik topilmasi bo'lardi)."_
</details>
Xulosa {#xulosa}
- So'rov yo'li: DNS → TCP → TLS → HTTP so'rov → server (+DB) → javob → render. Har bosqich o'z bug'iga ega va
curl -wyoki DevTools Timing bilan o'lchanadi. - URL qismlari (ayniqsa query) — eng arzon va samarali test maydoni; fragment serverga yuborilmaydi.
- HTTP stateless; holat cookie va brauzer xotirasida yashaydi. Auth cookie'si uchun
HttpOnly; Secure; SameSiteuchligini tekshiring. - Kesh tezlik beradi, lekin eski fayl, eski narx va eng xavflisi — begona shaxsiy ma'lumot kabi bug'larga olib keladi.
- CORS — faqat brauzer qoidasi: "Postman'da ishlaydi, saytda yo'q" ko'pincha shu.
- Bug'ni lokalizatsiya qilishda avval Network: so'rov ketdimi → to'g'rimi → status → javob → UI.
- DevTools'dagi Copy as cURL, HAR (sanitized), Local overrides va throttling — har kungi QA asboblari.
Keyingi dars: QA 10: API testing (1) — REST, JSON, status kodlar va Postman amaliyoti
Manbalar {#manbalar}
- MDN — An overview of HTTP
- MDN — What is a URL?
- MDN — HTTP response status codes
- MDN — HTTP request methods
- MDN — Evolution of HTTP
- MDN — Using HTTP cookies
- MDN — Set-Cookie header
- MDN — Web Storage API
- MDN — Window: sessionStorage
- MDN — IndexedDB API
- MDN — HTTP caching
- MDN — Cache-Control
- MDN — ETag
- MDN — 304 Not Modified
- MDN — Same-origin policy
- MDN — Cross-Origin Resource Sharing (CORS)
- MDN — Preflight request
- MDN — Rendering engine
- RFC 9110 — HTTP Semantics
- RFC 9111 — HTTP Caching
- RFC 9112 — HTTP/1.1
- RFC 9113 — HTTP/2
- RFC 9114 — HTTP/3
- RFC 6265 — HTTP State Management Mechanism (cookies)
- Chrome DevTools — Inspect network activity
- Chrome DevTools — Network features reference
- Chrome DevTools — Override web content and HTTP response headers locally
- Chrome DevTools — Application panel
- Chrome DevTools — Console
- Chrome DevTools — Elements
- Chrome DevTools — Device mode
- Chrome DevTools — Recorder
- Chrome DevTools — Recorder features reference
- Lighthouse overview
- Apple — App Store Review Guidelines (2.5.6)
- Apple — Using alternative browser engines
- JSONPlaceholder — Guide