Pre programátorov · Java + TestNG + Selenium

Ako to funguje vnútri

Celá automatizácia je Maven projekt s TestNG testami. Jenkins job nerobí nič iné, než že spustí test s parametrami — a test potom kombinuje tri veci: Selenium (preklikanie Spinj), API/MQ volania (ESB a ACE) a databázu (generovanie údajov). Selenium časť je v jadre „find element + click“ — dôležité je pochopiť tok dát okolo nej.

Celý tok od Buildu po e-mail

Jenkins odovzdá parametre testu

Polia z „Build with Parameters“ sa do JVM dostanú ako system properties (-Demail=…, -Dsegment=…). Test si ich číta cez System.getProperty s rozumnými defaultmi.

Validácia vstupov (fail-fast)

E-mail regexom, telefón presne 12 číslic, suma musí byť číslo — a ak je nad 50 000, potichu sa zníži na 50 000. Zlý vstup zhodí beh hneď na začiatku, nie po piatich minútach klikania.

Príprava dát: IČO, meno firmy, majiteľ

IČO sa vygeneruje ako 8-miestne číslo platné podľa modulo 11 (vysvetlenie nižšie); pre municipality sa berie náhodné reálne IČO zo súboru mun_ico.csv. Unikátne meno firmy sa skladá cez DB + BeastMachine. Majiteľ (fyzická osoba) sa vytvorí vopred cez SOAP — nie klikaním.

Selenium: založenie klienta v Spinj (NE64)

Page objecty prekliknú NE64: údaje, sektor, kategória a segment (podľa segment/templates.json), pridanie majiteľa, KYC, marketingové súhlasy, uloženie, podpis, archív dokumentov. Na konci sa vyčíta nové CIS_ID.

Reštart prehliadača, potom účet (IN03 → IN19)

Browser sa zavrie a otvorí nanovo (Edge, 1920×1080), aby nezhavaroval celý proces. Nové prihlásenie, otvorenie účtu cez IN03 na existujúce CIS_ID, dohľadanie cez IN19 — výsledkom je IBAN.

Platba cez ACE/MQ: funguje · podpis funguje

Nadotovanie = vygenerovanie payment document ID cez ESB + odoslanie platobného príkazu ako JMS správa cez IBM MQ do frontu ACE (fronty ACE.GATEWAY). Pôvodné priame SOAP volanie na ESB je v kóde vypnuté. Podpisový vzor a oprávnenia k účtu sa nastavia API volaním. Voliteľne nasleduje úver (createLoan) a kontokorent (createOverdraft).

Zápis CSV a e-mail

Po dobehnutí všetkých klientov (@AfterSuite) sa zapíše results/<názov>.csv so zoznamom vytvorených klientov a Jenkins ho pošle e-mailom.

Kde kód žije

Balík sk.vub.autotests.SPINJ; Finstat časť má vlastný balík sk.vub.autotests.FINSTAT.

Trieda / miestoRolaPoznámka
tests.LEClientAndAccountTestTestNG test — vstupný bodČíta parametre, validuje, volá helper, zbiera výsledky a zapisuje CSV.
helper…selenium.LegalEntityAndAccountHelperOrchestrácia celého scenáraPoradie krokov: klient → účet → dotácia → podpis → úver/kontokorent.
pages.*Selenium page objectyLoginPage, SpinjMainPage, SearchingClientPage, NE64PravnickaOsobaPage, NE64PSektorPage, NE64PMajitelPage, NE64PdotaznikKYCPage, IN03Page, PV01ShowPage, IN19Page. Vnútri „find element + click / fill“.
providers.*Generátory dátLegalEntityDataProvider (dataProvider testu), NameProvider (meno firmy), CompanyNumbersProvider (IČO).
objects.*Dátové objektyNewClient, Account, Customer, NewClientOwner, DatabaseConnection…
helper.requests.*API/MQ helpery (ESB, ACE)ExecutePaymentRequestHelper (platba — cez ACE/MQ, pôvodná ESB cesta vypnutá), AccountRequestHelper (podpisový vzor), LoanServiceHelper, OverdraftServiceHelper.
helper.MQWorkerPPOv2Odosielanie správ do ACE cez IBM MQTLS spojenie (keystore/truststore), sendToACE pošle JMS správu do frontu ACE.GATEWAY s hlavičkami z MQPropertiesAce.
resources/segment/templates.jsonMapa segmentovSegment → sektor / kategória / právna forma; pre corporate a sme_retail vnorené podľa businessType.
FINSTAT.tests.FinstatTestFinstat AUTO jobinsertFinancialStatementOnLegalEntity — vloženie výkazu (rok 2024) a final ratingu vo Finstat Viewer.

Kľúčové miesta v kóde

LEClientAndAccountTest — parametre prichádzajú z Jenkinsu ako system properties

String amountParam    = System.getProperty("amount", "10000").replace(" ", "");
String userEmail      = System.getProperty("email", "jantal@vub.sk").replace(" ", "");
String phoneNumber    = System.getProperty("phoneNumber", "421915558385").replace(" ", "");
String segmentChoice  = System.getProperty("segment", "default").replace(" ", ""); // načítanie z Jenkins
String businessType   = System.getProperty("businessType", "sro").replace(" ", "");
String finalRating    = System.getProperty("finalRating", "").replace(" ", "");

Validácia vstupov — zlý vstup zhodí beh hneď na začiatku

if (!newClient.getEmail().matches("^(.+)@(\\S+)$")) {
    throw new AssertionError("Zadaj platny email do userEmail…");
}
else if (!newClient.getPhoneNumber().matches("^\\d{12}$")) {
    throw new AssertionError("Zadaj cislo na mobile vo formate: 421905123456…");
}
// suma musí byť číslo („veľa“ ani „sto“ neprejde) a viac než 50 000 sa zníži:
if (amountNumber > 50000) { account.setAmount("50000"); }

LegalEntityAndAccountHelper — odkiaľ sú IČO, meno firmy a nastavenie segmentu

// IČO: municipalita berie reálne IČO zo súboru, ostatné segmenty generované — platné podľa modulo 11
if (!newClient.getSegment().equals(municipality)) {
    companyNumber = generateEightDigitNumber();
} else {
    companyNumber = getRandomNumberFromFile();          // mun_ico.csv
}

// unikátne meno firmy: databáza + BeastMachine
DatabaseConnection db = new DatabaseConnection(urlDB, schemaDB, usernameDB, passwordDB);
String companyName = generateFiveDigitAndWordCompanyName(db, beastMachineHelper);

// segment → právna forma/sektor: resources/segment/templates.json;
// pre corporate a sme_retail sa šablóna vyberá ešte podľa businessType
JsonNode segment = json.get(newClient.getSegment());
JsonNode resultSegment = (corporate || sme_retail) ? segment.get(businessType) : segment;

Čo je modulo 11 a prečo na ňom záleží pri IČO

Slovenské IČO je 8-miestne číslo, ktorého posledná (8.) číslica nie je náhodná — je to kontrolná číslica dopočítaná z prvých siedmich číslic. Rovnaký princíp (pod názvom „modulo 11“) sa v slovenských a českých systémoch používa aj pri rodných číslach či číslach bankových účtov. Vďaka nej vie systém jednoducho overiť, či zadané IČO vôbec mohlo vzniknúť, bez toho, aby si ho musel hľadať v registri.

Výpočet kontrolnej číslice:

  1. Prvých sedem číslic IČO sa vynásobí váhami 8, 7, 6, 5, 4, 3, 2 (prvá číslica krát 8, druhá krát 7, atď.).
  2. Súčiny sa spočítajú a spočíta sa zvyšok po delení 11.
  3. Z toho zvyšku sa určí 8. (kontrolná) číslica:
    • zvyšok 0 alebo 10 → kontrolná číslica 1
    • zvyšok 1 → kontrolná číslica 0
    • inak → kontrolná číslica = 11 − zvyšok

Príklad — IČO 10482245

1×8 + 0×7 + 4×6 + 8×5 + 2×4 + 2×3 + 4×2 = 8+0+24+40+8+6+8 = 94
94 mod 11 = 6   →   kontrolná číslica = 11 − 6 = 5   →   IČO končí na 5 ✓

Predtým sa companyNumber generoval ako úplne náhodné 8-miestne číslo, ktoré túto kontrolu spravidla nesplnilo. Generátor teraz dopočíta 8. číslicu podľa modulo 11, takže vygenerovaná firma pôsobí ako reálna aj v systémoch (napr. Obchodný register, Finstat), ktoré si IČO takto overujú.

Nadotovanie účtu — pôvodná cesta cez ESB je v kóde natvrdo vypnutá

public String vytvorPlatbu(NewClient newClient, String endpoint, String generatedPaymentId, String accountFromIban) throws Exception {
    logWarning("!!! Docasne je dotovanie uctu cez ESB vypnute !!!");
    return "platby su vypnute";
    // pôvodný SOAP kód (executeCreditTransfer/1.0) je celý zakomentovaný nižšie —
    // nechaný v repu pre prípad rollbacku, reálne sa už nespúšťa
}

Nová cesta — platba sa posiela ako JMS správa cez IBM MQ do ACE

public String vytvorPlatbuACE(NewClient newClient, String accountFromIban,
        String authorizationUserId, String authorizationUserName,
        String generatedPaymentId, Properties propfile) throws Exception {

    // instrId: dátum (yyMMdd) + "9" + 3-miestny counter + "IBR" (kód zdrojového systému)
    String instrId = datePart + "9" + generateRandomDocId() + "IBR";

    String soapMsgReplaced = soapMsg
            .replace("{msgId}", generatedPaymentId)
            .replace("{amount}", newClient.getAccount().getAmount())
            .replace("{cdtrAcctIBAN}", newClient.getIban())
            .replace("{dbtrAcctIBAN}", accountFromIban);
            // ... + variabilný symbol, dátumy, inštrukčné ID

    MQPropertiesAce mqPropertiesAce = new MQPropertiesAce();
    mqPropertiesAce.service          = "PaymentInitiation";
    mqPropertiesAce.serviceOperation = "initiateCreditTransfer";
    mqPropertiesAce.targetTenant     = "SUBASKBX";
    mqPropertiesAce.sourceSystem     = "IBR";

    MQWorkerPPOv2 mqWorkerPPO = new MQWorkerPPOv2(propfile);
    mqWorkerPPO.sendToACE(soapMsgReplaced, UUID.randomUUID().toString(), mqPropertiesAce);
    // fire-and-forget: čakanie na potvrdzujúcu správu z ACE (receiveFromQueue)
    // je v sendToACE zakomentované — kód teda nekontroluje, či ACE platbu skutočne spracoval
    return "";
}
Fire-and-forget, nie request/response

Na rozdiel od pôvodného priameho SOAP volania na ESB je odoslanie do ACE asynchrónne — správa sa pošle do frontu ACE.GATEWAY a metóda sa hneď vráti. Kód si aktuálne nečíta potvrdzujúcu odpoveď späť (v MQWorkerPPOv2.sendToACE je to zakomentované), takže úspech nadotovania sa v evidencii jobu nevie priamo overiť — spolieha sa na to, že samotné odoslanie do MQ prebehne bez výnimky.

Výstupné CSV — @AfterSuite pozbiera všetkých vytvorených klientov

legalEntityData = legalEntityArray.stream().map(n -> counter.getAndIncrement()
        + ". Cis_id: "       + n.getId()
        + ", Ucet: "          + n.getIban()
        + ", Majitel/Staturar: " + n.getCustomer().getCustomerId()
        + ", Segment: "       + n.getSegment()
        + ", Pobocka: "       + n.getBranch()
        + ", FinalRating: "   + n.getFinalRating())
    .collect(Collectors.toList());

File file = new File("./results/" + legalEntityCsv + ".csv");   // Jenkins ho pošle e-mailom

Známe problémy a kam siahnuť

Nadotovanie účtu (predtým cez ESB) je opravené — beží cez ACE, pozri sekciu vyššie. Nižšie sú problémy, ktoré ešte otvorené sú.

ProblémPrejavKde hľadať
Účelový úver (createLoan) — obmedzený na 2 segmenty Funguje len pre segmenty SME/CORPORATE a SBA/SME_RETAIL. Pri ostatných segmentoch (MUN, SVB, CCD) proces potrebuje iné vstupné dáta, než aké má momentálne k dispozícii. LoanServiceHelper.createCommercialLoan. Podpora ostatných segmentov je vo fáze spracovania.
Kontokorent — limit (rozpracované) Kontokorent sa zriadi s limitom natvrdo nastaveným na pozadí na 100 000 — vlastnú sumu zatiaľ nie je možné zadať cez parameter. Volanie setOverdraftLoanLimits je v kóde zakomentované. Nie je to zámerne vypnuté natrvalo — je to rozrobené, zostáva doladiť detail a otestovať, potom sa odkomentuje. Funguje pre všetky segmenty; segment MUN má na pozadí trochu odlišné spracovanie (implementačný detail bez vplyvu na použitie).
Manuálne nadotovanie mimo automatizovaného jobu

Data Forge obsahuje aj šablónu „Nadotovanie účtu (data_nadotovanie_uctu.csv)“ — hodí sa, keď chceš dotovať účet mimo bežného flow Data creation PO.

Detaily, ktoré sa oplatí vedieť

  • Prečo sa medzi klientom a účtom reštartuje prehliadač: nová inštancia Edge (1920×1080) chráni beh pred zamrznutím Spinj po dokončení NE64 — je to zámer, nie chyba.
  • Vstupné parametre sa menia: podľa požiadaviek používateľov pribúdajú polia (napr. naceCode, legalForm). Ak formulár vyzerá inak než screenshoty, riadiš sa popismi pri poliach — validačné hlášky ťa navedú.
  • Viac klientov na jeden build: newClientCount vytvára klientov sekvenčne — každý ďalší klient pridá k behu ďalších cca 7 minút.
  • Prihlasovacie údaje a endpointy (Spinj login, DB, ESB) žijú v property súbore per prostredie — job (T) a (W) sa líšia práve týmto súborom, kód je rovnaký.
  • Čistý klient bez účtu: odškrtnutý createAccount preskočí celú druhú polovicu flow — vrátane úveru a kontokorentu (sú závislé na účte).