PIPERLINK · ЗВІТ ПРО ТЕСТУВАННЯВигаданий приклад

Приклад звіту про тестування: Acme Portal

Релізний звіт · версія 1.4

Застосунок
Acme Portal — вебзастосунок (Lovable + Supabase, оплата Stripe)
Пакет
Баги + вразливості · 1 платформа (веб)
Збірка
staging, 14 жовтня 2026
Період
14–18 жовтня 2026
Тестували
QA-інженер і фахівець з кібербезпеки piperlink
Номер звіту
PL-R-0042 · версія 1

Це вигаданий приклад, щоб показати формат і глибину звіту. Застосунок, баги, дані й скріншоти не реальні.

01Підсумок

ВердиктНе випускати, доки не виправлені 2 критичні й 3 високі проблеми.

Знайдено

2Критичний
3Високий
3Середній
2Низький

Головні ризики

  1. Подвійне натискання «Оплатити» списує гроші двічі.
  2. Будь-хто з публічним ключем застосунку бачить усі замовлення з адресами й телефонами.
  3. Оплату можна «підтвердити» підробленим запитом — без грошей.

Що добре

Реєстрація, каталог, кошик і адмінка товарів стабільно працюють на обох пристроях. Секретних ключів у коді сторінок немає.

Усі критичні й високі проблеми виправляються промптами з цього звіту. Після виправлень — безкоштовний ретест протягом 14 днів.

02Що тестували

Пристрої й браузери

ПристрійСистемаБраузерЕкран
MacBook Air M2macOS 15.0Chrome 1291440 × 900
iPhone 15iOS 18.0Safari393 × 852

Ролі

Клієнт · Власник магазину · Адміністратор · Без входу

Поза обсягом

Навантажувальне тестування; розрахунок доставки Нової пошти (немає тестового доступу); мобільні застосунки iOS та Android.

5 головних сценаріїв

  1. Реєстрація й вхід (email, Google, скидання пароля)
  2. Каталог → кошик → оплата тестовою карткою
  3. Листи: підтвердження, скидання пароля, чек
  4. Кабінет клієнта: замовлення, профіль
  5. Адмінка: товари, замовлення, ролі

Екрани: 22 з 25, що входять у пакет. Тестові дані: окремі тестові акаунти для кожної ролі, тестова картка Stripe.

03Як тестували

Сценарне тестування

Тест-план із 64 тест-кейсів на 5 головних сценаріїв — кожен пройдено на двох пристроях.

Дослідницьке тестування

Чотири сесії по 60 хвилин: шукаємо, де звичайний клієнт застрягне або зробить щось несподіване.

Негативні й граничні значення

Порожні поля, 1 000 символів, емодзі, номери з «+» і пробілами, минулі дати, повторні натискання.

Ролі й доступ

Кожну дію перевірено під трьома ролями й без входу: хто що бачить і що може змінити.

Вразливості без шкоди

Правила доступу до бази (Supabase RLS), ключі в коді, адмінка й API без входу, підробка оплати, перебір паролів. Лише на тестових акаунтах і власних тестових замовленнях.

Регрес

Після виправлень — ретест кожної проблеми й сценаріїв, яких вона торкається.

Як ми оцінюємо критичність

Критичний
Втрата грошей чи даних, або головний сценарій не працює для всіх.
Високий
Важливий сценарій ламається для частини людей; обхідного шляху немає або він складний.
Середній
Заважає, але є простий обхідний шлях.
Низький
Косметика, текст, рідкісний випадок.

04Результати за сценаріями

СценарійТест-кейсиПройденоНе пройденоЗаблокованоПроблеми
Реєстрація й вхід141220B-02, V-03
Каталог, кошик, оплата161132B-01, B-03, V-02
Листи10910B-05
Кабінет клієнта12930B-04, B-06, V-01
Адмінка121011B-07
Разом6451103

Заблоковано: розрахунок доставки (немає тестового доступу до Нової пошти) і експорт замовлень у CSV (обривається через 30 с — передали команді як питання, не як баг).

05Баги

B-01КритичнийПріоритет P1

Подвійне натискання «Оплатити» створює два замовлення й списує гроші двічі

Сценарій
Каталог, кошик, оплата
Середовище
MacBook Air · Chrome 129 · macOS 15; також iPhone 15 · Safari
Частота
5 з 5
Передумови
Клієнт увійшов, у кошику 1 товар за $24.

Кроки відтворення

  1. Відкрийте сторінку оплати /checkout.
  2. Введіть тестову картку 4242 4242 4242 4242.
  3. Двічі швидко натисніть «Оплатити».

Очікуваний результат

Одне замовлення й одне списання. Поки йде оплата, кнопка неактивна.

Фактичний результат

Створено два замовлення (#1043 і #1044) і два списання по $24 в тестовому кабінеті Stripe.

Скріншот

Stripe · Payments (test mode)

$24.00 · Succeeded · 14:02:11

$24.00 · Succeeded · 14:02:11

Промпт для AI

На сторінці оплати зроби кнопку «Оплатити» неактивною й покажи індикатор від першого натискання, доки запит не завершиться. У функції create-payment зроби запит ідемпотентним: генеруй один ключ на кошик і повертай уже створений платіж, якщо прийшов той самий ключ. Додай тест: два натискання за 300 мс створюють рівно одне замовлення й одне списання.

B-02ВисокийПріоритет P2

Посилання для скидання пароля одразу «недійсне» для клієнтів в Україні

Сценарій
Реєстрація й вхід
Середовище
Обидва пристрої
Частота
5 з 5 (часовий пояс UTC+3)
Передумови
Акаунт клієнта з паролем, часовий пояс Київ.

Кроки відтворення

  1. Натисніть «Забули пароль?» і введіть email.
  2. Відкрийте лист протягом 2 хвилин.
  3. Натисніть посилання в листі.

Очікуваний результат

Форма нового пароля; посилання діє 60 хвилин.

Фактичний результат

Сторінка «Посилання недійсне або застаріло». Ймовірна причина: термін дії порівнюється в місцевому часі, а не в UTC — для Києва посилання «старше» на 3 години.

Скріншот

acme-portal.app/reset

Посилання недійсне або застаріло

Запросити нове посилання

Промпт для AI

Зберігай і порівнюй термін дії токена скидання пароля в UTC (timestamptz), а не в місцевому часі. Додай тест: користувач у часовому поясі UTC+3 відкриває посилання через 2 хвилини — бачить форму нового пароля.

B-03ВисокийПріоритет P2

Після оплати кабінет показує «Очікує оплату», доки не оновити сторінку

Сценарій
Каталог, кошик, оплата
Середовище
Обидва пристрої
Частота
4 з 5
Передумови
Клієнт оплатив замовлення тестовою карткою.

Кроки відтворення

  1. Оплатіть замовлення.
  2. Дочекайтеся повернення на сторінку «Мої замовлення».
  3. Не оновлюйте сторінку 60 секунд.

Очікуваний результат

Статус «Оплачено» з’являється за кілька секунд після підтвердження оплати.

Фактичний результат

Статус лишається «Очікує оплату», кнопка «Завантажити» неактивна. Після оновлення сторінки — «Оплачено».

Скріншот

acme-portal.app/orders

Замовлення #1045 · Очікує оплату

Завантажити (неактивно)

Промпт для AI

На сторінці «Мої замовлення» підпишися на зміни статусу замовлення (Supabase Realtime) або перевіряй статус кожні 3 секунди протягом 60 секунд після повернення з оплати. Щойно статус «paid» — онови картку й увімкни кнопку «Завантажити».

B-04СереднійПріоритет P3

Поле «Телефон» відхиляє номери з «+» і пробілами

Сценарій
Кабінет клієнта
Середовище
Обидва пристрої
Частота
5 з 5
Передумови
Клієнт у профілі.

Кроки відтворення

  1. Відкрийте «Профіль».
  2. Введіть +380 67 123 45 67.
  3. Натисніть «Зберегти».

Очікуваний результат

Номер зберігається у форматі +380671234567.

Фактичний результат

Помилка «Невірний формат». Приймається лише 0671234567.

Скріншот

acme-portal.app/profile

Телефон: +380 67 123 45 67

Невірний формат

Промпт для AI

У полі «Телефон» перед перевіркою прибирай пробіли, дужки й дефіси та приймай міжнародний формат з «+». Зберігай номер у форматі E.164 (+380671234567). Додай тести для «+380 67 123 45 67», «067-123-45-67» і «(067) 123 45 67».

B-05СереднійПріоритет P3

Лист «Ваше замовлення прийнято» приходить англійською при українській мові інтерфейсу

Сценарій
Листи
Середовище
Поштові клієнти Gmail і Apple Mail
Частота
5 з 5
Передумови
Мова інтерфейсу — українська.

Кроки відтворення

  1. Оформіть замовлення.
  2. Відкрийте лист-підтвердження.

Очікуваний результат

Лист українською, як і інтерфейс.

Фактичний результат

Тема й текст листа англійською: «Your order has been received».

Скріншот

Gmail · Вхідні

Your order has been received

Order #1045 · $24.00

Промпт для AI

Зберігай мову, яку клієнт обрав в інтерфейсі, у профілі та в замовленні. Надсилай лист-підтвердження шаблоном цієї мови; якщо мови немає — українською.

B-06НизькийПріоритет P4

Порожня сторінка «Мої замовлення» показує «undefined»

Сценарій
Кабінет клієнта
Середовище
Обидва пристрої
Частота
5 з 5
Передумови
Новий акаунт без замовлень.

Кроки відтворення

  1. Увійдіть у новий акаунт.
  2. Відкрийте «Мої замовлення».

Очікуваний результат

Текст «У вас ще немає замовлень» і кнопка «До каталогу».

Фактичний результат

На сторінці написано «undefined».

Скріншот

acme-portal.app/orders

undefined

Промпт для AI

На сторінці «Мої замовлення», коли список порожній, показуй текст «У вас ще немає замовлень» і кнопку «До каталогу» замість значення змінної.

B-07НизькийПріоритет P4

Адмінка: сортування замовлень за датою працює як за текстом

Сценарій
Адмінка
Середовище
MacBook Air · Chrome 129
Частота
5 з 5
Передумови
Роль «Адміністратор», є замовлення 9.10 і 10.10.

Кроки відтворення

  1. Відкрийте «Замовлення».
  2. Відсортуйте за датою.

Очікуваний результат

10.10 після 9.10.

Фактичний результат

10.10 стоїть перед 9.10 — дати порівнюються як рядки.

Скріншот

acme-portal.app/admin/orders

10.10.2026 · #1040

9.10.2026 · #1039

Промпт для AI

В адмінці сортуй замовлення за полем created_at (дата й час), а не за відформатованим рядком дати.

06Вразливості

V-01КритичнийOWASP A01 · Broken Access Control (CWE-284)

Таблиця замовлень доступна будь-кому з публічним ключем

Де
Supabase, таблиця orders: Row Level Security вимкнено.
Наслідки
Витік особистих даних усіх клієнтів. Це порушення закону про захист персональних даних і GDPR.

Як перевірили

Під тестовим акаунтом клієнта B зробили запит до REST API Supabase з публічним ключем, який видно в коді сторінки. Отримали всі замовлення, зокрема тестового клієнта A: імена, адреси, телефони. Нічого не змінювали.

Промпт для AI

Увімкни Row Level Security для таблиці public.orders. Додай політики: клієнт бачить лише рядки, де customer_id = auth.uid(); власник магазину — лише замовлення свого магазину; вставка, зміна й видалення з браузера заборонені, замовлення створює лише функція create-order. Перевір двома тестовими акаунтами: клієнт B не бачить замовлень клієнта A.

V-02ВисокийOWASP A08 · Software and Data Integrity Failures (CWE-345)

Webhook оплати не перевіряє підпис — оплату можна підробити

Де
Функція payment-webhook.
Наслідки
Будь-хто може отримати товар чи доступ без оплати.

Як перевірили

Надіслали на /functions/v1/payment-webhook тестовий запит без підпису Stripe для власного тестового замовлення. Замовлення стало «Оплачено» без жодного платежу.

Промпт для AI

У функції payment-webhook перевіряй заголовок Stripe-Signature секретом вебхука (stripe.webhooks.constructEvent) і відхиляй запити без правильного підпису з кодом 400. Познач замовлення оплаченим лише якщо сума й валюта платежу збігаються із замовленням.

V-03СереднійOWASP A07 · Identification and Authentication Failures (CWE-307)

Вхід не обмежує кількість спроб пароля

Де
Сторінка входу й Supabase Auth.
Наслідки
Пароль можна підібрати перебором.

Як перевірили

Для власного тестового акаунта ввели 50 неправильних паролів за хвилину — без блокування, затримки чи капчі.

Промпт для AI

Обмеж спроби входу: після 5 невдалих спроб за 15 хвилин для одного email або IP — затримка й капча. Увімкни захист від перебору в налаштуваннях Supabase Auth і покажи зрозуміле повідомлення «Забагато спроб, спробуйте за кілька хвилин».

07Що працює добре

  • Реєстрація з email і через Google на обох пристроях.
  • Каталог, фільтри й пошук працюють швидко; порожній пошук показує підказку.
  • Кошик зберігається між сесіями й пристроями.
  • Адмінка: додавання й редагування товарів, призначення ролей.
  • Адмінка недоступна без входу й для ролі «Клієнт».
  • У коді сторінок немає секретних ключів — лише публічний ключ Supabase, і це нормально.

08Ретест і вердикт

Ретест 21 жовтня 2026 (приклад)

№ПроблемаСтатус
V-01Таблиця замовлень доступна всімВиправлено ✓
B-01Подвійне списанняВиправлено ✓
V-02Підробка оплатиВиправлено ✓
B-02Посилання скидання пароляВиправлено ✓
B-03Статус після оплатиВиправлено ✓
V-03Перебір паролівВиправлено ✓
B-04Поле «Телефон»Ще не працює
B-05Мова листаНе виправляли
B-06«undefined»Не виправляли
B-07Сортування датНе виправляли
ВердиктМожна випускати: критичних і високих проблем не лишилось. B-04 і проблеми низької критичності — на ваш розсуд у наступному оновленні.

Рішення про реліз — за вами. Ми даємо докази в межах тест-плану; тестування не гарантує, що багів не лишилось.