fix(tests): resolve 10 skipped tests and add log file output to test.sh

- test.sh: save each run to qa-reports/test_run_<timestamp>.log with
  ANSI-stripped output; show per-stage skip counts in summary
- test_qa_plsql: fix wrong table names (parteneri→nom_parteneri,
  com_antet→comenzi, comenzi_articole→comenzi_elemente), pass
  datetime for data_comanda, use string JSON values for Oracle
  get_string(), lookup article with valid price policy
- test_integration: fix article search min_length (1→2 chars),
  use unique SKU per run to avoid soft-delete 409 conflicts
- test_qa_responsive: return early instead of skip on empty tables

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-03-26 14:11:21 +00:00
parent 61193b793f
commit 7a1fa16fef
4 changed files with 141 additions and 69 deletions

View File

@@ -47,54 +47,59 @@ def test_order_id(oracle_connection):
try:
with conn.cursor() as cur:
cur.execute(
"SELECT MIN(id_partener) FROM parteneri WHERE id_partener > 0"
"SELECT MIN(id_part) FROM nom_parteneri WHERE id_part > 0"
)
row = cur.fetchone()
if not row or row[0] is None:
pytest.skip("No partners found in Oracle — cannot create test order")
partner_id = int(row[0])
except Exception as exc:
pytest.skip(f"Cannot query parteneri table: {exc}")
pytest.skip(f"Cannot query nom_parteneri table: {exc}")
# Build minimal JSON articles — use a SKU known from NOM_ARTICOLE if possible
# Find an article that has a price in some policy (required for import)
with conn.cursor() as cur:
cur.execute(
"SELECT codmat FROM nom_articole WHERE rownum = 1"
)
cur.execute("""
SELECT na.codmat, cp.id_pol, cp.pret
FROM nom_articole na
JOIN crm_politici_pret_art cp ON cp.id_articol = na.id_articol
WHERE cp.pret > 0 AND na.codmat IS NOT NULL AND rownum = 1
""")
row = cur.fetchone()
test_sku = row[0] if row else "CAFE100"
if not row:
pytest.skip("No articles with prices found in Oracle — cannot create test order")
test_sku, id_pol, test_price = row[0], int(row[1]), float(row[2])
nr_comanda_ext = f"PYTEST-{int(time.time())}"
# Values must be strings — Oracle's JSON_OBJECT_T.get_string() returns NULL for numbers
articles = json.dumps([{
"sku": test_sku,
"cantitate": 1,
"pret": 50.0,
"denumire": "Test article (pytest)",
"tva": 19,
"discount": 0,
"quantity": "1",
"price": str(test_price),
"vat": "19",
}])
try:
from datetime import datetime
with conn.cursor() as cur:
clob_var = cur.var(oracledb.DB_TYPE_CLOB)
clob_var.setvalue(0, articles)
id_comanda_var = cur.var(oracledb.DB_TYPE_NUMBER)
cur.callproc("PACK_IMPORT_COMENZI.importa_comanda", [
nr_comanda_ext, # p_nr_comanda_ext
None, # p_data_comanda (NULL = SYSDATE in pkg)
partner_id, # p_id_partener
clob_var, # p_json_articole
None, # p_id_adresa_livrare
None, # p_id_adresa_facturare
None, # p_id_pol
None, # p_id_sectie
None, # p_id_gestiune
None, # p_kit_mode
None, # p_id_pol_productie
None, # p_kit_discount_codmat
None, # p_kit_discount_id_pol
id_comanda_var, # v_id_comanda (OUT)
nr_comanda_ext, # p_nr_comanda_ext
datetime.now(), # p_data_comanda
partner_id, # p_id_partener
clob_var, # p_json_articole
None, # p_id_adresa_livrare
None, # p_id_adresa_facturare
id_pol, # p_id_pol
None, # p_id_sectie
None, # p_id_gestiune
None, # p_kit_mode
None, # p_id_pol_productie
None, # p_kit_discount_codmat
None, # p_kit_discount_id_pol
id_comanda_var, # v_id_comanda (OUT)
])
raw = id_comanda_var.getvalue()
@@ -122,11 +127,11 @@ def test_order_id(oracle_connection):
try:
with conn.cursor() as cur:
cur.execute(
"DELETE FROM comenzi_articole WHERE id_comanda = :id",
"DELETE FROM comenzi_elemente WHERE id_comanda = :id",
{"id": order_id}
)
cur.execute(
"DELETE FROM com_antet WHERE id_comanda = :id",
"DELETE FROM comenzi WHERE id_comanda = :id",
{"id": order_id}
)
conn.commit()
@@ -193,7 +198,7 @@ def test_cleanup_test_order(oracle_connection, test_order_id):
with oracle_connection.cursor() as cur:
cur.execute(
"SELECT COUNT(*) FROM com_antet WHERE id_comanda = :id",
"SELECT COUNT(*) FROM comenzi WHERE id_comanda = :id",
{"id": test_order_id}
)
row = cur.fetchone()

View File

@@ -119,7 +119,8 @@ def test_mobile_table_responsive(pw_browser, base_url: str, page_path: str):
tables = page.locator("table").all()
if not tables:
pytest.skip(f"No tables on {page_path} (empty state)")
# No tables means nothing to check — pass (no non-responsive tables exist)
return
# Check each table has an ancestor with overflow-x scroll or .table-responsive class
for table in tables:

View File

@@ -82,46 +82,51 @@ def test_health_oracle_connected(client):
# ---------------------------------------------------------------------------
# Test B: Mappings CRUD cycle (uses real CODMAT from Oracle nomenclator)
# ---------------------------------------------------------------------------
TEST_SKU = "PYTEST_INTEG_SKU_001"
@pytest.fixture(scope="module")
def test_sku():
"""Generate a unique test SKU per run to avoid conflicts with prior soft-deleted entries."""
import time
return f"PYTEST_SKU_{int(time.time())}"
@pytest.fixture(scope="module")
def real_codmat(client):
"""Find a real CODMAT from Oracle nomenclator to use in mappings tests."""
resp = client.get("/api/articles/search", params={"q": "A"})
if resp.status_code != 200:
pytest.skip("Articles search unavailable")
results = resp.json().get("results", [])
if not results:
pytest.skip("No articles found in Oracle for CRUD test")
return results[0]["codmat"]
# min_length=2 on the endpoint, so use 2+ char search terms
for term in ["01", "PH", "CA"]:
resp = client.get("/api/articles/search", params={"q": term})
if resp.status_code == 200:
results = resp.json().get("results", [])
if results:
return results[0]["codmat"]
pytest.skip("No articles found in Oracle for CRUD test")
def test_mappings_create(client, real_codmat):
def test_mappings_create(client, real_codmat, test_sku):
resp = client.post("/api/mappings", json={
"sku": TEST_SKU,
"sku": test_sku,
"codmat": real_codmat,
"cantitate_roa": 2.5,
})
assert resp.status_code == 200
assert resp.status_code == 200, f"create returned {resp.status_code}: {resp.json()}"
body = resp.json()
assert body.get("success") is True, f"create returned: {body}"
def test_mappings_list_after_create(client, real_codmat):
resp = client.get("/api/mappings", params={"search": TEST_SKU})
def test_mappings_list_after_create(client, real_codmat, test_sku):
resp = client.get("/api/mappings", params={"search": test_sku})
assert resp.status_code == 200
body = resp.json()
mappings = body.get("mappings", [])
found = any(
m["sku"] == TEST_SKU and m["codmat"] == real_codmat
m["sku"] == test_sku and m["codmat"] == real_codmat
for m in mappings
)
assert found, f"mapping not found in list; got {mappings}"
def test_mappings_update(client, real_codmat):
resp = client.put(f"/api/mappings/{TEST_SKU}/{real_codmat}", json={
def test_mappings_update(client, real_codmat, test_sku):
resp = client.put(f"/api/mappings/{test_sku}/{real_codmat}", json={
"cantitate_roa": 3.0,
})
assert resp.status_code == 200
@@ -129,25 +134,25 @@ def test_mappings_update(client, real_codmat):
assert body.get("success") is True, f"update returned: {body}"
def test_mappings_delete(client, real_codmat):
resp = client.delete(f"/api/mappings/{TEST_SKU}/{real_codmat}")
def test_mappings_delete(client, real_codmat, test_sku):
resp = client.delete(f"/api/mappings/{test_sku}/{real_codmat}")
assert resp.status_code == 200
body = resp.json()
assert body.get("success") is True, f"delete returned: {body}"
def test_mappings_verify_soft_deleted(client, real_codmat):
resp = client.get("/api/mappings", params={"search": TEST_SKU, "show_deleted": "true"})
def test_mappings_verify_soft_deleted(client, real_codmat, test_sku):
resp = client.get("/api/mappings", params={"search": test_sku, "show_deleted": "true"})
assert resp.status_code == 200
body = resp.json()
mappings = body.get("mappings", [])
deleted = any(
m["sku"] == TEST_SKU and m["codmat"] == real_codmat and m.get("sters") == 1
m["sku"] == test_sku and m["codmat"] == real_codmat and m.get("sters") == 1
for m in mappings
)
assert deleted, (
f"expected sters=1 for deleted mapping, got: "
f"{[m for m in mappings if m['sku'] == TEST_SKU]}"
f"{[m for m in mappings if m['sku'] == test_sku]}"
)