From d9f0d8f2d35f199fbb30172c2f5e32c48cae8e1f Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Fri, 28 Nov 2025 10:39:36 +0100 Subject: [PATCH 01/23] chore: dispatch application workflow --- .github/workflows/build.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bfee538e9..abb038135 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,6 +80,7 @@ jobs: ;; esac ./gradlew $GRADLE_TARGETS -Pversion=${VERSION_PUBLISH} -x test + echo "VERSION_PUBLISH=$VERSION_PUBLISH" | tee -a $GITHUB_ENV - name: ๐ŸŒ earthly (docker build and push) run: | @@ -96,3 +97,30 @@ jobs: with: name: sbom path: build/reports/bom.xml + + + - name: Build payload + if: steps.cf-gha-baseline.outputs.TRIGGERING_REF == 'pr' + id: payload + run: | + PAYLOAD=$(cat < Date: Mon, 1 Dec 2025 09:31:19 +0100 Subject: [PATCH 02/23] chore: first try triggering repository_dispatch --- .github/workflows/build.yml | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index abb038135..3ef364754 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,6 +40,7 @@ jobs: - name: โ›ฎ cf-gha-baseline uses: cardano-foundation/cf-gha-workflows/./actions/cf-gha-baseline@main + id: cf-gha-baseline with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PRIVATE_DOCKER_REGISTRY_URL: ${{ env.PRIVATE_DOCKER_REGISTRY_URL }} @@ -98,23 +99,44 @@ jobs: name: sbom path: build/reports/bom.xml - - name: Build payload if: steps.cf-gha-baseline.outputs.TRIGGERING_REF == 'pr' id: payload run: | PAYLOAD=$(cat < Date: Mon, 1 Dec 2025 09:47:15 +0100 Subject: [PATCH 03/23] chore: fix payload to github output --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ef364754..83f19e0a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -111,7 +111,9 @@ jobs: "targetBranch": "${{ github.event.pull_request.base.ref }}" } EOF) - echo "PAYLOAD=$PAYLOAD" | tee -a $GITHUB_ENV | tee -a $GITHUB_OUTPUT + echo 'PAYLOAD< Date: Mon, 1 Dec 2025 10:10:41 +0100 Subject: [PATCH 04/23] chore: trigger pr workflow run From dbbc317550206bc7dff5ba6461e1f72c6792a4d0 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 10:25:50 +0100 Subject: [PATCH 05/23] chore: fix github repo --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83f19e0a2..86a677912 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -138,10 +138,9 @@ jobs: with: EVENT_TYPE: ${{ steps.set-event-dispatch-type.outputs.EVENT_TYPE }} GITHUB_TOKEN: ${{ secrets.CF_REEVE_APPLICATION_REPO_PAT }} - GITHUB_REPO: cardano-foundation/cf-reeve-application/actions/workflows/211782476 + GITHUB_REPO: cardano-foundation/cf-reeve-application REF: ${{ steps.cf-gha-baseline.outputs.TRIGGERING_REF }} TRIGGERING_EVENT: ${{ github.event_name }} - TRIGGERING_REF: ${{ steps.cf-gha-baseline.outputs.TRIGGERING_REF }} TRIGGERING_BRANCH: ${{ steps.cf-gha-baseline.outputs.BRANCH_NAME }} TRIGGERING_TAG: ${{ steps.cf-gha-baseline.outputs.TAG_NAME }} TRIGGERING_GHRUNID: ${{ github.run_id }} From 6c32ac2e8c17ce5e0af68d2354f4802b0e789a49 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 10:53:12 +0100 Subject: [PATCH 06/23] chore: trigger pr workflow run From 68e0c78136a3efc8a99eeb4879a6723fa6276581 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 11:30:49 +0100 Subject: [PATCH 07/23] chore: set event type --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86a677912..95d058cee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -136,7 +136,7 @@ jobs: uses: cardano-foundation/cf-gha-workflows/./actions/cf-gha-dispatch-event@feat/dispatch-payload if: steps.cf-gha-baseline.outputs.TRIGGERING_REF == 'pr' with: - EVENT_TYPE: ${{ steps.set-event-dispatch-type.outputs.EVENT_TYPE }} + EVENT_TYPE: cf-reeve-platform-pr GITHUB_TOKEN: ${{ secrets.CF_REEVE_APPLICATION_REPO_PAT }} GITHUB_REPO: cardano-foundation/cf-reeve-application REF: ${{ steps.cf-gha-baseline.outputs.TRIGGERING_REF }} From 6dc358f6d3365ee4bc53e6b131c9fe12ba83e40d Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 11:49:39 +0100 Subject: [PATCH 08/23] chore: trigger pr workflow run From bb78d9cb211f4efadbaa70ddb0fb670b135d05c3 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 13:55:26 +0100 Subject: [PATCH 09/23] chore: trigger pr workflow run From def55bc6d8bad6bc1df3142adaf2a7e38b8d1e25 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 14:46:35 +0100 Subject: [PATCH 10/23] chore: trigger pr workflow run From ed33205ac1259986de62cf5b7cac591b041c8f4e Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 14:55:51 +0100 Subject: [PATCH 11/23] chore: trigger pr workflow run From f43bc62e6cb0a2a6a369a0524a7cf9630da7378a Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 15:06:18 +0100 Subject: [PATCH 12/23] chore: trigger pr workflow run From 3aa5c03b262468a929080aa2ebfd23392c3ce900 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 15:25:47 +0100 Subject: [PATCH 13/23] chore: trigger pr workflow run From 63af9d3aac7b1efb903034f4d1092ba263ca94c6 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 15:42:17 +0100 Subject: [PATCH 14/23] chore: trigger pr workflow run From ba1eacc7fc6f9c6afb5c1fda15570665a9120db8 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 16:01:27 +0100 Subject: [PATCH 15/23] chore: trigger pr workflow run From 2fcf1a0a31fbc04d883d62e5decff22ac9f29e38 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 1 Dec 2025 16:18:54 +0100 Subject: [PATCH 16/23] chore: trigger pr workflow run From 74c07fa506769d36b1b66cad0a09be05b395c09f Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Tue, 2 Dec 2025 08:45:31 +0100 Subject: [PATCH 17/23] chore: trigger pr workflow run From fcdbfad3386865c4a0c034ead0a8c965530ccb41 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Tue, 2 Dec 2025 09:54:14 +0100 Subject: [PATCH 18/23] chore: cleanup --- .github/workflows/build.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 95d058cee..578b30e8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -115,23 +115,6 @@ jobs: echo "$PAYLOAD" | tee -a ${GITHUB_ENV} | tee -a ${GITHUB_OUTPUT} echo EOF | tee -a ${GITHUB_ENV} | tee -a ${GITHUB_OUTPUT} - # - name: Build payload - # if: steps.cf-gha-baseline.outputs.TRIGGERING_REF == 'pr' - # id: payload - # run: | - # PAYLOAD=$(cat < Date: Tue, 2 Dec 2025 10:24:29 +0100 Subject: [PATCH 19/23] chore: remove playwright tests. they were moved to cf-reeve-application --- playwright/.gitignore | 28 - playwright/README.md | 54 -- .../api/api-helpers/batches-status-codes.ts | 8 - playwright/api/api-helpers/enpoints.ts | 42 - .../api/api-helpers/http-status-codes.ts | 6 - playwright/api/base.api.ts | 88 -- playwright/api/dtos/batchDto.ts | 98 -- playwright/api/dtos/batchsDto.ts | 34 - playwright/api/dtos/chartOfAccountsDto.ts | 25 - playwright/api/dtos/eventCodesDto.ts | 32 - playwright/api/dtos/transactionItemCsvDto.ts | 22 - playwright/api/dtos/transactionTypesDto.ts | 4 - playwright/api/reeve-api/reeve.api.ts | 169 ---- playwright/api/reeve-api/reeve.service.ts | 90 -- .../helpers/transaction-pending-status.ts | 5 - .../helpers/transactionCSVProperties.ts | 24 - playwright/helpers/transactionsBuilder.ts | 228 ----- playwright/package-lock.json | 888 ------------------ playwright/package.json | 22 - playwright/playwright.config.ts | 35 - .../tests/e2e/Import-transactions-CSV.feature | 30 - playwright/tests/e2e/login.feature | 11 - .../steps/importTransactionsCSV.steps.ts | 76 -- playwright/tests/steps/login.steps.ts | 34 - playwright/utils/csvFileGenerator.ts | 58 -- playwright/utils/dateGenerator.ts | 13 - playwright/utils/logger.ts | 16 - playwright/utils/transactionCSVHeaders.txt | 1 - playwright/validators/transactionValidator.ts | 68 -- 29 files changed, 2209 deletions(-) delete mode 100644 playwright/.gitignore delete mode 100644 playwright/README.md delete mode 100644 playwright/api/api-helpers/batches-status-codes.ts delete mode 100644 playwright/api/api-helpers/enpoints.ts delete mode 100644 playwright/api/api-helpers/http-status-codes.ts delete mode 100644 playwright/api/base.api.ts delete mode 100644 playwright/api/dtos/batchDto.ts delete mode 100644 playwright/api/dtos/batchsDto.ts delete mode 100644 playwright/api/dtos/chartOfAccountsDto.ts delete mode 100644 playwright/api/dtos/eventCodesDto.ts delete mode 100644 playwright/api/dtos/transactionItemCsvDto.ts delete mode 100644 playwright/api/dtos/transactionTypesDto.ts delete mode 100644 playwright/api/reeve-api/reeve.api.ts delete mode 100644 playwright/api/reeve-api/reeve.service.ts delete mode 100644 playwright/helpers/transaction-pending-status.ts delete mode 100644 playwright/helpers/transactionCSVProperties.ts delete mode 100644 playwright/helpers/transactionsBuilder.ts delete mode 100644 playwright/package-lock.json delete mode 100644 playwright/package.json delete mode 100644 playwright/playwright.config.ts delete mode 100644 playwright/tests/e2e/Import-transactions-CSV.feature delete mode 100644 playwright/tests/e2e/login.feature delete mode 100644 playwright/tests/steps/importTransactionsCSV.steps.ts delete mode 100644 playwright/tests/steps/login.steps.ts delete mode 100644 playwright/utils/csvFileGenerator.ts delete mode 100644 playwright/utils/dateGenerator.ts delete mode 100644 playwright/utils/logger.ts delete mode 100644 playwright/utils/transactionCSVHeaders.txt delete mode 100644 playwright/validators/transactionValidator.ts diff --git a/playwright/.gitignore b/playwright/.gitignore deleted file mode 100644 index ae6d623eb..000000000 --- a/playwright/.gitignore +++ /dev/null @@ -1,28 +0,0 @@ -/node_modules -/.pnp -.pnp.js - -# testing -/coverage -.auth/ -.logs/ -.reports/ -/resources/ -allure-results -**/.features-gen/**/*.spec.js - -# production -/build - -# misc -.DS_Store -../.env - -# Playwright -node_modules/ -/test-results/ -/playwright-report/ -/blob-report/ -/playwright/.cache/ -/playwright/resources - diff --git a/playwright/README.md b/playwright/README.md deleted file mode 100644 index bc0a6318f..000000000 --- a/playwright/README.md +++ /dev/null @@ -1,54 +0,0 @@ -# ๐Ÿงช Reeve API Automation Framework - -This project uses [Playwright](https://playwright.dev/) with BDD-style tests using [playwright-bdd](https://github.com/folke/playwright-bdd). - -## ๐Ÿ“ฆ Installation - -To install all dependencies, including Playwright and playwright-bdd: - -- Install Playwright and Playwright-BDD -``` -npm i -D @playwright/test playwright-bdd -``` -``` -npx playwright install -``` -- Install only Playwright-BDD -``` -npm i -D playwright-bdd -``` -## Env file to run in local - -1. Create a `.env` file at the root of the playwright folder. -2. Use next structure as example. -3. Ask a team member for the required environment variables & corresponding values for the API, KEYCLOAK and extra application necessary variables. - -``` -API_URL= -LOGIN_URL= -MANAGER_USER= -MANAGER_PASSWORD= -API_LOG_REQUEST= -ORGANIZATION_ID= -``` - -## โš™๏ธ Test run in local: - -### Run all tests in feature files - npm test -### You can run a specific .feature file by passing it as an argument: - npm test "your-feature-file.feature" - -## ๐Ÿ“‚ Test Structure - -The test suite follows a BDD-style structure using [Gherkin](https://cucumber.io/docs/gherkin/) -feature files and corresponding step definitions. - -### ๐Ÿ”ธ Folder layout -- `tests/` - - `e2e/`: Contains `.feature` files written in Gherkin syntax. Each file describes user scenarios using Given, When, and Then steps. - - `test-scenarios.feature` - - `other-tests.feature` - - `steps/`: Contains the step definitions โ€” the TypeScript code that implements the behavior described in the feature files. - - `test-scenarios.steps.ts` - diff --git a/playwright/api/api-helpers/batches-status-codes.ts b/playwright/api/api-helpers/batches-status-codes.ts deleted file mode 100644 index 1a5ef86e9..000000000 --- a/playwright/api/api-helpers/batches-status-codes.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum BatchesStatusCodes { - APPROVE = "APPROVE", - PENDING = "PENDING", - INVALID = "INVALID", - PUBLISH = "PUBLISH", - PUBLISHED = "PUBLISHED" - -} \ No newline at end of file diff --git a/playwright/api/api-helpers/enpoints.ts b/playwright/api/api-helpers/enpoints.ts deleted file mode 100644 index cc4048b96..000000000 --- a/playwright/api/api-helpers/enpoints.ts +++ /dev/null @@ -1,42 +0,0 @@ -import * as process from "process"; - -export class Reeve { - static readonly BASE_URL = process.env.API_URL as string; - static readonly LOGIN_URL = process.env.LOGIN_URL as string; - - static SignIn = class { - public static get Base() { - return `${Reeve.LOGIN_URL}/realms/reeve-master/protocol/openid-connect/token`; - } - }; - static Transactions = class { - public static get Types() { - return `${Reeve.BASE_URL}/transaction-types` - } - public static get Extraction() { - return `${Reeve.BASE_URL}/extraction` - } - public static get Validation() { - return `${Reeve.Transactions.Extraction}/validation` - } - } - static Organization = class { - public static get Base() { - return `${Reeve.BASE_URL}/organisations` - } - public static get EventCodes() { - return `${Reeve.Organization.Base}/:orgId/event-codes` - } - public static get ChartOfAccounts() { - return `${Reeve.Organization.Base}/:orgId/chart-of-accounts` - } - } - static Batches = class { - public static get Batches() { - return `${Reeve.BASE_URL}/batches` - } - public static get BatchById() { - return `${Reeve.Batches.Batches}/:batchId` - } - } -} \ No newline at end of file diff --git a/playwright/api/api-helpers/http-status-codes.ts b/playwright/api/api-helpers/http-status-codes.ts deleted file mode 100644 index 92cab7ee3..000000000 --- a/playwright/api/api-helpers/http-status-codes.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum HttpStatusCodes { - success = 200, - RequestAccepted = 202, - BadRequest = 400, - Unauthorized= 401 -} \ No newline at end of file diff --git a/playwright/api/base.api.ts b/playwright/api/base.api.ts deleted file mode 100644 index f03a328a3..000000000 --- a/playwright/api/base.api.ts +++ /dev/null @@ -1,88 +0,0 @@ -import {APIRequestContext, APIResponse} from "@playwright/test"; - -import {log} from "../utils/logger"; - -const returnLoggedResponse = async ( - response: APIResponse, - endpoint: string, - payload?: object, - isBodyNotSecret = true -) => { - log.info(`Request URL: ${endpoint}`); - if (typeof payload !== "undefined" && isBodyNotSecret) { - log.info(`Request params/body:\n${JSON.stringify(payload, null, 2)}`); - } - log.info(`Response status: ${response.status()}`); - if (response.headers()["content-type"]?.includes("application/json") && isBodyNotSecret) { - log.info(`Response body:\n${JSON.stringify(await response.json(), null, 2)}`); - } - return response; -}; - -export const postForm = async ( - request: APIRequestContext, - endpoint: string, - form?: { [key: string]: string }, - headers?: { [key: string]: string }, - isBodyNotSecret = true -) => - returnLoggedResponse( - await request.post(endpoint, { - form, - headers - }), - endpoint, - form, - isBodyNotSecret - ); -export const getData = async ( - request: APIRequestContext, - endpoint: string, - params?: { [key: string]: string | number | boolean }, - headers?: { [key: string]: string }, - isBodyNotSecret = true -) => - returnLoggedResponse( - await request.get(endpoint, { - headers, - params - }), - endpoint, - params, - isBodyNotSecret - ); -export const postFormData = async ( - request: APIRequestContext, - endpoint: string, - multipart?: {[key: string]: any}, - headers?: {[key: string]: string}, - isBodyNotSecret = true -) => { - return returnLoggedResponse( - await request.post(endpoint, { - headers, - multipart - }), - endpoint, - multipart, - isBodyNotSecret - ); -} -export const postData = async ( - request: APIRequestContext, - endpoint: string, - data?: {[key: string]: any}, - headers?: {[key: string]: string}, - params?: { [key: string]: string | number | boolean }, - isBodyNotSecret = true -) => { - return returnLoggedResponse( - await request.post(endpoint,{ - headers, - data - }), - endpoint, - data, - isBodyNotSecret - ) -} \ No newline at end of file diff --git a/playwright/api/dtos/batchDto.ts b/playwright/api/dtos/batchDto.ts deleted file mode 100644 index 6c381124f..000000000 --- a/playwright/api/dtos/batchDto.ts +++ /dev/null @@ -1,98 +0,0 @@ - -export interface BatchStatistics { - batchId: string; - invalid: number; - pending: number; - approve: number; - publish: number; - published: number; - total: number; -} - -export interface FilteringParameters { - transactionTypes: string[]; - from: string; - to: string; - accountingPeriodFrom: string; - accountingPeriodTo: string; - transactionNumbers: string[]; -} - -export interface TransactionItem { - id: string; - accountDebitCode: string; - accountDebitName: string; - accountDebitRefCode: string; - accountCreditCode: string; - accountCreditName: string; - accountCreditRefCode: string; - amountFcy: number; - amountLcy: number; - fxRate: number; - costCenterCustomerCode: string; - costCenterName: string; - parentCostCenterCustomerCode: string; - parentCostCenterName: string; - projectCustomerCode: string; - projectName: string; - parentProjectCustomerCode: string; - parentProjectName: string; - accountEventCode: string; - accountEventName: string; - documentNum: string; - documentCurrencyCustomerCode: string; - vatCustomerCode: string; - vatRate: number; - counterpartyCustomerCode: string; - counterpartyType: string; - counterpartyName: string; -} - -export interface Violation { - severity: string; - source: string; - transactionItemId: string; - code: string; - bag: { - customerCode: string; - transactionNumber: string; - }; -} - -export interface Transaction { - id: string; - internalTransactionNumber: string; - entryDate: string; - transactionType: string; - dataSource: string; - status: string; - statistic: string; - validationStatus: string; - ledgerDispatchStatus: string; - transactionApproved: boolean; - ledgerDispatchApproved: boolean; - amountTotalLcy: number; - itemRejection: boolean; - reconciliationSource: string; - reconciliationSink: string; - reconciliationFinalStatus: string; - reconciliationRejectionCode: string[]; - itemCount: number; - items: TransactionItem[]; - violations: Violation[]; -} - -export interface BatchResponse { - id: string; - createdAt: string; - updatedAt: string; - createdBy: string; - updateBy: string; - organisationId: string; - status: string; - batchStatistics: BatchStatistics; - filteringParameters: FilteringParameters; - transactions: Transaction[]; - details: Record; - totalTransactionsCount: number; -} \ No newline at end of file diff --git a/playwright/api/dtos/batchsDto.ts b/playwright/api/dtos/batchsDto.ts deleted file mode 100644 index 2e1fd0487..000000000 --- a/playwright/api/dtos/batchsDto.ts +++ /dev/null @@ -1,34 +0,0 @@ -interface BatchStatistics { - batchId: string; - invalid: number; - pending: number; - approve: number; - publish: number; - published: number; - total: number; -} - -interface FilteringParameters { - transactionTypes: string[]; - from: string; - to: string; - accountingPeriodFrom: string; - accountingPeriodTo: string; - transactionNumbers: string[] | number[]; -} -export interface Batch { - id: string; - createdAt: string; - updatedAt: string; - createdBy: string; - updateBy: string; - organisationId: string; - status: string; - batchStatistics: BatchStatistics; - filteringParameters: FilteringParameters; -} - -export interface BatchData { - total: number; - batchs: Batch[]; -} \ No newline at end of file diff --git a/playwright/api/dtos/chartOfAccountsDto.ts b/playwright/api/dtos/chartOfAccountsDto.ts deleted file mode 100644 index 122315b05..000000000 --- a/playwright/api/dtos/chartOfAccountsDto.ts +++ /dev/null @@ -1,25 +0,0 @@ -export interface ChartOfAccountsDto { - customerCode: string; - eventRefCode: string; - name: string; - subType: number; - type: number; - active: boolean; - error: any; -} - -export interface AccountRefCodePair { - accountCode: string; - referenceCode: string; - accountName: string; -} - -export interface AccountCodeAndNamePair { - accountCode: string; - accountName: string; -} - -export interface DebitAndCreditAccounts { - debitAccounts: AccountCodeAndNamePair[]; - creditAccounts: AccountCodeAndNamePair[]; -} \ No newline at end of file diff --git a/playwright/api/dtos/eventCodesDto.ts b/playwright/api/dtos/eventCodesDto.ts deleted file mode 100644 index 551536475..000000000 --- a/playwright/api/dtos/eventCodesDto.ts +++ /dev/null @@ -1,32 +0,0 @@ -export interface EventCodesDto { - organisationId: string; - debitReferenceCode: string; - creditReferenceCode: string; - customerCode: string; - description: string; - active: boolean; - error?: ErrorDetails; -} - -export interface ErrorDetails { - instance: string; - type: string; - parameters?: { - additionalProp1?: any; - additionalProp2?: any; - additionalProp3?: any; - }; - title: string; - status: StatusInfo; - detail: string; -} - -export interface StatusInfo { - reasonPhrase: string; - statusCode: number; -} - -export interface ReferenceCodePair { - debitReferenceCode: string; - creditReferenceCode: string; -} \ No newline at end of file diff --git a/playwright/api/dtos/transactionItemCsvDto.ts b/playwright/api/dtos/transactionItemCsvDto.ts deleted file mode 100644 index 594bb012c..000000000 --- a/playwright/api/dtos/transactionItemCsvDto.ts +++ /dev/null @@ -1,22 +0,0 @@ -export interface TransactionItemCsvDto { - TxNumber?: string; - TxDate?: string; - TxType?: string; - FxRate?: string; - AmountLcyDebit?: string; - AmountLcyCredit?: string; - AmountFcyDebit?: string; - AmountFcyCredit?: string; - DebitCode?: string; - DebitName?: string; - CreditCode?: string; - CreditName?: string; - ProjectCode?: string; - DocumentName?: string; - TxCurrency?: string; - VatRate?: string; - VatCode?: string; - TxCostCenter?: string; - CounterParty?: string; - CounterpartyName?: string; -} \ No newline at end of file diff --git a/playwright/api/dtos/transactionTypesDto.ts b/playwright/api/dtos/transactionTypesDto.ts deleted file mode 100644 index 404115a4a..000000000 --- a/playwright/api/dtos/transactionTypesDto.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface TransactionTypeDto { - id: string; - title: string; -} \ No newline at end of file diff --git a/playwright/api/reeve-api/reeve.api.ts b/playwright/api/reeve-api/reeve.api.ts deleted file mode 100644 index 781fa68a2..000000000 --- a/playwright/api/reeve-api/reeve.api.ts +++ /dev/null @@ -1,169 +0,0 @@ -import {APIRequestContext} from "@playwright/test"; - -import * as BaseApi from "../base.api"; -import * as Endpoints from "../api-helpers/enpoints"; -import {getDateInThePast} from "../../utils/dateGenerator"; -import * as fs from "fs"; -import * as path from "node:path"; - -export function reeveApi(request: APIRequestContext) { - let logApiResponse = process.env.API_LOG_REQUEST == "true" - const loginReeve = async (userName: string, password: string) => { - return BaseApi.postForm( - request, - Endpoints.Reeve.SignIn.Base, - { - grant_type: "password", - client_id: "webclient", - username: userName, - password: password - }, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/x-www-form-urlencoded" - }, - logApiResponse - ); - }; - - const transactionTypes = async (authToken: string) => { - return BaseApi.getData( - request, - Endpoints.Reeve.Transactions.Types, - {}, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/x-www-form-urlencoded", - Authorization: authToken - }, - logApiResponse - ) - } - - const eventCodes = async (organizationId: string, authToken: string) => { - return BaseApi.getData( - request, - Endpoints.Reeve.Organization.EventCodes.replace(":orgId", organizationId), - {}, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/x-www-form-urlencoded", - Authorization: authToken - }, - logApiResponse - ) - } - - const chartOfAccounts = async (organizationId: string, authToken: string) => { - return BaseApi.getData( - request, - Endpoints.Reeve.Organization.ChartOfAccounts.replace(":orgId", organizationId), - {}, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/x-www-form-urlencoded", - Authorization: authToken - }, - logApiResponse - ) - } - - const validateTransactionCsvFile = async (organizationId: string, authToken: string, transactionFilePath: string) => { - return BaseApi.postFormData( - request, - Endpoints.Reeve.Transactions.Validation, - { - organisationId: organizationId, - extractorType: 'CSV', - dateFrom: getDateInThePast(6, false), - dateTo: getDateInThePast(2, false), - file: { - name: path.basename(transactionFilePath), - mimeType: 'text/csv', - buffer: fs.readFileSync(transactionFilePath), - } - }, - { - "Accept-Encoding": "gzip, deflate, br", - 'Authorization': authToken - }, - logApiResponse - ); - } - - const importTransactionCsvFile = async (organizationId: string, authToken: string, transactionFilePath: string) => { - return BaseApi.postFormData( - request, - Endpoints.Reeve.Transactions.Extraction, - { - organisationId: organizationId, - extractorType: 'CSV', - dateFrom: getDateInThePast(6, false), - dateTo: getDateInThePast(2, false), - file: { - name: path.basename(transactionFilePath), - mimeType: 'text/csv', - buffer: fs.readFileSync(transactionFilePath), - } - }, - { - "Accept-Encoding": "gzip, deflate, br", - 'Authorization': authToken - }, - logApiResponse - ); - } - const batchesByStatus = async (organizationId: string, authToken: string, status: string) => { - return BaseApi.postData( - request, - Endpoints.Reeve.Batches.Batches, - { - organisationId: organizationId, - batchStatistics: [status] - }, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/json", - Authorization: authToken - }, - { - page: 0, - size: 100 - }, - logApiResponse - ) - } - const batchById = async (authToken: string, batchId: string) => { - return BaseApi.postData( - request, - Endpoints.Reeve.Batches.BatchById.replace(":batchId",batchId), - {}, - { - Accept: "*/*", - "Accept-Encoding": "gzip, deflate, br", - "Content-Type": "application/json", - Authorization: authToken - }, - { - page: 0, - size: 100 - }, - logApiResponse - ) - } - return { - loginReeve, - transactionTypes, - eventCodes, - chartOfAccounts, - validateTransactionCsvFile, - importTransactionCsvFile, - batchesByStatus, - batchById - }; -} \ No newline at end of file diff --git a/playwright/api/reeve-api/reeve.service.ts b/playwright/api/reeve-api/reeve.service.ts deleted file mode 100644 index 53abe89f6..000000000 --- a/playwright/api/reeve-api/reeve.service.ts +++ /dev/null @@ -1,90 +0,0 @@ -import {APIRequestContext, APIResponse, expect} from "@playwright/test"; -import {reeveApi} from "./reeve.api"; -import {Batch, BatchData} from "../dtos/batchsDto"; -import {BatchesStatusCodes} from "../api-helpers/batches-status-codes"; -import {BatchResponse} from "../dtos/batchDto"; -import {log} from "../../utils/logger"; - -let managerUser = process.env.MANAGER_USER as string; -let managerPassword = process.env.MANAGER_PASSWORD as string; -let organizationId = process.env.ORGANIZATION_ID as string; -export async function reeveService(request: APIRequestContext) { - const loginToReeve = async (userName: string, password: string) => { - return await reeveApi(request).loginReeve(userName, password); - }; - - const loginManager = async () => { - return await reeveApi(request).loginReeve(managerUser, managerPassword); - } - - const getTransactionTypes = async (authToken: string) => { - return await reeveApi(request).transactionTypes(authToken); - } - - const getEventCodes = async (authToken: string) => { - return await reeveApi(request).eventCodes(organizationId, authToken); - } - - const getChartOfAccounts = async (authToken: string) => { - return await reeveApi(request).chartOfAccounts(organizationId, authToken); - } - - const validateTransactionCsvFile = async (authToken: string, transactionFile: string) => { - return await reeveApi(request).validateTransactionCsvFile(organizationId, authToken, transactionFile); - } - - const importTransactionCsvFile = async (authToken: string, transactionFile: string) => { - return await reeveApi(request).importTransactionCsvFile(organizationId,authToken, transactionFile) - } - - const getBatchesByStatus = async (authToken: string, status: string) => { - return await reeveApi(request).batchesByStatus(organizationId, authToken, status); - } - - const getNewBatch = async (authToken: string, status: string, txNumber: string) => { - let batchesResponse: APIResponse; - let batchesAfterImport: BatchData; - let batchId: BatchResponse; - await expect.poll(async () => { - batchesResponse = await (await reeveService(request)).getBatchesByStatus(authToken, - status); - batchesAfterImport = await batchesResponse.json() - let batchesIdAfterImport = batchesAfterImport.batchs.map(batch => batch.id); - batchId = await findBatchWithTxNumber(batchesIdAfterImport,txNumber,authToken); - return batchId - },{ - message: "The new Batch was not created: ", - intervals: [1_000, 2_000, 10_000], - timeout: 280_000 - }).not.toBeNull(); - return batchId - } - - const getBatchById = async (authToken: string, batchId: string) => { - return await reeveApi(request).batchById(authToken, batchId) - } - - const findBatchWithTxNumber = async (batchesIdAfterImport: string[], txNumber: string, authToken: string) => { - for (const batchId of batchesIdAfterImport) { - const batchDetailsResponse: BatchResponse = await (await getBatchById(authToken, batchId)).json(); - if (batchDetailsResponse.transactions[0].internalTransactionNumber == txNumber){ - return batchDetailsResponse - } - } - return null; - } - - return { - loginToReeve, - loginManager, - getTransactionTypes, - getEventCodes, - getChartOfAccounts, - validateTransactionCsvFile, - importTransactionCsvFile, - getBatchesByStatus, - getNewBatch, - getBatchById - }; - -} \ No newline at end of file diff --git a/playwright/helpers/transaction-pending-status.ts b/playwright/helpers/transaction-pending-status.ts deleted file mode 100644 index 94e148beb..000000000 --- a/playwright/helpers/transaction-pending-status.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum TransactionPendingStatus { - VAT_DATA_NOT_FOUND = "VAT_DATA_NOT_FOUND", - COST_CENTER_DATA_NOT_FOUND = "COST_CENTER_DATA_NOT_FOUND", - CHART_OF_ACCOUNT_NOT_FOUND = "CHART_OF_ACCOUNT_NOT_FOUND" -} \ No newline at end of file diff --git a/playwright/helpers/transactionCSVProperties.ts b/playwright/helpers/transactionCSVProperties.ts deleted file mode 100644 index 5220e3b5a..000000000 --- a/playwright/helpers/transactionCSVProperties.ts +++ /dev/null @@ -1,24 +0,0 @@ - - -export enum TxCSVHeader { - TxNumber = "Transaction Number", - TxDate = "Transaction Date", - TxType = "Transaction Type", - FxRate = "Fx Rate", - AmountLcyDebit = "AmountLCY Debit", - AmountLcyCredit = "AmountLCY Credit", - AmountFcyDebit = "AmountFCY Debit", - AmountFcyCredit = "AmountFCY Credit", - DebitCode = "Debit Code", - DebitName = "Debit Name", - CreditCode = "Credit Code", - CreditName = "Credit Name", - ProjectCode = "Project Code", - DocumentName = "Document Name", - TxCurrency = "Currency", - VatRate = "VAT Rate", - VatCode = "VAT Code", - TxCostCenter = "CostCenterCode", - CounterParty = "Counterparty Code", - CounterpartyName = "Counterparty Name" -} \ No newline at end of file diff --git a/playwright/helpers/transactionsBuilder.ts b/playwright/helpers/transactionsBuilder.ts deleted file mode 100644 index 0468e4505..000000000 --- a/playwright/helpers/transactionsBuilder.ts +++ /dev/null @@ -1,228 +0,0 @@ -import {saveCSV} from "../utils/csvFileGenerator"; -import * as fs from "fs"; -import {log} from "../utils/logger"; -import {APIRequestContext, expect} from "@playwright/test"; -import {reeveService} from "../api/reeve-api/reeve.service"; -import {HttpStatusCodes} from "../api/api-helpers/http-status-codes"; -import {TransactionTypeDto} from "../api/dtos/transactionTypesDto"; -import {getDateInThePast} from "../utils/dateGenerator"; -import {TransactionItemCsvDto} from "../api/dtos/transactionItemCsvDto"; -import {EventCodesDto, ReferenceCodePair} from "../api/dtos/eventCodesDto"; -import { - AccountCodeAndNamePair, - AccountRefCodePair, - ChartOfAccountsDto, - DebitAndCreditAccounts -} from "../api/dtos/chartOfAccountsDto"; -import {TransactionPendingStatus} from "./transaction-pending-status"; - -export async function transactionsBuilder(request: APIRequestContext, authToken: string) { - const createCSVTransactionReadyToApprove = async (transactionDataToImport: TransactionItemCsvDto[]) => { - const columns = await getTransactionCSVHeaders(); - const rows = await createValidTransactionData(transactionDataToImport) - const fileName = "Approve-" + Math.random().toString(36).substring(2, 2 + 8) + ".csv"; - return await saveCSV(columns, rows, fileName); - } - const createCSVTransactionPending = async (transactionDataToImport: TransactionItemCsvDto[], pendingReason: string) => { - const columns = await getTransactionCSVHeaders(); - const rows = await createPendingTransactionData(transactionDataToImport, pendingReason); - const fileName = "Pending-" + Math.random().toString(36).substring(2, 2 + 8) + ".csv"; - return await saveCSV(columns, rows, fileName) - } - const getTransactionCSVHeaders = async () => { - try { - const headers = await fs.promises.readFile('../playwright/utils/transactionCSVHeaders.txt', 'utf-8') - return headers - .split(',') - .map(header => header.trim()) - } catch (error) { - log.error("Error trying to read file: ", error); - } - } - - /** - * Create a transaction with just two transactions items, - * txNumber Random short hash - * documentName Random short hash - * txType organization transaction type requested through API - * debitTxItem accounts are requested through API in base of organization event codes - * creditTxItem accounts are requested through API in base of organization event codes - */ - const createValidTransactionData = async (transactionDataToImport: TransactionItemCsvDto[]) => { - const transactionCommonData = await getTransactionCommonData() - const amountForTxItem = (Math.floor(Math.random() * 100000) + 1).toString(); - const eventCodes = await getEventCodes(); - const debitAndCreditAccounts = await getDebitAndCreditAccounts(eventCodes); - const debitTxItem = await createTransactionItem(transactionCommonData, amountForTxItem, - true, debitAndCreditAccounts); - const creditTxItem = await createTransactionItem(transactionCommonData, amountForTxItem, - false, debitAndCreditAccounts); - transactionDataToImport.push(debitTxItem); - transactionDataToImport.push(creditTxItem); - const rows: string[][] = []; - rows.push(Object.values(debitTxItem)); - rows.push(Object.values(creditTxItem)) - return rows - } - const createPendingTransactionData = async (transactionDataToImport: TransactionItemCsvDto[], pendingReason: string) => { - const transactionCommonData = await getTransactionCommonData() - const amountForTxItem = (Math.floor(Math.random() * 100000) + 1).toString(); - const eventCodes = await getEventCodes(); - const debitAndCreditAccounts = await getDebitAndCreditAccounts(eventCodes); - const debitTxItem = await createTransactionItem(transactionCommonData, amountForTxItem, - true, debitAndCreditAccounts) - await setPendingReason(debitTxItem, pendingReason); - const creditTxItem = await createTransactionItem(transactionCommonData, amountForTxItem, - false, debitAndCreditAccounts); - transactionDataToImport.push(debitTxItem); - transactionDataToImport.push(creditTxItem); - const rows: string[][] = []; - rows.push(Object.values(debitTxItem)); - rows.push(Object.values(creditTxItem)) - return rows - } - const getTransactionCommonData = async () => { - const txNumber = "TEST-" + Math.random().toString(36).substring(2, 2 + 8); - const txDate = getDateInThePast(2, true); - const txType = await getTransactionType(); - const documentName = "TEST-" + Math.random().toString(36).substring(2, 2 + 8); - const transactionItemCommonData: TransactionItemCsvDto = { - TxNumber: txNumber, - TxDate: txDate, - TxType: txType, - DocumentName: documentName - } - return transactionItemCommonData - } - const setPendingReason = async (transactionItem: TransactionItemCsvDto, pendingReason: string) => { - if(pendingReason == TransactionPendingStatus.COST_CENTER_DATA_NOT_FOUND){ - transactionItem.TxCostCenter = Math.random().toString(36).substring(2, 2 + 8); - } - if(pendingReason == TransactionPendingStatus.VAT_DATA_NOT_FOUND){ - transactionItem.VatCode = Math.random().toString(36).substring(2, 2 + 8); - } - if(pendingReason == TransactionPendingStatus.CHART_OF_ACCOUNT_NOT_FOUND){ - transactionItem.DebitCode = Math.random().toString(36).substring(2, 2 + 8); - } - } - - const getTransactionType = async () => { - const transactionTypeResponse = await (await reeveService(request)) - .getTransactionTypes(authToken); - expect(transactionTypeResponse.status()).toEqual(HttpStatusCodes.success); - const transactionTypes: TransactionTypeDto[] = await (transactionTypeResponse.json()); - const randomTxType = Math.floor(Math.random() * (transactionTypes.length - 1)); - return (transactionTypes[randomTxType].id) - } - - const getEventCodes = async () => { - const eventCodesResponse = await (await reeveService(request)).getEventCodes(authToken); - expect(eventCodesResponse.status()).toEqual(HttpStatusCodes.success); - const eventCodes: EventCodesDto[] = await (eventCodesResponse.json()); - const referenceCodes: ReferenceCodePair[] = eventCodes.map(eventCode => ({ - debitReferenceCode: eventCode.debitReferenceCode, - creditReferenceCode: eventCode.creditReferenceCode - })); - return referenceCodes; - } - - /** - * Get two lists of accounts that has an event code - * for the combination of debit and credit accounts - * @param eventCodes array of organization's event codes - * - */ - const getDebitAndCreditAccounts = async (eventCodes: ReferenceCodePair[]) => { - const chartOfAccounts: AccountRefCodePair[] = await getChartOfAccounts(); - let index = 0; - let accountsMatch: boolean = false; - let debitAccounts: AccountCodeAndNamePair[] | null; - let creditAccounts: AccountCodeAndNamePair[] | null; - while (accountsMatch == false) { - if (eventCodes[index].debitReferenceCode != eventCodes[index].creditReferenceCode) { - debitAccounts = chartOfAccounts.filter(chartOfAccount => - chartOfAccount.referenceCode === eventCodes[index].debitReferenceCode) - .map(chartOfAccount => ({ - accountCode: chartOfAccount.accountCode, - accountName: chartOfAccount.accountName - })); - if (debitAccounts.length >= 1) { - creditAccounts = chartOfAccounts.filter(chartOfAccount => - chartOfAccount.referenceCode === eventCodes[index].creditReferenceCode - && chartOfAccount.accountCode !== debitAccounts[0].accountCode) - .map(chartOfAccount => ({ - accountCode: chartOfAccount.accountCode, - accountName: chartOfAccount.accountName - })); - } - if (creditAccounts != null) { - accountsMatch = true; - } - } - index++; - } - const debitAndCreditAccounts: DebitAndCreditAccounts = { - debitAccounts: debitAccounts, - creditAccounts: creditAccounts - } - return debitAndCreditAccounts - } - - const getChartOfAccounts = async () => { - const chartOfAccountsResponse = await (await reeveService(request)).getChartOfAccounts(authToken); - expect(chartOfAccountsResponse.status()).toEqual(HttpStatusCodes.success); - const chartOfAccounts: AccountRefCodePair[] = (await (chartOfAccountsResponse).json()) - .map(chartOfAccount => ({ - accountCode: chartOfAccount.customerCode, - referenceCode: chartOfAccount.eventRefCode, - accountName: chartOfAccount.name - })) - return chartOfAccounts - } - - const createTransactionItem = async (transactionItemCommonData: TransactionItemCsvDto, amount: string, - isDebit: boolean, debitAndCreditAccounts: DebitAndCreditAccounts) => { - let randomIndexDebit = Math.floor(Math.random() * debitAndCreditAccounts.debitAccounts.length) - let randomIndexCredit = Math.floor(Math.random() * debitAndCreditAccounts.creditAccounts.length) - const transactionItem: TransactionItemCsvDto = { - TxNumber: transactionItemCommonData.TxNumber, - TxDate: transactionItemCommonData.TxDate, - TxType: transactionItemCommonData.TxType, - FxRate: "1", - AmountLcyDebit: "", - AmountLcyCredit: "", - AmountFcyDebit: "", - AmountFcyCredit: "", - DebitCode: "", - DebitName: "", - CreditCode: "", - CreditName: "", - ProjectCode: "", - DocumentName: transactionItemCommonData.DocumentName, - TxCurrency: "CHF", - VatRate: "", - VatCode: "", - TxCostCenter: "", - CounterParty: "", - CounterpartyName: "", - } - if (isDebit) { - transactionItem.AmountLcyDebit = amount; - transactionItem.AmountFcyDebit = amount; - } else { - transactionItem.AmountLcyCredit = amount; - transactionItem.AmountFcyCredit = amount; - } - transactionItem.DebitCode = debitAndCreditAccounts.debitAccounts[randomIndexDebit].accountCode; - transactionItem.DebitName = debitAndCreditAccounts.debitAccounts[randomIndexDebit].accountName; - transactionItem.CreditCode = debitAndCreditAccounts.creditAccounts[randomIndexCredit].accountCode; - transactionItem.CreditName = debitAndCreditAccounts.creditAccounts[randomIndexCredit].accountName; - return transactionItem - } - - return { - createReadyToApproveTransaction: createCSVTransactionReadyToApprove, - createCSVTransactionPending - } - -} \ No newline at end of file diff --git a/playwright/package-lock.json b/playwright/package-lock.json deleted file mode 100644 index 7395bb9bf..000000000 --- a/playwright/package-lock.json +++ /dev/null @@ -1,888 +0,0 @@ -{ - "name": "playwright", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "playwright", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@faker-js/faker": "^9.9.0", - "dotenv": "^17.2.1", - "log4js": "^6.9.1" - }, - "devDependencies": { - "@playwright/test": "^1.56.1", - "@types/node": "^24.3.0", - "playwright-bdd": "^8.4.1" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@cucumber/cucumber-expressions": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-18.0.1.tgz", - "integrity": "sha512-NSid6bI+7UlgMywl5octojY5NXnxR9uq+JisjOrO52VbFsQM6gTWuQFE8syI10KnIBEdPzuEUSVEeZ0VFzRnZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regexp-match-indices": "1.0.2" - } - }, - "node_modules/@cucumber/gherkin": { - "version": "32.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-32.2.0.tgz", - "integrity": "sha512-X8xuVhSIqlUjxSRifRJ7t0TycVWyX58fygJH3wDNmHINLg9sYEkvQT0SO2G5YlRZnYc11TIFr4YPenscvdlBIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/messages": ">=19.1.4 <28" - } - }, - "node_modules/@cucumber/gherkin-utils": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-9.2.0.tgz", - "integrity": "sha512-3nmRbG1bUAZP3fAaUBNmqWO0z0OSkykZZotfLjyhc8KWwDSOrOmMJlBTd474lpA8EWh4JFLAX3iXgynBqBvKzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/gherkin": "^31.0.0", - "@cucumber/messages": "^27.0.0", - "@teppeis/multimaps": "3.0.0", - "commander": "13.1.0", - "source-map-support": "^0.5.21" - }, - "bin": { - "gherkin-utils": "bin/gherkin-utils" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin": { - "version": "31.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-31.0.0.tgz", - "integrity": "sha512-wlZfdPif7JpBWJdqvHk1Mkr21L5vl4EfxVUOS4JinWGf3FLRV6IKUekBv5bb5VX79fkDcfDvESzcQ8WQc07Wgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/messages": ">=19.1.4 <=26" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin/node_modules/@cucumber/messages": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-26.0.1.tgz", - "integrity": "sha512-DIxSg+ZGariumO+Lq6bn4kOUIUET83A4umrnWmidjGFl8XxkBieUZtsmNbLYgH/gnsmP07EfxxdTr0hOchV1Sg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/uuid": "10.0.0", - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.2", - "uuid": "10.0.0" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@cucumber/html-formatter": { - "version": "21.14.0", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-21.14.0.tgz", - "integrity": "sha512-vQqbmQZc0QiN4c+cMCffCItpODJlOlYtPG7pH6We096dBOa7u0ttDMjT6KrMAnQlcln54rHL46r408IFpuznAw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@cucumber/messages": ">=18" - } - }, - "node_modules/@cucumber/junit-xml-formatter": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@cucumber/junit-xml-formatter/-/junit-xml-formatter-0.7.1.tgz", - "integrity": "sha512-AzhX+xFE/3zfoYeqkT7DNq68wAQfBcx4Dk9qS/ocXM2v5tBv6eFQ+w8zaSfsktCjYzu4oYRH/jh4USD1CYHfaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/query": "^13.0.2", - "@teppeis/multimaps": "^3.0.0", - "luxon": "^3.5.0", - "xmlbuilder": "^15.1.1" - }, - "peerDependencies": { - "@cucumber/messages": "*" - } - }, - "node_modules/@cucumber/messages": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-27.2.0.tgz", - "integrity": "sha512-f2o/HqKHgsqzFLdq6fAhfG1FNOQPdBdyMGpKwhb7hZqg0yZtx9BVqkTyuoNk83Fcvk3wjMVfouFXXHNEk4nddA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/uuid": "10.0.0", - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.2", - "uuid": "11.0.5" - } - }, - "node_modules/@cucumber/query": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-13.6.0.tgz", - "integrity": "sha512-tiDneuD5MoWsJ9VKPBmQok31mSX9Ybl+U4wqDoXeZgsXHDURqzM3rnpWVV3bC34y9W6vuFxrlwF/m7HdOxwqRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@teppeis/multimaps": "3.0.0", - "lodash.sortby": "^4.7.0" - }, - "peerDependencies": { - "@cucumber/messages": "*" - } - }, - "node_modules/@cucumber/tag-expressions": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-6.2.0.tgz", - "integrity": "sha512-KIF0eLcafHbWOuSDWFw0lMmgJOLdDRWjEL1kfXEWrqHmx2119HxVAr35WuEd9z542d3Yyg+XNqSr+81rIKqEdg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@faker-js/faker": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.9.0.tgz", - "integrity": "sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/fakerjs" - } - ], - "license": "MIT", - "engines": { - "node": ">=18.0.0", - "npm": ">=9.0.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@playwright/test": { - "version": "1.56.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz", - "integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.56.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@teppeis/multimaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz", - "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@types/node": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", - "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.10.0" - } - }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/class-transformer": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", - "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/commander": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", - "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dotenv": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", - "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "license": "ISC" - }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", - "dev": true, - "license": "MIT" - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "license": "Apache-2.0", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/luxon": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.1.tgz", - "integrity": "sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/playwright": { - "version": "1.56.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", - "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.56.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-bdd": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/playwright-bdd/-/playwright-bdd-8.4.1.tgz", - "integrity": "sha512-2KM6yHKjpfCKVv0j8lhJkSLbhgfX2yTZLPM+Q9WnnBk/1oa3bmXaHoyokX5Sby2NU/culwC6pErdQAmVfxFnAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cucumber/cucumber-expressions": "18.0.1", - "@cucumber/gherkin": "^32.1.2", - "@cucumber/gherkin-utils": "^9.2.0", - "@cucumber/html-formatter": "^21.11.0", - "@cucumber/junit-xml-formatter": "^0.7.1", - "@cucumber/messages": "^27.2.0", - "@cucumber/tag-expressions": "^6.2.0", - "cli-table3": "0.6.5", - "commander": "^13.1.0", - "fast-glob": "^3.3.3", - "mime-types": "^3.0.1", - "xmlbuilder": "15.1.1" - }, - "bin": { - "bddgen": "dist/cli/index.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/vitalets" - }, - "peerDependencies": { - "@playwright/test": ">=1.44" - } - }, - "node_modules/playwright-core": { - "version": "1.56.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", - "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/regexp-match-indices": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", - "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "regexp-tree": "^0.1.11" - } - }, - "node_modules/regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", - "dev": true, - "license": "MIT", - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "license": "MIT" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "license": "MIT", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/uuid": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.5.tgz", - "integrity": "sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/esm/bin/uuid" - } - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - } - } -} diff --git a/playwright/package.json b/playwright/package.json deleted file mode 100644 index d2c695f36..000000000 --- a/playwright/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "playwright", - "version": "1.0.0", - "main": "index.js", - "scripts": { - "test": "npx bddgen && npx playwright test --project='api-tests'" - }, - "keywords": [], - "author": "", - "license": "ISC", - "description": "", - "devDependencies": { - "@playwright/test": "^1.56.1", - "@types/node": "^24.3.0", - "playwright-bdd": "^8.4.1" - }, - "dependencies": { - "@faker-js/faker": "^9.9.0", - "dotenv": "^17.2.1", - "log4js": "^6.9.1" - } -} diff --git a/playwright/playwright.config.ts b/playwright/playwright.config.ts deleted file mode 100644 index c93d5d1ad..000000000 --- a/playwright/playwright.config.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { defineConfig, devices } from '@playwright/test'; -import {defineBddConfig} from "playwright-bdd"; - -import "dotenv/config"; - - -const testDir = defineBddConfig({ - features: './tests/e2e', - steps: './tests/steps' -}); -export default defineConfig({ - /* Indicates where the test steps definition are */ - testDir, - - - timeout: 120_000, - - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', - /* Configure projects for major browsers */ - projects: [ - { - name: "api-tests", - testDir, - } - ], -}); diff --git a/playwright/tests/e2e/Import-transactions-CSV.feature b/playwright/tests/e2e/Import-transactions-CSV.feature deleted file mode 100644 index e720cf595..000000000 --- a/playwright/tests/e2e/Import-transactions-CSV.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Users can import transactions into Reeve with a CSV file, system validates the structure file - and import the transactions to be processed by the validation rules - - Scenario: Import ready to approve transaction - Given Manager user wants to import a transaction with a CSV file - And the manager creates the CSV file with all the required fields - And system get the validation request - When system get import request - Then the transaction data should be imported with ready to approve status - - Scenario: Import transaction in pending status by unknown cost center - Given Manager user wants to import a transaction with a CSV file - And the cost center data in the CSV file doesn't exist in the system - And system get the validation request - When system get import request - Then the system should create the transaction with pending status by "COST_CENTER_DATA_NOT_FOUND" - - Scenario: Import transaction in pending status by unknown VAT code - Given Manager user wants to import a transaction with a CSV file - And the vat code data in the CSV file doesn't exist in the system - And system get the validation request - When system get import request - Then the system should create the transaction with pending status by "VAT_DATA_NOT_FOUND" - - Scenario: Import transaction in pending status by unknown Chart of account code - Given Manager user wants to import a transaction with a CSV file - And the chart of account code data in the CSV file doesn't exist in the system - And system get the validation request - When system get import request - Then the system should create the transaction with pending status by "CHART_OF_ACCOUNT_NOT_FOUND" \ No newline at end of file diff --git a/playwright/tests/e2e/login.feature b/playwright/tests/e2e/login.feature deleted file mode 100644 index 878553630..000000000 --- a/playwright/tests/e2e/login.feature +++ /dev/null @@ -1,11 +0,0 @@ -Feature: Login and authentication process tests - - Scenario: Manager user can login with its credentials - Given Manager user wants to login into Reeve - When system get the login request - Then system should return success login response with authorization token - - Scenario: Manager user can not login with invalid credentials - Given Manager user wants to login into Reeve with wrong credentials - When system get the login request - Then system should reject access \ No newline at end of file diff --git a/playwright/tests/steps/importTransactionsCSV.steps.ts b/playwright/tests/steps/importTransactionsCSV.steps.ts deleted file mode 100644 index cd2795758..000000000 --- a/playwright/tests/steps/importTransactionsCSV.steps.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {APIResponse, expect} from '@playwright/test'; -import {createBdd} from 'playwright-bdd' -import {reeveService} from "../../api/reeve-api/reeve.service"; -import {HttpStatusCodes} from "../../api/api-helpers/http-status-codes"; -import {transactionsBuilder} from "../../helpers/transactionsBuilder"; -import {BatchesStatusCodes} from "../../api/api-helpers/batches-status-codes"; -import {TransactionItemCsvDto} from "../../api/dtos/transactionItemCsvDto"; -import {BatchResponse} from "../../api/dtos/batchDto"; -import {transactionValidator} from "../../validators/transactionValidator"; -import {TransactionPendingStatus} from "../../helpers/transaction-pending-status"; -import {deleteFile} from "../../utils/csvFileGenerator"; - -const {Given, When, Then} = createBdd(); -let authToken: string -let transactionCSVFile: string; -let transactionDataToImport: TransactionItemCsvDto[] = []; -Given(/^Manager user wants to import a transaction with a CSV file$/, async ({request}) => { - const loginResponse = await (await reeveService(request)).loginManager() - expect(loginResponse.status()).toEqual(HttpStatusCodes.success) - authToken = (await loginResponse.json()).token_type + " " + (await loginResponse.json()).access_token; -}); -Given(/^the manager creates the CSV file with all the required fields$/, async ({request}) => { - transactionCSVFile = await (await transactionsBuilder(request, authToken)) - .createReadyToApproveTransaction(transactionDataToImport); -}); -Given(/^system get the validation request$/, async ({request}) => { - const validateResponse = await (await reeveService(request)).validateTransactionCsvFile(authToken, - transactionCSVFile); - expect(validateResponse.status()).toEqual(HttpStatusCodes.success); -}); -When(/^system get import request$/, async ({request}) => { - const importTxCsvResponse = await (await reeveService(request)).importTransactionCsvFile(authToken, - transactionCSVFile); - expect(importTxCsvResponse.status()).toEqual(HttpStatusCodes.RequestAccepted); - await deleteFile(transactionCSVFile) -}); -Then(/^the transaction data should be imported with ready to approve status$/, async ({request}) => { - const newBatchAfterImport = await (await reeveService(request)).getNewBatch(authToken, - BatchesStatusCodes.APPROVE, transactionDataToImport[0].TxNumber); - const batchDetailsResponse = await (await reeveService(request)).getBatchById(authToken, - newBatchAfterImport.id); - expect(batchDetailsResponse.status()).toEqual(HttpStatusCodes.success); - let importedBatchDetails: BatchResponse = await batchDetailsResponse.json() - await (await transactionValidator()).validateImportedTxWithStatus(transactionDataToImport, importedBatchDetails, - BatchesStatusCodes.APPROVE); -}); -Given(/^the cost center data in the CSV file doesn't exist in the system$/, async ({request}) => { - transactionCSVFile = await (await transactionsBuilder(request, authToken)) - .createCSVTransactionPending(transactionDataToImport, TransactionPendingStatus.COST_CENTER_DATA_NOT_FOUND); -}); -Then(/^the system should create the transaction with pending status by "([^"]*)"$/, async ({request}, reason) => { - const newBatchAfterImport = await (await reeveService(request)).getNewBatch(authToken, - BatchesStatusCodes.PENDING, transactionDataToImport[0].TxNumber); - await (await transactionValidator()).validateImportedTxWithStatus(transactionDataToImport, newBatchAfterImport, - BatchesStatusCodes.PENDING); - if(reason == TransactionPendingStatus.COST_CENTER_DATA_NOT_FOUND){ - await (await transactionValidator()).validatePendingCondition(newBatchAfterImport, - TransactionPendingStatus.COST_CENTER_DATA_NOT_FOUND) - } - if(reason == TransactionPendingStatus.VAT_DATA_NOT_FOUND){ - await (await transactionValidator()).validatePendingCondition(newBatchAfterImport, - TransactionPendingStatus.VAT_DATA_NOT_FOUND) - } - if(reason == TransactionPendingStatus.CHART_OF_ACCOUNT_NOT_FOUND){ - await (await transactionValidator()).validatePendingCondition(newBatchAfterImport, - TransactionPendingStatus.CHART_OF_ACCOUNT_NOT_FOUND) - } -}); -Given(/^the vat code data in the CSV file doesn't exist in the system$/, async ({request}) => { - transactionCSVFile = await (await transactionsBuilder(request, authToken)) - .createCSVTransactionPending(transactionDataToImport, TransactionPendingStatus.VAT_DATA_NOT_FOUND); -}); -Given(/^the chart of account code data in the CSV file doesn't exist in the system$/, async ({request}) => { - transactionCSVFile = await (await transactionsBuilder(request, authToken)) - .createCSVTransactionPending(transactionDataToImport, TransactionPendingStatus.CHART_OF_ACCOUNT_NOT_FOUND); -}); \ No newline at end of file diff --git a/playwright/tests/steps/login.steps.ts b/playwright/tests/steps/login.steps.ts deleted file mode 100644 index 286d46986..000000000 --- a/playwright/tests/steps/login.steps.ts +++ /dev/null @@ -1,34 +0,0 @@ -import {APIResponse, expect} from '@playwright/test'; -import {faker} from "@faker-js/faker"; -import {createBdd} from 'playwright-bdd'; -import {reeveApi} from "../../api/reeve-api/reeve.api"; -import {reeveService} from "../../api/reeve-api/reeve.service"; -import {log} from "../../utils/logger"; -import {HttpStatusCodes} from "../../api/api-helpers/http-status-codes"; - -const {Given, When, Then} = createBdd(); - -let userName: string; -let password: string; -let loginResponse: APIResponse; -Given(/^Manager user wants to login into Reeve$/, async ({page}) => { - userName = process.env.MANAGER_USER as string; - password = process.env.MANAGER_PASSWORD as string; -}); -When(/^system get the login request$/, async ({request}) => { - loginResponse = await (await reeveService(request)).loginToReeve(userName, password) -}); -Then(/^system should return success login response with authorization token$/, async ({page}) => { - expect(loginResponse.status()).toEqual(HttpStatusCodes.success) - const authToken = (await loginResponse.json()).access_token - const tokenType = (await loginResponse.json()).token_type - expect(authToken).toBeDefined() - expect(tokenType).toContain("Bearer") -}); -Given(/^Manager user wants to login into Reeve with wrong credentials$/, async () => { - userName = faker.internet.userAgent() - password = faker.string.sample() -}); -Then(/^system should reject access$/, async () => { - expect(loginResponse.status()).toEqual(HttpStatusCodes.Unauthorized) -}); \ No newline at end of file diff --git a/playwright/utils/csvFileGenerator.ts b/playwright/utils/csvFileGenerator.ts deleted file mode 100644 index da0af26a3..000000000 --- a/playwright/utils/csvFileGenerator.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import {unlink} from "node:fs/promises"; - -/** - * Create CSV data - * @param columns Array of column names - * @param rows Array of rows (each row is an array of values in order) - * @param filename Output CSV filename - */ -export async function saveCSV( - columns: string[], - rows: any[][], - filename: string -): Promise { - const folderPath = "./resources"; - - if (columns.length === 0) { - throw new Error("You must provide at least one column."); - } - - // Escape values that contain quotes, commas or newlines - const escape = (value: any): string => { - if (value == null) return ""; - const valueAsString = String(value); - if (/[",\n]/.test(valueAsString)) { - return `"${valueAsString.replace(/"/g, '""')}"`; - } - return valueAsString; - }; - - // Build CSV content - const header = columns.join(","); - const data = rows.map(r => - columns.map((_, i) => escape(r[i] ?? "")).join(",") - ); - const csvContent = [header, ...data].join("\n"); - - // Ensure folder exists - fs.mkdirSync(folderPath, { recursive: true }); - - // Save file - const fullPath = path.join(folderPath, filename); - fs.writeFileSync(fullPath, csvContent, "utf-8"); - - //return file - return fullPath; -} - -export async function deleteFile(fullPath: string): Promise { - try { - await unlink(fullPath); - console.log(`โœ“ File successfully deleted`); - } catch (error) { - console.error(`โœ— Error trying to delete:`, error); - throw error; - } -} diff --git a/playwright/utils/dateGenerator.ts b/playwright/utils/dateGenerator.ts deleted file mode 100644 index 1ffd1a5f5..000000000 --- a/playwright/utils/dateGenerator.ts +++ /dev/null @@ -1,13 +0,0 @@ - -export function getDateInThePast(monthsInPast: number, usFormat: boolean){ - const date = new Date(); - date.setMonth(date.getMonth() - monthsInPast); - - const day = String(date.getDate()).padStart(2, '0'); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const year = date.getFullYear(); - if(usFormat==true){ - return `${day}/${month}/${year}`; - } - return `${year}-${month}-${day}` -} \ No newline at end of file diff --git a/playwright/utils/logger.ts b/playwright/utils/logger.ts deleted file mode 100644 index 756408ecf..000000000 --- a/playwright/utils/logger.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { configure, getLogger } from "log4js"; - -configure({ - appenders: { - app: { type: "file", filename: "./.logs/test-run.log" }, - out: { type: "stdout" } - }, - categories: { - default: { - appenders: ["app", "out"], - level: "debug" - } - } -}); - -export const log = getLogger(); \ No newline at end of file diff --git a/playwright/utils/transactionCSVHeaders.txt b/playwright/utils/transactionCSVHeaders.txt deleted file mode 100644 index b0c604e44..000000000 --- a/playwright/utils/transactionCSVHeaders.txt +++ /dev/null @@ -1 +0,0 @@ -Transaction Number,Transaction Date,Transaction Type,Fx Rate,AmountLCY Debit,AmountLCY Credit,AmountFCY Debit,AmountFCY Credit,Debit Code,Debit Name,Credit Code,Credit Name,Project Code,Document Name,Currency,VAT Rate,VAT Code,Cost Center Code,Counterparty Code,Counterparty Name \ No newline at end of file diff --git a/playwright/validators/transactionValidator.ts b/playwright/validators/transactionValidator.ts deleted file mode 100644 index 6c00e0d24..000000000 --- a/playwright/validators/transactionValidator.ts +++ /dev/null @@ -1,68 +0,0 @@ -import {TransactionItemCsvDto} from "../api/dtos/transactionItemCsvDto"; -import {BatchResponse, TransactionItem} from "../api/dtos/batchDto"; -import {expect} from "@playwright/test"; -import {log} from "../utils/logger"; -import {BatchesStatusCodes} from "../api/api-helpers/batches-status-codes"; - -export async function transactionValidator() { - const validateImportedTxWithStatus = async (transactionCsvData: TransactionItemCsvDto[], - importedBatchDetails: BatchResponse, transactionStatus: string) => { - const debitCsvItem: TransactionItemCsvDto = await extractCsvTxItem(transactionCsvData, true); - const creditCsvItem: TransactionItemCsvDto = await extractCsvTxItem(transactionCsvData, false); - const txItems = importedBatchDetails.transactions[0].items - const txDebitItem = txItems.find(tx => - tx.accountDebitCode == debitCsvItem.DebitCode) - const txCreditItem = txItems.find(tx => - tx.accountCreditCode == creditCsvItem.CreditCode) - if(transactionStatus == BatchesStatusCodes.APPROVE){ - expect(importedBatchDetails.batchStatistics.approve, "Imported batch should have transaction in ready to approve status ") - .toEqual(importedBatchDetails.totalTransactionsCount) - } - if(transactionStatus == BatchesStatusCodes.PENDING){ - expect(importedBatchDetails.batchStatistics.pending, "Imported batch should have transaction in pending status ") - .toEqual(importedBatchDetails.totalTransactionsCount) - } - expect(importedBatchDetails.transactions[0].items.length, "The sent transaction items are not the same imported in the system ") - .toEqual(transactionCsvData.length) - expect(importedBatchDetails.transactions[0].internalTransactionNumber, "The transaction number is not the same that was sent") - .toEqual(transactionCsvData[0].TxNumber) - expect(importedBatchDetails.transactions[0].transactionType,"The transaction type is not the same that was sent") - .toEqual(transactionCsvData[0].TxType) - await validateTxItem(txDebitItem, debitCsvItem, true); - await validateTxItem(txCreditItem, creditCsvItem, false); - } - const validateTxItem = async (txItem: TransactionItem, txCsvItem: TransactionItemCsvDto, isDebit: boolean) => { - expect(txItem.accountDebitCode, "The sent debit code is not the same imported in the system") - .toEqual(txCsvItem.DebitCode); - expect(txItem.accountCreditCode, "The sent credit code is not the same imported in the system") - .toEqual(txCsvItem.CreditCode); - expect(txItem.documentNum, "The sent document number is not the same imported in the system") - .toEqual(txCsvItem.DocumentName) - if(isDebit == true){ - expect(txItem.amountLcy, "The LCY amount in debit item is not the same imported in the system") - .toEqual(parseFloat(txCsvItem.AmountLcyDebit)) - }else { - expect(Math.abs(txItem.amountLcy), "The LCY amount in credit item is not the same imported in the system") - .toEqual(parseFloat(txCsvItem.AmountLcyCredit)) - } - } - const validatePendingCondition = async (importedBatchDetails: BatchResponse, expectedReason: string) => { - expect(importedBatchDetails.transactions[0].violations[0].code, "The expected pending reason is wrong") - .toEqual(expectedReason) - } - const extractCsvTxItem = async (transactionCsvData: TransactionItemCsvDto[], isDebit: boolean) => { - return transactionCsvData.find(tx => { - let amount: number - if(isDebit == true){ - amount = parseFloat(tx.AmountLcyDebit); - return !isNaN(amount) && amount > 0; - } - amount = parseFloat(tx.AmountLcyCredit); - return !isNaN(amount) && amount > 0 - }) - } - return { - validateImportedTxWithStatus, - validatePendingCondition - } -} \ No newline at end of file From 8f57d911a93cff9ca7b2bc0a2a9a4d0be880a5eb Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Tue, 2 Dec 2025 14:04:43 +0100 Subject: [PATCH 20/23] chore: trigger pr workflow run From 41c756fdc59681bde93cda50d15101c85e84cdf7 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Tue, 2 Dec 2025 14:17:24 +0100 Subject: [PATCH 21/23] chore: fix REF input --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 578b30e8b..7f748779d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -122,7 +122,7 @@ jobs: EVENT_TYPE: cf-reeve-platform-pr GITHUB_TOKEN: ${{ secrets.CF_REEVE_APPLICATION_REPO_PAT }} GITHUB_REPO: cardano-foundation/cf-reeve-application - REF: ${{ steps.cf-gha-baseline.outputs.TRIGGERING_REF }} + TRIGGERING_REF: ${{ steps.cf-gha-baseline.outputs.TRIGGERING_REF }} TRIGGERING_EVENT: ${{ github.event_name }} TRIGGERING_BRANCH: ${{ steps.cf-gha-baseline.outputs.BRANCH_NAME }} TRIGGERING_TAG: ${{ steps.cf-gha-baseline.outputs.TAG_NAME }} From 741e4bb9aeea5359fd20c4518d02cc3777fa1c37 Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Mon, 8 Dec 2025 08:38:48 +0100 Subject: [PATCH 22/23] chore: trigger pr workflow run From a1cef65fc8807c9c41cd99f870d4463db2f708ed Mon Sep 17 00:00:00 2001 From: Florian Schumann Date: Tue, 9 Dec 2025 11:29:41 +0100 Subject: [PATCH 23/23] chore: trigger pr workflow run