Files
erv-clientright/hotels/qa-report-erv-hotels-form-2026-03-13.md
2026-03-13 10:42:01 +03:00

9.1 KiB
Raw Permalink Blame History

QA report: ERV Hotels claim form

Date: 2026-03-13 URL: https://erv.clientright.ru/hotels/ Scope: manual code-assisted QA review of masks, validation, policy check flow, SMS flow, step logic, and submission flow.

Executive summary

The form is generally wired up and backend endpoints respond, but there are several important frontend issues.

Most important findings:

  1. Critical: form submission appears to bypass real SMS-confirmation gating.
  2. High: Tab is blocked on the first input field.
  3. Medium: jQuery is loaded twice.
  4. Medium: policy-number normalization is incomplete and fragile.
  5. Medium: phone validation logic is strict and should be regression-tested with paste scenarios.

Confirmed observations

Backend policy check responds correctly

Endpoint: database.php

Tested cases:

  • empty payload → returns {"success":"false","message":"Номер полиса не указан"}
  • invalid policy number → returns {"success":"false","message":"Полис не найден"}

This part looks alive and generally sane.


Findings

1) CRITICAL — submit flow appears to bypass actual SMS confirmation

Why this is critical

In the submit handler, the code opens the SMS modal but still proceeds directly to submit.php because the condition is hardcoded as if(1).

Relevant code pattern

$('.form.active form').submit(function(e){
  if(!validate_step(index)){ e.preventDefault(); } else {
    e.preventDefault();
    $('button[type="submit"]').attr("disabled", true);

    if(1) {
      $.fancybox.open({ src: '#confirm_sms', type: 'inline' });
      ...
      $.ajax({
        url: 'submit.php',
        method: 'post',
        ...
      });

Risk

The form may be submitted even if SMS code was not actually confirmed.

Expected behavior

Submission to submit.php should only happen after successful SMS verification.

Replace the hardcoded if(1) with a real condition based on verified phone state, for example:

  • a dedicated boolean like smsVerified === true
  • or a validated marker on the phone field after successful verification
  • and prevent submit entirely until SMS verification succeeds

Suggested implementation direction

  • set explicit state after successful sms-verify.php?action=verify
  • on form submit, check that state
  • only then build FormData and call submit.php

2) HIGH — Tab key is blocked on the first input

Relevant code

document.querySelector('input').addEventListener('keydown', function (e) {
  if (e.which == 9) {
    e.preventDefault();
  }
});

Problem

This blocks Tab on the first input field.

User impact

  • keyboard navigation is broken
  • accessibility is degraded
  • desktop UX becomes weird and frustrating

Expected behavior

Tab should move focus to the next field normally.

Remove this listener entirely unless there is a very specific documented reason.


3) MEDIUM — jQuery is included twice

Current page includes

<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
<script src="libs/jquery/jquery-3.4.1.min.js"></script>

Risk

  • plugin conflicts
  • unexpected behavior depending on initialization order
  • harder debugging

Expected behavior

Only one jQuery version should be loaded.

Keep a single version and verify plugins against it.


4) MEDIUM — policy number normalization is incomplete / fragile

Current behavior

The code only explicitly normalizes Cyrillic:

  • ЕE
  • АA

Relevant logic

if(police_number.slice(0,1)=="Е"){
  police_number=police_number.replace(/Е/g, 'E');
}

if(police_number.slice(0,1)=="А"){
  police_number=police_number.replace(/А/g, 'A');
}

Risk

User input may still fail in edge cases:

  • pasted values with spaces
  • other Cyrillic lookalikes
  • lowercase input
  • mixed formatting

Expected behavior

Policy number should be normalized consistently before validation / sending.

Before submit/check:

  • trim()
  • uppercase
  • replace common Cyrillic lookalikes with Latin equivalents
  • normalize spaces
  • possibly normalize dash types

5) MEDIUM — applicant phone validation needs regression testing for paste/input scenarios

Current logic

Applicant phone (.js-phone-mask) is normalized to Russian 10-digit local format and validated strictly.

Relevant behavior

  • strips +7 / 8
  • keeps only 10 digits
  • formats as 999 999-99-99

Potential issue areas

  • paste of +7 912 345-67-89
  • paste of 8 (912) 345-67-89
  • typing starting with 8 or 7
  • editing in the middle of the string
  • overlong paste values

Expected behavior

All common Russian user inputs should normalize cleanly and predictably.

  • 9123456789
  • 8 912 345-67-89
  • +7 912 345-67-89
  • 89123456789
  • 79123456789
  • paste with brackets/spaces/dashes

6) MEDIUM — hotel phone field uses separate validation logic and should be tested independently

Current logic

Hotel phone (.js-place-phone) allows 10 to 15 digits.

Risk

International phone scenarios may behave inconsistently:

  • with +
  • with spaces
  • with brackets
  • with short local numbers

Expected behavior

Visible, predictable validation for international hotel contact numbers.

  • +49 30 12345678
  • +1 (555) 123-4567
  • 0049...
  • short invalid numbers
  • numbers over 15 digits

7) MEDIUM — description field has hard limits; UX should be checked

Current logic

Description requires:

  • minimum 50 characters
  • maximum 2000 characters

Risk

Users may be blocked without clear enough guidance.

Expected behavior

  • clear live or submit-time feedback
  • understandable character requirement

Consider a live character counter or helper text.


8) MEDIUM — file requirements for selected hotel risks should be regression-tested in browser

Current logic

On hotel-2:

  • at least one risk checkbox must be selected
  • if a risk is selected, a supporting file is required
  • unchecking should clear file state

Why this matters

This logic is easy to break in real browser interaction.

  • select risk without file → should block next/submit
  • add file → should pass
  • uncheck risk after upload → file state should reset cleanly
  • re-check and re-upload → should still work

9) LOW — duplicated / potentially confusing SMS UI flow

Observed behavior in code

The SMS modal and button state handling are fairly complex:

  • cooldown timer
  • resend behavior
  • modal warnings
  • direct phone field locking after success

This may be fine, but it is sensitive to regressions.

Recommendation

Simplify state handling where possible and ensure there is a single source of truth:

  • not verified
  • sending
  • code sent
  • verified

Suggested fixes by priority

Priority P1

  1. Fix submit flow so submit.php is called only after successful SMS verification.
  2. Remove the Tab blocker on the first input.

Priority P2

  1. Remove duplicate jQuery include.
  2. Harden policy number normalization.

Priority P3

  1. Regression-test applicant phone paste/typing behavior.
  2. Regression-test hotel phone international input behavior.
  3. Regression-test file upload behavior on hotel-2.
  4. Improve UX around description-length validation.

Suggested manual QA checklist for Cursor / further automation

Policy check

  • empty policy number
  • invalid policy number
  • valid-format policy number with slash
  • Cyrillic first letter (А, Е)
  • paste with spaces

Date of birth / representative block

  • adult DOB
  • minor DOB
  • representative block shown only for minors
  • representative fields disabled/hidden correctly otherwise

Applicant phone

  • direct typing: 9123456789
  • paste: +7 912 345-67-89
  • paste: 8 (912) 345-67-89
  • reject incomplete values
  • reject non-digit garbage cleanly

Hotel phone

  • accept international-looking values
  • reject too short values
  • reject too long values

Email

  • valid email
  • invalid email without domain
  • invalid email without @
  • trim spaces around value

Files

  • required file missing for selected risk
  • file upload passes when attached
  • file reset after uncheck
  • re-upload after returning back in steps

Description

  • under 50 chars → error
  • exactly 50 chars → pass
  • over 2000 chars → error

Final submit

  • no agreement checkbox → block
  • with agreement → allow
  • ensure SMS verified state is mandatory before actual submit

Important note

This report is based on:

  • live endpoint checks
  • frontend source review
  • flow analysis of production JS

A full browser-driven E2E pass is still recommended after fixes, especially for:

  • file uploads
  • modal transitions
  • SMS flow
  • step navigation

Best next step for Cursor

Ask Cursor to:

  1. inspect common.js
  2. fix the submit/SMS gating bug first
  3. remove the Tab blocker
  4. remove duplicate jQuery include
  5. add robust input normalization for policy/phone
  6. produce a small browser regression checklist after patching