From 32765adf95807d19549ea93da394f42fdc8dd67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 5 Nov 2024 10:17:37 +0100 Subject: [PATCH 01/61] docs: update backend readme to use proper ghc and cabal versions --- govtool/backend/README.md | 44 ++++++++++++++++++++++++++------------ govtool/frontend/README.md | 2 +- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/govtool/backend/README.md b/govtool/backend/README.md index 8d539b304..566293184 100644 --- a/govtool/backend/README.md +++ b/govtool/backend/README.md @@ -5,9 +5,10 @@ This is a backend application of GovTool project. ## Prerequisites In order to run `backend` your host machine will need access to the `cardano-db-sync` postgres database. To have this database running locally you'll need: -* `cardano-node` -* `cardano-db-sync` -* PostgreSQL database + +- `cardano-node` +- `cardano-db-sync` +- PostgreSQL database You will need your `cardano-node` and `cardano-db-sync` to be compatible with Sancho testnet. Until these features will be merged to the master branch the new Sancho compatible versions are available as releases on [github](https://github.com/IntersectMBO/cardano-db-sync/releases). You will also need a correct `cardano-node` version. The release notes for `cardano-db-sync` usualy specify that. @@ -25,35 +26,50 @@ You can utilize the [docker-compose.node+dbsync.yml](../../scripts/govtool/docke Due to problems with openapi3 package it's hard to build this project with plain `ghc` and `cabal-install`. Until the prolem is solved we reccomend using `nix` - this problem is fixed when you build your project from inside of the nix shell. -1. Get [Nix](https://nixos.org/download). +1. Get [Nix](https://nixos.org/download). + +2. Get [direnv](https://direnv.net/). + +3. Set GHC version to 9.10.1: + + ```sh + ghcup install ghc 9.10.1 + + ghcup set ghc 9.10.1 + ``` + +4. Install cabal -2. Get [direnv](https://direnv.net/). + ```sh + ghcup install cabal + ghcup set cabal + ``` -3. Enter `govtool/backend` directory: +5. Enter `govtool/backend` directory: ```sh cd govtool/backend ``` -4. Allow direnv to setup your environment: +6. Allow direnv to setup your environment: ```sh direnv allow ``` -5. Update cabal & build project +7. Update cabal & build project ```sh cabal update cabal build all ``` -6. Create a config file. You can use `example-config.json` as a template. +8. Create a config file. You can use `example-config.json` as a template. -7. Run project - ```sh +9. Run project + `sh cabal run vva-be -- --config start-app - ``` -> [!WARNING] -> In the context of our ongoing project enhancements, it is assumed that the executable previously known as 'vva-be' should be now officially renamed to 'govtool-backend'. This change is necessary for aligning with the updated branding and functional scope of the application and it has to be implemented in the near future as a chore and refactoring ticket. Make sure that the documentation matches the actual name of the executable. + ` + > [!WARNING] + > In the context of our ongoing project enhancements, it is assumed that the executable previously known as 'vva-be' should be now officially renamed to 'govtool-backend'. This change is necessary for aligning with the updated branding and functional scope of the application and it has to be implemented in the near future as a chore and refactoring ticket. Make sure that the documentation matches the actual name of the executable. ## Development diff --git a/govtool/frontend/README.md b/govtool/frontend/README.md index 6e79d6f2d..43eca3082 100644 --- a/govtool/frontend/README.md +++ b/govtool/frontend/README.md @@ -114,7 +114,7 @@ yarn dev #### Using Nix and Direnv -1. Get [Nix](https://nixos.org/download). +1. Get [Nix](https://nixos.org/download) (And/Or) Get [GHCUP](https://www.haskell.org/ghcup/). 2. Get [direnv](https://direnv.net/). From df3cd74a27562b7b6dac88fcaad3d1cb42b6c309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 8 Jan 2025 08:59:14 +0100 Subject: [PATCH 02/61] chore: remove @jdyczka from CODEOWNERS --- CODEOWNERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 91d3c7698..92b6221ef 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,10 +4,10 @@ * @Ryun1 @MSzalowski # Frontend assets templates -govtool/frontend/* @MSzalowski @jdyczka -*.tsx @MSzalowski @jdyczka -*.ts @MSzalowski @jdyczka -*.css @MSzalowski @jdyczka +govtool/frontend/* @MSzalowski +*.tsx @MSzalowski +*.ts @MSzalowski +*.css @MSzalowski # Backend govtool/backend/* @MSzalowski @jankun4 From e9d429d360f467d9433c7a5cf9c5ae69fc4dfc62 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 14 Feb 2025 14:49:08 +0545 Subject: [PATCH 03/61] fix: test 8D by removing unecessary intercept and testid updates --- .../playwright/lib/_mock/infoProposedGAs.json | 1110 -------------- .../lib/_mock/treasuryProposedGAs.json | 1362 ----------------- .../proposalDiscussion.spec.ts | 31 +- 3 files changed, 6 insertions(+), 2497 deletions(-) delete mode 100644 tests/govtool-frontend/playwright/lib/_mock/infoProposedGAs.json delete mode 100644 tests/govtool-frontend/playwright/lib/_mock/treasuryProposedGAs.json diff --git a/tests/govtool-frontend/playwright/lib/_mock/infoProposedGAs.json b/tests/govtool-frontend/playwright/lib/_mock/infoProposedGAs.json deleted file mode 100644 index f5fe2f80f..000000000 --- a/tests/govtool-frontend/playwright/lib/_mock/infoProposedGAs.json +++ /dev/null @@ -1,1110 +0,0 @@ -{ - "data": [ - { - "id": 339, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "137", - "createdAt": "2024-07-01T10:19:22.617Z", - "updatedAt": "2024-07-01T10:19:22.617Z", - "user_govtool_username": "No name", - "content": { - "id": 338, - "attributes": { - "proposal_id": "339", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": "First Draft", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-07-01T10:19:22.617Z", - "updatedAt": "2024-07-01T10:19:22.617Z", - "is_draft": false, - "user_id": "137", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 329, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "20", - "createdAt": "2024-07-01T06:18:34.760Z", - "updatedAt": "2024-07-01T06:18:34.760Z", - "user_govtool_username": "Anonymous", - "content": { - "id": 328, - "attributes": { - "proposal_id": "329", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": "dQuad draft", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-07-01T06:18:34.760Z", - "updatedAt": "2024-07-01T06:18:34.760Z", - "is_draft": false, - "user_id": "20", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 323, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "20", - "createdAt": "2024-07-01T06:05:41.221Z", - "updatedAt": "2024-07-01T06:05:41.221Z", - "user_govtool_username": "Anonymous", - "content": { - "id": 322, - "attributes": { - "proposal_id": "323", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-07-01T06:05:41.235Z", - "updatedAt": "2024-07-01T06:05:41.235Z", - "is_draft": false, - "user_id": "20", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 319, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "127", - "createdAt": "2024-06-27T10:10:47.816Z", - "updatedAt": "2024-06-27T10:10:47.816Z", - "user_govtool_username": "Val", - "content": { - "id": 318, - "attributes": { - "proposal_id": "319", - "prop_rev_active": true, - "prop_abstract": "Summary", - "prop_motivation": "Motivation", - "prop_rationale": "Rationale", - "gov_action_type_id": "1", - "prop_name": "New proposal", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-27T10:10:47.838Z", - "updatedAt": "2024-06-27T10:10:47.838Z", - "is_draft": false, - "user_id": "127", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 62, - "prop_link": "https://docs.intersectmbo.org/intersect-community-grants/closed-grants/proposal-discussion-forum", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 305, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 1, - "user_id": "127", - "createdAt": "2024-06-24T13:09:54.524Z", - "updatedAt": "2024-06-27T09:55:44.508Z", - "user_govtool_username": "Val", - "content": { - "id": 317, - "attributes": { - "proposal_id": "305", - "prop_rev_active": true, - "prop_abstract": "na", - "prop_motivation": "na", - "prop_rationale": "na", - "gov_action_type_id": "1", - "prop_name": "New Title", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-27T09:55:14.956Z", - "updatedAt": "2024-06-27T09:55:14.956Z", - "is_draft": false, - "user_id": "127", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 318, - "attributes": { - "prop_likes": 1, - "prop_dislikes": 0, - "prop_comments_number": 4, - "user_id": "137", - "createdAt": "2024-06-27T02:33:45.412Z", - "updatedAt": "2024-06-27T10:04:12.908Z", - "user_govtool_username": "No name", - "content": { - "id": 316, - "attributes": { - "proposal_id": "318", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-27T02:33:45.426Z", - "updatedAt": "2024-06-27T02:33:45.426Z", - "is_draft": false, - "user_id": "137", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 317, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 1, - "user_id": "124", - "createdAt": "2024-06-27T01:39:54.268Z", - "updatedAt": "2024-06-27T02:07:24.503Z", - "user_govtool_username": "Test", - "content": { - "id": 315, - "attributes": { - "proposal_id": "317", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-27T01:39:54.283Z", - "updatedAt": "2024-06-27T01:39:54.283Z", - "is_draft": false, - "user_id": "124", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 313, - "attributes": { - "prop_likes": 1, - "prop_dislikes": 0, - "prop_comments_number": 2, - "user_id": "19", - "createdAt": "2024-06-26T04:00:01.483Z", - "updatedAt": "2024-06-26T13:02:23.814Z", - "user_govtool_username": "pm00", - "content": { - "id": 309, - "attributes": { - "proposal_id": "313", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-26T04:00:01.497Z", - "updatedAt": "2024-06-26T04:00:01.497Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 312, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-26T02:55:19.093Z", - "updatedAt": "2024-06-26T02:55:19.093Z", - "user_govtool_username": "pm00", - "content": { - "id": 308, - "attributes": { - "proposal_id": "312", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-26T02:55:19.113Z", - "updatedAt": "2024-06-26T02:55:19.113Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 56, - "prop_link": "https://test.com", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 311, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-26T01:35:26.674Z", - "updatedAt": "2024-06-26T01:35:26.674Z", - "user_govtool_username": "pm00", - "content": { - "id": 307, - "attributes": { - "proposal_id": "311", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-26T01:35:26.697Z", - "updatedAt": "2024-06-26T01:35:26.697Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 55, - "prop_link": "https://test.com", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 310, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-26T01:28:56.923Z", - "updatedAt": "2024-06-26T01:28:56.923Z", - "user_govtool_username": "pm00", - "content": { - "id": 306, - "attributes": { - "proposal_id": "310", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-26T01:28:56.947Z", - "updatedAt": "2024-06-26T01:28:56.947Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 54, - "prop_link": "https://test.com", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 309, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-25T22:55:52.976Z", - "updatedAt": "2024-06-25T22:55:52.976Z", - "user_govtool_username": "pm00", - "content": { - "id": 305, - "attributes": { - "proposal_id": "309", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-25T22:55:53.005Z", - "updatedAt": "2024-06-25T22:55:53.005Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 53, - "prop_link": "dfsd", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 303, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "135", - "createdAt": "2024-06-24T10:20:19.799Z", - "updatedAt": "2024-06-24T10:20:19.799Z", - "user_govtool_username": "TestingUser", - "content": { - "id": 299, - "attributes": { - "proposal_id": "303", - "prop_rev_active": true, - "prop_abstract": "Test", - "prop_motivation": "Test", - "prop_rationale": "Test", - "gov_action_type_id": "1", - "prop_name": "Test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-24T10:20:19.810Z", - "updatedAt": "2024-06-24T10:20:19.810Z", - "is_draft": false, - "user_id": "135", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 302, - "attributes": { - "prop_likes": 1, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-20T15:50:40.146Z", - "updatedAt": "2024-06-20T18:29:28.590Z", - "user_govtool_username": "pm00", - "content": { - "id": 298, - "attributes": { - "proposal_id": "302", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-20T16:02:33.770Z", - "updatedAt": "2024-06-20T16:02:33.770Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 49, - "prop_link": "https://test.com/", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 301, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 1, - "prop_comments_number": 13, - "user_id": "6", - "createdAt": "2024-06-20T14:10:41.553Z", - "updatedAt": "2024-06-20T15:39:13.447Z", - "user_govtool_username": "lorenzo.bruno@intersectmbo.org", - "content": { - "id": 296, - "attributes": { - "proposal_id": "301", - "prop_rev_active": true, - "prop_abstract": "ds", - "prop_motivation": "ds", - "prop_rationale": "ds", - "gov_action_type_id": "1", - "prop_name": "ds", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-20T14:10:41.564Z", - "updatedAt": "2024-06-20T14:10:41.564Z", - "is_draft": false, - "user_id": "6", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 299, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 5, - "user_id": "32", - "createdAt": "2024-06-20T10:47:43.456Z", - "updatedAt": "2024-06-20T13:46:49.580Z", - "user_govtool_username": "Michal", - "content": { - "id": 294, - "attributes": { - "proposal_id": "299", - "prop_rev_active": true, - "prop_abstract": "Test Abstract", - "prop_motivation": "Test Motivation", - "prop_rationale": "Test Rationale", - "gov_action_type_id": "1", - "prop_name": "Test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-20T10:47:43.469Z", - "updatedAt": "2024-06-20T10:47:43.469Z", - "is_draft": false, - "user_id": "32", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 297, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "19", - "createdAt": "2024-06-19T15:57:47.949Z", - "updatedAt": "2024-06-19T15:57:47.949Z", - "user_govtool_username": "pm00", - "content": { - "id": 292, - "attributes": { - "proposal_id": "297", - "prop_rev_active": true, - "prop_abstract": "test", - "prop_motivation": "test", - "prop_rationale": "test", - "gov_action_type_id": "1", - "prop_name": "test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-19T15:57:47.968Z", - "updatedAt": "2024-06-19T15:57:47.968Z", - "is_draft": false, - "user_id": "19", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 47, - "prop_link": "test.com", - "prop_link_text": null - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 331, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "124", - "createdAt": "2024-06-19T10:28:05.678Z", - "updatedAt": "2024-06-19T10:28:05.678Z", - "user_govtool_username": "Test", - "content": { - "id": 330, - "attributes": { - "proposal_id": "331", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-19T10:28:05.678Z", - "updatedAt": "2024-06-19T10:28:05.678Z", - "is_draft": false, - "user_id": "124", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 292, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 5, - "user_id": "124", - "createdAt": "2024-06-19T09:41:12.144Z", - "updatedAt": "2024-06-19T15:57:16.935Z", - "user_govtool_username": "Test", - "content": { - "id": 287, - "attributes": { - "proposal_id": "292", - "prop_rev_active": true, - "prop_abstract": "Fake abstract", - "prop_motivation": " Fake Motivation", - "prop_rationale": " Fake Rationale", - "gov_action_type_id": "1", - "prop_name": "fake title", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-19T10:13:32.814Z", - "updatedAt": "2024-06-19T10:13:32.814Z", - "is_draft": false, - "user_id": "124", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [ - { - "id": 45, - "prop_link": "google.com", - "prop_link_text": "Google" - } - ], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 291, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "129", - "createdAt": "2024-06-19T08:00:31.668Z", - "updatedAt": "2024-06-19T08:00:31.668Z", - "user_govtool_username": "Niraj3", - "content": { - "id": 285, - "attributes": { - "proposal_id": "291", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-19T08:00:31.668Z", - "updatedAt": "2024-06-19T08:00:31.668Z", - "is_draft": false, - "user_id": "129", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 286, - "attributes": { - "prop_likes": 1, - "prop_dislikes": 0, - "prop_comments_number": 2, - "user_id": "127", - "createdAt": "2024-06-18T14:50:58.504Z", - "updatedAt": "2024-06-19T12:30:16.464Z", - "user_govtool_username": "Val", - "content": { - "id": 280, - "attributes": { - "proposal_id": "286", - "prop_rev_active": true, - "prop_abstract": "na", - "prop_motivation": "na", - "prop_rationale": "na", - "gov_action_type_id": "1", - "prop_name": "Test 4", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-18T14:50:58.516Z", - "updatedAt": "2024-06-18T14:50:58.516Z", - "is_draft": false, - "user_id": "127", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 333, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "126", - "createdAt": "2024-06-18T08:18:26.508Z", - "updatedAt": "2024-06-18T08:18:26.508Z", - "user_govtool_username": "Kneerose", - "content": { - "id": 332, - "attributes": { - "proposal_id": "333", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " test", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-18T08:18:26.508Z", - "updatedAt": "2024-06-18T08:18:26.508Z", - "is_draft": false, - "user_id": "126", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 288, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 1, - "user_id": "126", - "createdAt": "2024-06-18T08:18:26.508Z", - "updatedAt": "2024-06-19T04:42:25.687Z", - "user_govtool_username": "Kneerose", - "content": { - "id": 282, - "attributes": { - "proposal_id": "288", - "prop_rev_active": true, - "prop_abstract": " ", - "prop_motivation": " ", - "prop_rationale": " ", - "gov_action_type_id": "1", - "prop_name": " ", - "prop_receiving_address": null, - "prop_amount": null, - "createdAt": "2024-06-18T08:18:26.508Z", - "updatedAt": "2024-06-18T08:18:26.508Z", - "is_draft": false, - "user_id": "126", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 280, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 1, - "prop_comments_number": 4, - "user_id": "121", - "createdAt": "2024-06-17T08:30:36.868Z", - "updatedAt": "2024-06-18T09:26:15.103Z", - "user_govtool_username": "Brock.Kilback", - "content": { - "id": 274, - "attributes": { - "proposal_id": "280", - "prop_rev_active": true, - "prop_abstract": "Conicio cubo amet. Vorago totidem quod in patior explicabo delicate.", - "prop_motivation": "Vel tot audio cilicium uredo. Occaecati crepusculum cuppedia deporto valeo illum.", - "prop_rationale": "Vulgo quod denuo admitto. Aspicio tersus uredo depromo caelum apud pectus vitae commemoro.", - "gov_action_type_id": "1", - "prop_name": "Baumbach, Hauck and Bartell", - "prop_receiving_address": "addr_test1qqqqqqqqqqa4kpmh", - "prop_amount": 520, - "createdAt": "2024-06-17T08:30:36.893Z", - "updatedAt": "2024-06-17T08:30:36.893Z", - "is_draft": false, - "user_id": "121", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - }, - { - "id": 277, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "121", - "createdAt": "2024-06-17T08:27:52.316Z", - "updatedAt": "2024-06-17T08:27:52.316Z", - "user_govtool_username": "Brock.Kilback", - "content": { - "id": 271, - "attributes": { - "proposal_id": "277", - "prop_rev_active": true, - "prop_abstract": "Terror commodi terebro arma torrens caterva vivo alias decumbo. Ubi volup aufero adficio audax.", - "prop_motivation": "Terror thermae delibero cinis crux somniculosus. Suscipit conspergo administratio tutamen cursim combibo.", - "prop_rationale": "Conculco ater amor beneficium cunabula qui vespillo tempora textilis allatus. Admiratio cuppedia repudiandae voluptatem anser calculus attonbitus.", - "gov_action_type_id": "1", - "prop_name": "Orn - Crist", - "prop_receiving_address": "addr_test1qqqqqqqqqqa4kpmh", - "prop_amount": 591, - "createdAt": "2024-06-17T08:27:52.329Z", - "updatedAt": "2024-06-17T08:27:52.329Z", - "is_draft": false, - "user_id": "121", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "proposal_links": [], - "gov_action_type": { - "id": 1, - "attributes": { - "gov_action_type_name": "Info", - "createdAt": "2024-05-27T15:06:15.640Z", - "updatedAt": "2024-05-27T15:06:15.640Z" - } - } - } - } - } - } - ], - "meta": { - "pagination": { - "page": 1, - "pageSize": 25, - "pageCount": 8, - "total": 194 - } - } -} diff --git a/tests/govtool-frontend/playwright/lib/_mock/treasuryProposedGAs.json b/tests/govtool-frontend/playwright/lib/_mock/treasuryProposedGAs.json deleted file mode 100644 index 29c84a6c3..000000000 --- a/tests/govtool-frontend/playwright/lib/_mock/treasuryProposedGAs.json +++ /dev/null @@ -1,1362 +0,0 @@ -{ - "data": [ - { - "id": 17204, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3316", - "createdAt": "2025-01-30T11:29:33.731Z", - "updatedAt": "2025-01-30T11:29:33.731Z", - "user_govtool_username": "korbin46_1738235936720", - "content": { - "id": 17183, - "attributes": { - "proposal_id": "17204", - "prop_rev_active": true, - "prop_abstract": "cura amoveo dedico complectus crastinus", - "prop_motivation": "tergeo amor volva aqua arma", - "prop_rationale": "pel ocer desidero blandior cultura", - "gov_action_type_id": "2", - "prop_name": "Statua cimentarius depraedor advenio alveus corrupti.", - "is_draft": false, - "user_id": "3316", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T11:29:33.760Z", - "updatedAt": "2025-01-30T11:29:33.760Z", - "proposal_links": [ - { - "id": 17030, - "prop_link": "https://slight-clarity.org/", - "prop_link_text": "euphoric-barium" - } - ], - "proposal_withdrawals": [ - { - "id": 15358, - "prop_receiving_address": "stake1uqqv758up00900wk9k7xlud8ljtj5zjw4hczht34034kyrgwcsvsk", - "prop_amount": 621 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17183, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3306", - "createdAt": "2025-01-30T09:52:59.102Z", - "updatedAt": "2025-01-30T09:52:59.102Z", - "user_govtool_username": "myah43_1738230167776", - "content": { - "id": 17162, - "attributes": { - "proposal_id": "17183", - "prop_rev_active": true, - "prop_abstract": "copia venia voluptates accusator varius", - "prop_motivation": "currus paulatim canto veritas cognatus", - "prop_rationale": "volutabrum comburo vitium cogito coniuratio", - "gov_action_type_id": "2", - "prop_name": "Verbera cubicularis acer argentum benevolentia laudantium.", - "is_draft": false, - "user_id": "3306", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T09:52:59.130Z", - "updatedAt": "2025-01-30T09:52:59.130Z", - "proposal_links": [ - { - "id": 17009, - "prop_link": "https://playful-size.name/", - "prop_link_text": "bare-spiderling" - } - ], - "proposal_withdrawals": [ - { - "id": 15337, - "prop_receiving_address": "stake1up6c3kuuf9ccy6nq5qr7j2k52m8csg54yhm50d5r5x8lg4q2vvhnc", - "prop_amount": 879 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17181, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-30T09:43:38.887Z", - "updatedAt": "2025-01-30T09:43:38.887Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17160, - "attributes": { - "proposal_id": "17181", - "prop_rev_active": true, - "prop_abstract": "desparatus arma speculum ver admoneo", - "prop_motivation": "adstringo ultio capto cado tertius", - "prop_rationale": "tergum stella depraedor tamen vigilo", - "gov_action_type_id": "2", - "prop_name": "Patruus articulus atqui temporibus curtus cernuus.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T09:43:38.914Z", - "updatedAt": "2025-01-30T09:43:38.914Z", - "proposal_links": [ - { - "id": 17007, - "prop_link": "https://sore-channel.org/", - "prop_link_text": "enormous-summary" - } - ], - "proposal_withdrawals": [ - { - "id": 15335, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 883 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17162, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3294", - "createdAt": "2025-01-30T07:33:43.674Z", - "updatedAt": "2025-01-30T07:33:43.674Z", - "user_govtool_username": "albin_cormier42_1738221335719", - "content": { - "id": 17141, - "attributes": { - "proposal_id": "17162", - "prop_rev_active": true, - "prop_abstract": "sonitus decimus succedo aedificium repellendus", - "prop_motivation": "aetas verto capitulus copiose tabgo", - "prop_rationale": "nostrum desidero confero ambulo supellex", - "gov_action_type_id": "2", - "prop_name": "Crebro animadverto pecto trado alo alienus.", - "is_draft": false, - "user_id": "3294", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T07:33:43.699Z", - "updatedAt": "2025-01-30T07:33:43.699Z", - "proposal_links": [ - { - "id": 16988, - "prop_link": "https://optimistic-bill.biz/", - "prop_link_text": "tedious-regulation" - } - ], - "proposal_withdrawals": [ - { - "id": 15316, - "prop_receiving_address": "stake1uz924cfl9ag6ga4ah0c3mrgrley6pelvxrc30augvmqgwmqenqge9", - "prop_amount": 619 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17160, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-30T07:16:26.480Z", - "updatedAt": "2025-01-30T07:16:26.480Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17139, - "attributes": { - "proposal_id": "17160", - "prop_rev_active": true, - "prop_abstract": "cimentarius summopere voco natus quod", - "prop_motivation": "corporis solum constans amplus tertius", - "prop_rationale": "illum quasi cilicium debitis avaritia", - "gov_action_type_id": "2", - "prop_name": "Depono distinctio adhuc animi tres cum.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T07:16:26.514Z", - "updatedAt": "2025-01-30T07:16:26.514Z", - "proposal_links": [ - { - "id": 16986, - "prop_link": "https://far-off-leaf.org", - "prop_link_text": "unconscious-plunger" - } - ], - "proposal_withdrawals": [ - { - "id": 15314, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 494 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17158, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-30T07:07:07.606Z", - "updatedAt": "2025-01-30T07:07:07.606Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17137, - "attributes": { - "proposal_id": "17158", - "prop_rev_active": true, - "prop_abstract": "curriculum in caste alioqui amoveo", - "prop_motivation": "substantia angustus subvenio argentum tum", - "prop_rationale": "acervus reiciendis fuga tenetur aedificium", - "gov_action_type_id": "2", - "prop_name": "Copia comprehendo cognomen quam conspergo absorbeo.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T07:07:07.632Z", - "updatedAt": "2025-01-30T07:07:07.632Z", - "proposal_links": [ - { - "id": 16984, - "prop_link": "https://powerless-theology.net/", - "prop_link_text": "informal-bratwurst" - } - ], - "proposal_withdrawals": [ - { - "id": 15312, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 128 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17157, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3293", - "createdAt": "2025-01-30T07:05:45.314Z", - "updatedAt": "2025-01-30T07:05:45.314Z", - "user_govtool_username": "barney.kreiger_1738220473415", - "content": { - "id": 17136, - "attributes": { - "proposal_id": "17157", - "prop_rev_active": true, - "prop_abstract": "sulum charisma astrum tabernus coerceo", - "prop_motivation": "capitulus virgo spectaculum defendo voluntarius", - "prop_rationale": "denego tremo callide traho avaritia", - "gov_action_type_id": "2", - "prop_name": "Tendo ago dolores tandem ultra adaugeo.", - "is_draft": false, - "user_id": "3293", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-30T07:05:45.343Z", - "updatedAt": "2025-01-30T07:05:45.343Z", - "proposal_links": [ - { - "id": 16983, - "prop_link": "https://utter-memo.net", - "prop_link_text": "thunderous-cofactor" - } - ], - "proposal_withdrawals": [ - { - "id": 15311, - "prop_receiving_address": "stake1upmqsvunjaczvfyck7zqwptk56z2ty7smfmga5zvcduwz4cc9cq6v", - "prop_amount": 202 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17147, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3277", - "createdAt": "2025-01-29T16:43:47.743Z", - "updatedAt": "2025-01-29T16:43:47.743Z", - "user_govtool_username": "jacey45_1738168202436", - "content": { - "id": 17126, - "attributes": { - "proposal_id": "17147", - "prop_rev_active": true, - "prop_abstract": "averto vulariter absque tametsi thermae", - "prop_motivation": "pax aestivus aro causa cariosus", - "prop_rationale": "appositus beneficium avarus certus carpo", - "gov_action_type_id": "2", - "prop_name": "Amo aranea cibo alo vehemens tamquam.", - "is_draft": false, - "user_id": "3277", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T16:43:47.772Z", - "updatedAt": "2025-01-29T16:43:47.772Z", - "proposal_links": [ - { - "id": 16974, - "prop_link": "https://polished-sideboard.name/", - "prop_link_text": "worthwhile-foodstuffs" - } - ], - "proposal_withdrawals": [ - { - "id": 15301, - "prop_receiving_address": "stake1uqpsyvc8lcxvmt3xzrq09cmgv6hxmezdychhery9ctvt0xsw2zsvg", - "prop_amount": 441 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17133, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3277", - "createdAt": "2025-01-29T16:40:10.956Z", - "updatedAt": "2025-01-29T16:40:10.956Z", - "user_govtool_username": "jacey45_1738168202436", - "content": { - "id": 17112, - "attributes": { - "proposal_id": "17133", - "prop_rev_active": true, - "prop_abstract": "aeger cibus acer amaritudo incidunt", - "prop_motivation": "provident maiores quia deorsum suscipio", - "prop_rationale": "conatus culpa sulum alveus cum", - "gov_action_type_id": "2", - "prop_name": "Termes apostolus sonitus sustineo architecto demo.", - "is_draft": false, - "user_id": "3277", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T16:40:10.982Z", - "updatedAt": "2025-01-29T16:40:10.982Z", - "proposal_links": [ - { - "id": 16960, - "prop_link": "https://functional-chick.net/", - "prop_link_text": "tasty-symbol" - } - ], - "proposal_withdrawals": [ - { - "id": 15287, - "prop_receiving_address": "stake1uqpsyvc8lcxvmt3xzrq09cmgv6hxmezdychhery9ctvt0xsw2zsvg", - "prop_amount": 529 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17131, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T16:30:52.083Z", - "updatedAt": "2025-01-29T16:30:52.083Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17110, - "attributes": { - "proposal_id": "17131", - "prop_rev_active": true, - "prop_abstract": "uxor vulnus defendo dolorem vacuus", - "prop_motivation": "turbo quod eligendi veritas ait", - "prop_rationale": "apparatus ultra stabilis celo sol", - "gov_action_type_id": "2", - "prop_name": "Curriculum inventore patrocinor vaco similique solvo.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T16:30:52.111Z", - "updatedAt": "2025-01-29T16:30:52.111Z", - "proposal_links": [ - { - "id": 16958, - "prop_link": "https://reflecting-gain.name/", - "prop_link_text": "repentant-oregano" - } - ], - "proposal_withdrawals": [ - { - "id": 15285, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 910 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17112, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3264", - "createdAt": "2025-01-29T16:17:23.432Z", - "updatedAt": "2025-01-29T16:17:23.432Z", - "user_govtool_username": "gilda26_1738166760447", - "content": { - "id": 17091, - "attributes": { - "proposal_id": "17112", - "prop_rev_active": true, - "prop_abstract": "pax iure carus ocer bellum", - "prop_motivation": "aqua vapulus demens cogo carus", - "prop_rationale": "tamdiu statua accusamus distinctio animus", - "gov_action_type_id": "2", - "prop_name": "Careo terreo careo odio carus temptatio.", - "is_draft": false, - "user_id": "3264", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T16:17:23.462Z", - "updatedAt": "2025-01-29T16:17:23.462Z", - "proposal_links": [ - { - "id": 16939, - "prop_link": "https://palatable-grand.info", - "prop_link_text": "infinite-deviation" - } - ], - "proposal_withdrawals": [ - { - "id": 15266, - "prop_receiving_address": "stake1uz7vg8mjrh8hnvsdsh4gzw3affghkpexfmzj69yra0mn5hqncy7kh", - "prop_amount": 682 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17110, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T16:06:48.927Z", - "updatedAt": "2025-01-29T16:06:48.927Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17089, - "attributes": { - "proposal_id": "17110", - "prop_rev_active": true, - "prop_abstract": "velum cito sperno adimpleo cruciamentum", - "prop_motivation": "adipisci vicinus eius copia debitis", - "prop_rationale": "illum deduco succedo coniuratio tamen", - "gov_action_type_id": "2", - "prop_name": "Censura vis utor aegrotatio vestrum tactus.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T16:06:48.953Z", - "updatedAt": "2025-01-29T16:06:48.953Z", - "proposal_links": [ - { - "id": 16937, - "prop_link": "https://radiant-donut.name", - "prop_link_text": "chilly-earth" - } - ], - "proposal_withdrawals": [ - { - "id": 15264, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 436 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17091, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3249", - "createdAt": "2025-01-29T13:29:34.484Z", - "updatedAt": "2025-01-29T13:29:34.484Z", - "user_govtool_username": "jimmy_deckow21_1738156299677", - "content": { - "id": 17070, - "attributes": { - "proposal_id": "17091", - "prop_rev_active": true, - "prop_abstract": "trucido tolero amplitudo arcesso bellicus", - "prop_motivation": "cauda amita itaque dolorem expedita", - "prop_rationale": "bene denego patrocinor iusto baiulus", - "gov_action_type_id": "2", - "prop_name": "Barba adnuo repellat incidunt quas aufero.", - "is_draft": false, - "user_id": "3249", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T13:29:34.516Z", - "updatedAt": "2025-01-29T13:29:34.516Z", - "proposal_links": [ - { - "id": 16918, - "prop_link": "https://admirable-prizefight.com", - "prop_link_text": "some-main" - } - ], - "proposal_withdrawals": [ - { - "id": 15245, - "prop_receiving_address": "stake1urqlur423v8w95kle28ftm3mt3jpwg6vx2fmlh4xk0pyntq0t2x03", - "prop_amount": 716 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17070, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3242", - "createdAt": "2025-01-29T13:25:44.278Z", - "updatedAt": "2025-01-29T13:25:44.278Z", - "user_govtool_username": "felicity_johns_1738156022811", - "content": { - "id": 17049, - "attributes": { - "proposal_id": "17070", - "prop_rev_active": true, - "prop_abstract": "vis caelestis vir arcus venio", - "prop_motivation": "statua voluptates admoveo concedo turba", - "prop_rationale": "abutor acsi sollers nihil ara", - "gov_action_type_id": "2", - "prop_name": "Currus uxor carpo teres varius testimonium.", - "is_draft": false, - "user_id": "3242", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T13:25:44.305Z", - "updatedAt": "2025-01-29T13:25:44.305Z", - "proposal_links": [ - { - "id": 16897, - "prop_link": "https://hollow-onset.info/", - "prop_link_text": "used-jacket" - } - ], - "proposal_withdrawals": [ - { - "id": 15224, - "prop_receiving_address": "stake1urvcy7mtk5r509jejxxwz6ha80w646yxaxaeq32a6fm39fs48p22e", - "prop_amount": 649 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17068, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T13:12:34.653Z", - "updatedAt": "2025-01-29T13:12:34.653Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17047, - "attributes": { - "proposal_id": "17068", - "prop_rev_active": true, - "prop_abstract": "utrum debeo callide templum corona", - "prop_motivation": "aranea ventus verto pauci provident", - "prop_rationale": "laudantium placeat deputo vix tabernus", - "gov_action_type_id": "2", - "prop_name": "Repellat magnam conturbo comitatus pecco patior.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T13:12:34.691Z", - "updatedAt": "2025-01-29T13:12:34.691Z", - "proposal_links": [ - { - "id": 16895, - "prop_link": "https://insistent-hypochondria.info/", - "prop_link_text": "raw-tamale" - } - ], - "proposal_withdrawals": [ - { - "id": 15222, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 779 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17066, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T13:07:52.762Z", - "updatedAt": "2025-01-29T13:07:52.762Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17045, - "attributes": { - "proposal_id": "17066", - "prop_rev_active": true, - "prop_abstract": "cernuus quam theologus denique aegre", - "prop_motivation": "admitto odit statua veritatis utilis", - "prop_rationale": "tum sui aurum speculum repellat", - "gov_action_type_id": "2", - "prop_name": "Curis tersus confero stella cerno celebrer.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T13:07:52.792Z", - "updatedAt": "2025-01-29T13:07:52.792Z", - "proposal_links": [ - { - "id": 16893, - "prop_link": "https://previous-fisherman.info/", - "prop_link_text": "leafy-hobby" - } - ], - "proposal_withdrawals": [ - { - "id": 15220, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 807 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17064, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T12:52:21.000Z", - "updatedAt": "2025-01-29T12:52:21.000Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17043, - "attributes": { - "proposal_id": "17064", - "prop_rev_active": true, - "prop_abstract": "anser quibusdam ab conventus creator", - "prop_motivation": "acerbitas atrocitas commodo libero apto", - "prop_rationale": "vilitas nobis desidero trepide certe", - "gov_action_type_id": "2", - "prop_name": "Casso statua ad credo aurum curo.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T12:52:21.027Z", - "updatedAt": "2025-01-29T12:52:21.027Z", - "proposal_links": [ - { - "id": 16891, - "prop_link": "https://mortified-faucet.info", - "prop_link_text": "super-sandbar" - } - ], - "proposal_withdrawals": [ - { - "id": 15218, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 581 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17062, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T12:52:00.202Z", - "updatedAt": "2025-01-29T12:52:00.202Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17041, - "attributes": { - "proposal_id": "17062", - "prop_rev_active": true, - "prop_abstract": "tabella aggredior basium ager summisse", - "prop_motivation": "blanditiis pax venio ter defaeco", - "prop_rationale": "ambitus coniuratio clementia complectus verto", - "gov_action_type_id": "2", - "prop_name": "Cerno tempora accusamus celo curvo iure.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T12:52:00.242Z", - "updatedAt": "2025-01-29T12:52:00.242Z", - "proposal_links": [ - { - "id": 16889, - "prop_link": "https://parched-catalogue.name", - "prop_link_text": "inborn-middleman" - } - ], - "proposal_withdrawals": [ - { - "id": 15216, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 436 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17043, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3215", - "createdAt": "2025-01-29T11:48:35.324Z", - "updatedAt": "2025-01-29T11:48:35.324Z", - "user_govtool_username": "carter_padberg53_1738150702304", - "content": { - "id": 17022, - "attributes": { - "proposal_id": "17043", - "prop_rev_active": true, - "prop_abstract": "utique surgo validus consuasor esse", - "prop_motivation": "aetas despecto aiunt avaritia conturbo", - "prop_rationale": "anser labore est uterque comes", - "gov_action_type_id": "2", - "prop_name": "Doloremque vacuus tricesimus id approbo adopto.", - "is_draft": false, - "user_id": "3215", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T11:48:35.354Z", - "updatedAt": "2025-01-29T11:48:35.354Z", - "proposal_links": [ - { - "id": 16870, - "prop_link": "https://heartfelt-economics.name/", - "prop_link_text": "gloomy-derby" - } - ], - "proposal_withdrawals": [ - { - "id": 15197, - "prop_receiving_address": "stake1uz862u3nh7nldmeakemr3pkxdr8xz6n39xkq3wtu2ptxhcsfghatd", - "prop_amount": 805 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17024, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "3206", - "createdAt": "2025-01-29T11:42:48.167Z", - "updatedAt": "2025-01-29T11:42:48.167Z", - "user_govtool_username": "ericka.ritchie_1738150365664", - "content": { - "id": 17003, - "attributes": { - "proposal_id": "17024", - "prop_rev_active": true, - "prop_abstract": "cicuta undique verto comparo vespillo", - "prop_motivation": "absorbeo videlicet cenaculum deprecator accusator", - "prop_rationale": "natus voco conicio baiulus condico", - "gov_action_type_id": "2", - "prop_name": "Undique subseco abundans aegre vulnus ambulo.", - "is_draft": false, - "user_id": "3206", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T11:42:48.193Z", - "updatedAt": "2025-01-29T11:42:48.193Z", - "proposal_links": [ - { - "id": 16851, - "prop_link": "https://meaty-gate.net", - "prop_link_text": "orange-widow" - } - ], - "proposal_withdrawals": [ - { - "id": 15178, - "prop_receiving_address": "stake1urf2xgpkh7u2kjee4uu5as2h24l2tefpc4xsnha8sdsj6uqhtgsyq", - "prop_amount": 722 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17022, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T11:39:16.069Z", - "updatedAt": "2025-01-29T11:39:16.069Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 17001, - "attributes": { - "proposal_id": "17022", - "prop_rev_active": true, - "prop_abstract": "amet culpo vicissitudo arca adulatio", - "prop_motivation": "calcar agnitio succurro taedium ipsa", - "prop_rationale": "summa terebro minima bis sordeo", - "gov_action_type_id": "2", - "prop_name": "Beatae anser stillicidium quam aperio vallum.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T11:39:16.105Z", - "updatedAt": "2025-01-29T11:39:16.105Z", - "proposal_links": [ - { - "id": 16849, - "prop_link": "https://good-spark.biz", - "prop_link_text": "surprised-identification" - } - ], - "proposal_withdrawals": [ - { - "id": 15176, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 961 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 17020, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T11:33:35.606Z", - "updatedAt": "2025-01-29T11:33:35.606Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 16999, - "attributes": { - "proposal_id": "17020", - "prop_rev_active": true, - "prop_abstract": "curtus capitulus tardus brevis vox", - "prop_motivation": "auditor et aduro aperio vulgivagus", - "prop_rationale": "conturbo tersus minus cubo aestivus", - "gov_action_type_id": "2", - "prop_name": "Cursus attonbitus deorsum tollo ciminatio villa.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T11:33:35.634Z", - "updatedAt": "2025-01-29T11:33:35.634Z", - "proposal_links": [ - { - "id": 16847, - "prop_link": "https://silent-container.biz", - "prop_link_text": "tense-facelift" - } - ], - "proposal_withdrawals": [ - { - "id": 15174, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 447 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 16999, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-29T09:24:17.156Z", - "updatedAt": "2025-01-29T09:24:17.156Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 16978, - "attributes": { - "proposal_id": "16999", - "prop_rev_active": true, - "prop_abstract": "crustulum versus vapulus aliquam circumvenio", - "prop_motivation": "adhuc thalassinus arx dolores curvo", - "prop_rationale": "valde bene acquiro stabilis officiis", - "gov_action_type_id": "2", - "prop_name": "Curvo adsuesco depereo statua vulticulus thorax.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-29T09:24:17.191Z", - "updatedAt": "2025-01-29T09:24:17.191Z", - "proposal_links": [ - { - "id": 16826, - "prop_link": "https://traumatic-eagle.org/", - "prop_link_text": "anchored-sake" - } - ], - "proposal_withdrawals": [ - { - "id": 15153, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 261 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 16958, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-28T17:48:59.554Z", - "updatedAt": "2025-01-28T17:48:59.554Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 16937, - "attributes": { - "proposal_id": "16958", - "prop_rev_active": true, - "prop_abstract": "complectus adflicto voro adipiscor volubilis", - "prop_motivation": "decimus quis adduco alo trans", - "prop_rationale": "ubi demitto crux trepide contego", - "gov_action_type_id": "2", - "prop_name": "Undique ambulo acerbitas ter tertius titulus.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-28T17:48:59.585Z", - "updatedAt": "2025-01-28T17:48:59.585Z", - "proposal_links": [ - { - "id": 16785, - "prop_link": "https://testy-neuron.biz/", - "prop_link_text": "exemplary-selling" - } - ], - "proposal_withdrawals": [ - { - "id": 15112, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 563 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - }, - { - "id": 16957, - "attributes": { - "prop_likes": 0, - "prop_dislikes": 0, - "prop_comments_number": 0, - "user_id": "1876", - "createdAt": "2025-01-28T17:45:28.363Z", - "updatedAt": "2025-01-28T17:45:28.363Z", - "user_govtool_username": "cordie_stark_1732618876964", - "content": { - "id": 16936, - "attributes": { - "proposal_id": "16957", - "prop_rev_active": true, - "prop_abstract": "sol deprimo bonus adicio tamdiu", - "prop_motivation": "accusamus creta vir ara aetas", - "prop_rationale": "ultio degero exercitationem adfero vae", - "gov_action_type_id": "2", - "prop_name": "Animus virgo averto suscipio agnosco decerno.", - "is_draft": false, - "user_id": "1876", - "prop_submitted": false, - "prop_submission_tx_hash": null, - "prop_submission_date": null, - "createdAt": "2025-01-28T17:45:28.387Z", - "updatedAt": "2025-01-28T17:45:28.387Z", - "proposal_links": [ - { - "id": 16784, - "prop_link": "https://klutzy-light.biz", - "prop_link_text": "boring-closing" - } - ], - "proposal_withdrawals": [ - { - "id": 15111, - "prop_receiving_address": "stake1up8xg8ur80nsymvefrlk4dshjyfrze4pep843l289f4n8fgynegq0", - "prop_amount": 555 - } - ], - "gov_action_type": { - "id": 2, - "attributes": { - "gov_action_type_name": "Treasury", - "createdAt": "2024-08-21T21:40:32.586Z", - "updatedAt": "2024-08-21T21:40:33.850Z", - "publishedAt": "2024-08-21T21:40:33.843Z" - } - } - } - } - } - } - ], - "meta": { - "pagination": { - "page": 1, - "pageSize": 25, - "pageCount": 138, - "total": 3437 - } - } -} diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 28688e6ed..220d26c3c 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -16,8 +16,6 @@ import { ProposalType } from "@types"; const mockProposal = require("../../lib/_mock/proposal.json"); const mockPoll = require("../../lib/_mock/proposalPoll.json"); const mockComments = require("../../lib/_mock/proposalComments.json"); -const mockInfoProposedGA = require("../../lib/_mock/infoProposedGAs.json"); -const mockTreasuryProposal = require("../../lib/_mock/treasuryProposedGAs.json"); test.beforeEach(async () => { await setAllureEpic("8. Proposal Discussion Forum"); @@ -98,35 +96,18 @@ test("8D. Should show the view-all categorized proposed governance actions.", as browser, }) => { await Promise.all( - Object.entries({ - [ProposalType.info]: mockInfoProposedGA, - [ProposalType.treasury]: mockTreasuryProposal, - }).map(async ([proposalType, mockData]) => { - const requestUrl = `**/api/proposals?**`; - let requestHandled = 0; - + Object.values(ProposalType).map(async (proposalType: string) => { const context = await browser.newContext(); const page = await context.newPage(); - await page.route(requestUrl, async (route) => { - if (requestHandled < 2) { - requestHandled = requestHandled + 1; - return route.fulfill({ - body: JSON.stringify(mockData), - }); - } - return route.continue(); - }); - const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); - await proposalDiscussionPage.filterBtn.click(); - await proposalDiscussionPage.filterProposalByNames([proposalType]); - // to close the filter menu - await proposalDiscussionPage.filterBtn.click({ force: true }); - - proposalDiscussionPage.showAllBtn.click(); + page + .getByTestId( + proposalType.toLowerCase().replace(/ /g, "-") + "-show-all-button" + ) + .click(); const proposalCards = await proposalDiscussionPage.getAllProposals(); From 30c7603d1676308ac3b31b417daa95ee8535f37a Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 14 Feb 2025 14:51:43 +0545 Subject: [PATCH 04/61] chore: update test id of guardrailsScript checkbox --- .../playwright/lib/pages/proposalSubmissionPage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 78ead7bcb..0ea5f177d 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -66,9 +66,9 @@ export default class ProposalSubmissionPage { readonly createNewProposalBtn = this.page.getByTestId( "create-new-proposal-button" ); - readonly guardrailsScriptCheckbox = this.page.getByLabel( - "Do you want to provide new" - ); // BUG missing test id + readonly guardrailsScriptCheckbox = this.page.getByTestId( + "chb-prop-have-guardrails-script" + ); // input fields readonly titleInput = this.page.getByTestId("title-input"); From 5299bbd0174e13497f4e49ffa6b8e3f2a68b011a Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 12:31:23 +0545 Subject: [PATCH 05/61] feat: add method to calculate total abstain votes for DRep proposals --- .../lib/pages/governanceActionDetailsPage.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts index 4199b7f99..d79a84e51 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts @@ -124,6 +124,28 @@ export default class GovernanceActionDetailsPage { } } + async getDRepTotalAbstainVoted( + proposal: IProposal, + metricsResponsePromise: Promise + ): Promise { + const metricsResponses = await Promise.resolve(metricsResponsePromise); + const alwaysAbstainVotingPower = await metricsResponses + .json() + .then((data) => data.alwaysAbstainVotingPower); + + if ( + alwaysAbstainVotingPower && + typeof alwaysAbstainVotingPower === "number" + ) { + const totalAbstainVoted = + alwaysAbstainVotingPower + proposal.dRepAbstainVotes; + + return totalAbstainVoted; + } else { + return proposal.dRepAbstainVotes; + } + } + async downloadVoteMetadata() { const download: Download = await this.page.waitForEvent("download"); return downloadMetadata(download); From a5ad6666dae243449b4c1f2e02fbc6cb708053a4 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 12:32:30 +0545 Subject: [PATCH 06/61] fix: remove dRepNotVoted assertion --- .../proposalVisibility.dRep.spec.ts | 17 ++++++----------- .../proposalVisibility.spec.ts | 11 ----------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts index 4036d80ba..c10950fe0 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -184,10 +184,11 @@ test.describe("Check vote count", () => { `${proposalToCheck.txHash}#${proposalToCheck.index}` ); - const dRepNotVoted = await govActionDetailsPage.getDRepNotVoted( - proposalToCheck, - metricsResponsePromise - ); + const dRepTotalAbstainVote = + await govActionDetailsPage.getDRepTotalAbstainVoted( + proposalToCheck, + metricsResponsePromise + ); await govActionDetailsPage.showVotesBtn.click(); @@ -197,17 +198,11 @@ test.describe("Check vote count", () => { `₳ ${correctVoteAdaFormat(proposalToCheck.dRepYesVotes)}` ); await expect(govActionDetailsPage.dRepAbstainVotes).toHaveText( - `₳ ${correctVoteAdaFormat(proposalToCheck.dRepAbstainVotes)}` + `₳ ${correctVoteAdaFormat(dRepTotalAbstainVote)}` ); await expect(govActionDetailsPage.dRepNoVotes).toHaveText( `₳ ${correctVoteAdaFormat(proposalToCheck.dRepNoVotes)}` ); - - if (dRepNotVoted) { - await expect(govActionDetailsPage.dRepNotVoted).toHaveText( - `₳ ${correctVoteAdaFormat(dRepNotVoted)}` - ); - } } // check sPos votes diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts index d573eadee..d5d62692b 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts @@ -75,11 +75,6 @@ test("4K. Should display correct vote counts on governance details page for disc `${proposalToCheck.txHash}#${proposalToCheck.index}` ); - const dRepNotVoted = await govActionDetailsPage.getDRepNotVoted( - proposalToCheck, - metricsResponsePromise - ); - // check dRep votes if (await areDRepVoteTotalsDisplayed(proposalToCheck)) { await expect(govActionDetailsPage.dRepYesVotes).toHaveText( @@ -91,12 +86,6 @@ test("4K. Should display correct vote counts on governance details page for disc await expect(govActionDetailsPage.dRepNoVotes).toHaveText( `₳ ${correctVoteAdaFormat(proposalToCheck.dRepNoVotes)}` ); - - if (dRepNotVoted) { - await expect(govActionDetailsPage.dRepNotVoted).toHaveText( - `₳ ${correctVoteAdaFormat(dRepNotVoted)}` - ); - } } // check sPos votes if (await areSPOVoteTotalsDisplayed(proposalToCheck)) { From 7b615e3c041b7fb5cb81f6a93002c47ac06e8c3e Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 12:36:04 +0545 Subject: [PATCH 07/61] fix: await page interaction in proposal show-all-button --- .../tests/8-proposal-discussion/proposalDiscussion.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 220d26c3c..32dd3c618 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -103,7 +103,7 @@ test("8D. Should show the view-all categorized proposed governance actions.", as const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); - page + await page .getByTestId( proposalType.toLowerCase().replace(/ /g, "-") + "-show-all-button" ) From adc750accb26007a84b7594b5eac9a6610c4400c Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 13:56:03 +0545 Subject: [PATCH 08/61] feat: add guardrails script handling in proposal submission --- .../playwright/lib/constants/index.ts | 9 ++++ .../playwright/lib/helpers/metadata.ts | 9 ++++ .../lib/pages/proposalSubmissionPage.ts | 47 ++++++++++++------- .../govtool-frontend/playwright/lib/types.ts | 1 + .../proposalSubmission.loggedin.spec.ts | 6 +-- 5 files changed, 52 insertions(+), 20 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/constants/index.ts b/tests/govtool-frontend/playwright/lib/constants/index.ts index fc15d0258..f403d28b8 100644 --- a/tests/govtool-frontend/playwright/lib/constants/index.ts +++ b/tests/govtool-frontend/playwright/lib/constants/index.ts @@ -19,3 +19,12 @@ export const PROPOSAL_TYPE_FILTERS = [ export const BOOTSTRAP_PROPOSAL_TYPE_FILTERS = ["Info Action"]; export const PROPOSAL_STATUS_FILTER = ["Submitted for vote", "Active proposal"]; + +export const guardrailsScript = { + type: "PlutusScriptV3", + description: "", + cborHex: "46450101004981", +}; + +export const guardrailsScriptHash = + "914d97d63e2b7113465739faddd82362b1deaeedbcc4d01016c35c6e"; diff --git a/tests/govtool-frontend/playwright/lib/helpers/metadata.ts b/tests/govtool-frontend/playwright/lib/helpers/metadata.ts index 69e8802f2..267d9e177 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/metadata.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/metadata.ts @@ -62,3 +62,12 @@ export async function uploadMetadataAndGetJsonHash() { ); return { dataHash, url }; } + +export async function uploadScriptAndGenerateUrl(payload: Object) { + const data = JSON.stringify(payload); + const jsonData = JSON.parse(data); + return await metadataBucketService.uploadMetadata( + "guardrail-script", + jsonData + ); +} diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 0ea5f177d..f58c4b349 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -1,10 +1,14 @@ import environments from "@constants/environments"; +import { guardrailsScript, guardrailsScriptHash } from "@constants/index"; import { proposal04Wallet } from "@constants/staticWallets"; import { faker } from "@faker-js/faker"; import { isBootStrapingPhase } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { expectWithInfo } from "@helpers/exceptionHandler"; -import { calculateHash, downloadMetadata } from "@helpers/metadata"; +import { + downloadMetadata, + uploadScriptAndGenerateUrl, +} from "@helpers/metadata"; import { extractProposalIdFromUrl } from "@helpers/string"; import { invalid } from "@mock/index"; import { Download, Locator, Page, expect } from "@playwright/test"; @@ -172,7 +176,9 @@ export default class ProposalSubmissionPage { await this.treasuryBtn.click(); } else { await this.updateTheConstitutionBtn.click(); - await this.guardrailsScriptCheckbox.click(); + if (governanceProposal.has_guardrails) { + await this.guardrailsScriptCheckbox.click(); + } } await this.fillupFormWithTypeSelected(governanceProposal); @@ -199,12 +205,14 @@ export default class ProposalSubmissionPage { governanceProposal.prop_constitution_url ); - await this.guardrailsScriptUrlInput.fill( - governanceProposal.prop_guardrails_script_url - ); - await this.guardrailsScriptHashInput.fill( - governanceProposal.prop_guardrails_script_hash - ); + if (governanceProposal.has_guardrails) { + await this.guardrailsScriptUrlInput.fill( + governanceProposal.prop_guardrails_script_url + ); + await this.guardrailsScriptHashInput.fill( + governanceProposal.prop_guardrails_script_hash + ); + } } async fillProposalLinks(proposal_links: Array) { @@ -358,10 +366,11 @@ export default class ProposalSubmissionPage { await expect(this.continueBtn).toBeDisabled(); } - generateValidProposalFormFields( + async generateValidProposalFormFields( proposalType: ProposalType, is_draft?: boolean, - receivingAddress?: string + receivingAddress?: string, + hasGuardrails: boolean = true ) { const proposal: ProposalCreateRequest = { prop_name: faker.lorem.sentence(6), @@ -376,6 +385,7 @@ export default class ProposalSubmissionPage { }, ], gov_action_type_id: Object.values(ProposalType).indexOf(proposalType), + has_guardrails: hasGuardrails, is_draft: !!is_draft, }; @@ -386,11 +396,14 @@ export default class ProposalSubmissionPage { .toString()); } if (proposalType === ProposalType.updatesToTheConstitution) { - proposal.prop_constitution_url = faker.internet.url(); - proposal.prop_guardrails_script_url = faker.internet.url(); - proposal.prop_guardrails_script_hash = calculateHash( - faker.lorem.paragraph() - ); + proposal.prop_constitution_url = + environments.metadataBucketUrl + "/data.jsonId"; + + if (proposal.has_guardrails) { + const url = await uploadScriptAndGenerateUrl(guardrailsScript); + proposal.prop_guardrails_script_url = url; + proposal.prop_guardrails_script_hash = guardrailsScriptHash; + } } return proposal; } @@ -437,7 +450,7 @@ export default class ProposalSubmissionPage { ); const proposalRequest: ProposalCreateRequest = - this.generateValidProposalFormFields( + await this.generateValidProposalFormFields( (await isBootStrapingPhase()) ? ProposalType.info : proposalType, false, receivingAddr @@ -457,7 +470,7 @@ export default class ProposalSubmissionPage { await this.goto(); await this.addLinkBtn.click(); - const proposalFormValue = this.generateValidProposalFormFields( + const proposalFormValue = await this.generateValidProposalFormFields( proposalType, true, ShelleyWallet.fromJson(proposal04Wallet).rewardAddressBech32( diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 25d233055..71c50c4fb 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -163,6 +163,7 @@ export type ProposalCreateRequest = { prop_constitution_url?: string; prop_guardrails_script_url?: string; prop_guardrails_script_hash?: string; + has_guardrails?: boolean; is_draft: boolean; }; diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts index af5cbeb47..a65f06781 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts @@ -64,7 +64,7 @@ test.describe("Proposal created logged state", () => { await ShelleyWallet.generate() ).rewardAddressBech32(environments.networkId); const formFields: ProposalCreateRequest = - proposalSubmissionPage.generateValidProposalFormFields( + await proposalSubmissionPage.generateValidProposalFormFields( type, false, rewardAddressBech32 @@ -141,7 +141,7 @@ test.describe("Proposal created logged state", () => { wallet ).rewardAddressBech32(environments.networkId); const proposal: ProposalCreateRequest = - proposalSubmissionPage.generateValidProposalFormFields( + await proposalSubmissionPage.generateValidProposalFormFields( type, false, stakeAddressBech32 @@ -195,7 +195,7 @@ test.describe("Proposal created logged state", () => { proposal01Wallet ).rewardAddressBech32(environments.networkId); const proposal: ProposalCreateRequest = - proposalSubmissionPage.generateValidProposalFormFields( + await proposalSubmissionPage.generateValidProposalFormFields( type, false, rewardAddressBech32 From 2f48a4ce074f92ed18060b0c2a19acc72cb5953e Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 14:02:25 +0545 Subject: [PATCH 09/61] fix: add dynamic CORS middleware to handle cross-origin requests --- tests/test-metadata-api/index.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/test-metadata-api/index.js b/tests/test-metadata-api/index.js index b689ac0f1..62c25b1a6 100644 --- a/tests/test-metadata-api/index.js +++ b/tests/test-metadata-api/index.js @@ -8,6 +8,24 @@ const swaggerJsdoc = require('swagger-jsdoc'); const app = express(); + +const dynamicCors = (req, res, next) => { + const origin = req.headers.origin + + // Allow requests from any origin but with credentials + res.header('Access-Control-Allow-Origin', origin || '*'); + res.header('Access-Control-Allow-Methods', 'GET,PUT,OPTIONS'); + res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + res.header('Access-Control-Allow-Credentials', 'true'); + + // Handle preflight requests + if (req.method === 'OPTIONS') { + res.sendStatus(200); + } else { + next(); + } +}; + const dataDir = process.env.DATA_DIR || path.join(__dirname, 'json_files'); if (!fs.existsSync(dataDir)) { @@ -31,6 +49,9 @@ const swaggerOptions = { const swaggerSpec = swaggerJsdoc(swaggerOptions); +// cors enable +app.use(dynamicCors); + // Serve Swagger UI app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec)); From bc801ce2c43554e802b5fae4d756a6d68083fceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 13 Feb 2025 21:49:48 +0100 Subject: [PATCH 10/61] fix(#2929): fix high severity code smells --- CHANGELOG.md | 1 + govtool/frontend/.eslintrc.cjs | 1 + .../src/components/atoms/Background.tsx | 88 ++++-- .../src/components/atoms/CopyButton.tsx | 7 + .../src/components/atoms/StakeRadio.tsx | 8 +- .../frontend/src/components/atoms/Tooltip.tsx | 2 +- .../molecules/AutomatedVotingCard.tsx | 159 +++++----- .../src/components/molecules/CopyableInfo.tsx | 2 +- .../src/components/molecules/DRepInfoCard.tsx | 5 +- .../molecules/DashboardActionCard.tsx | 181 +++++------ .../molecules/DataActionsFilters.tsx | 3 - .../molecules/GovernanceActionCardElement.tsx | 285 +++++++++--------- .../GovernanceActionDetailsCardLinks.tsx | 10 + .../src/components/organisms/TopNav.tsx | 230 +++++++------- govtool/frontend/src/context/getUtxos.ts | 91 +++--- .../frontend/src/stories/Checkbox.stories.tsx | 6 +- .../src/stories/GovernanceAction.stories.ts | 2 +- .../frontend/src/utils/bech32Validation.ts | 2 +- .../utils/getGovActionVotingThresholdKey.ts | 166 +++++----- 19 files changed, 643 insertions(+), 606 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8be337c51..805838873 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ changes. - Add support for submitting all 7 governance action types [Issue 2258](https://github.com/IntersectMBO/govtool/issues/2258) - Add workflow to automatically update any of the @intersect.mbo package [Issue 2968](https://github.com/IntersectMBO/govtool/issues/2968) - Add Propose Governance Action button in governance actions dashboard [Issue 1188](https://github.com/IntersectMBO/govtool/issues/1188) +- Add click handlers to non-interactive elements [Issue 2929](https://github.com/IntersectMBO/govtool/issues/2929) ### Fixed diff --git a/govtool/frontend/.eslintrc.cjs b/govtool/frontend/.eslintrc.cjs index 07d27ff79..d550a36d6 100644 --- a/govtool/frontend/.eslintrc.cjs +++ b/govtool/frontend/.eslintrc.cjs @@ -94,6 +94,7 @@ module.exports = { }, ], "react/require-default-props": "off", + "react/no-unstable-nested-components": "off", // TODO: This rule should be enabled in the future "react-hooks/exhaustive-deps": "off", diff --git a/govtool/frontend/src/components/atoms/Background.tsx b/govtool/frontend/src/components/atoms/Background.tsx index 62ca862a1..50948ff60 100644 --- a/govtool/frontend/src/components/atoms/Background.tsx +++ b/govtool/frontend/src/components/atoms/Background.tsx @@ -1,17 +1,75 @@ -import { ReactNode } from "react"; - +import { ReactNode, CSSProperties } from "react"; import { IMAGES } from "@consts"; import { useScreenDimension } from "@/hooks"; +type BackgroundProps = { + children: ReactNode; + isReverted?: boolean; + opacity?: number; +}; + +const getStyle = ( + isMobile: boolean, + isReverted: boolean, + type: "orange" | "blue", + opacity: number, +): CSSProperties => { + const commonStyles: CSSProperties = { + opacity, + position: "fixed", + zIndex: -10, + }; + + let orangeBottomStyle = -650; + if (isMobile) { + orangeBottomStyle = -150; + if (isReverted) { + orangeBottomStyle = 200; + } + } + + let orangeRightStyle = -650; + if (isMobile) { + orangeRightStyle = -250; + if (isReverted) { + orangeRightStyle = 450; + } + } + + let blueTopStyle = -500; + if (isMobile) { + blueTopStyle = -150; + if (isReverted) { + blueTopStyle = 400; + } + } + let blueLeftStyle = -400; + if (isMobile) { + blueLeftStyle = -250; + if (isReverted) { + blueLeftStyle = 400; + } + } + + const positions = { + orange: { + bottom: orangeBottomStyle, + right: orangeRightStyle, + }, + blue: { + top: blueTopStyle, + left: blueLeftStyle, + }, + }; + + return { ...commonStyles, ...positions[type] }; +}; + export const Background = ({ children, isReverted = false, opacity = 1, -}: { - children: ReactNode; - isReverted?: boolean; - opacity?: number; -}) => { +}: BackgroundProps) => { const { isMobile } = useScreenDimension(); return ( @@ -20,13 +78,7 @@ export const Background = ({ alt="bg-orange" height={isMobile ? 600 : "auto"} src={IMAGES.bgOrange} - style={{ - bottom: isMobile ? -150 : isReverted ? 200 : -650, - opacity, - position: "fixed", - right: isMobile ? -250 : isReverted ? 450 : -650, - zIndex: -10, - }} + style={getStyle(isMobile, isReverted, "orange", opacity)} width={isMobile ? 600 : "auto"} /> {children} @@ -34,13 +86,7 @@ export const Background = ({ alt="bg-blue" height={isMobile ? 600 : "auto"} src={IMAGES.bgBlue} - style={{ - left: isMobile ? -250 : isReverted ? 400 : -400, - opacity, - position: "fixed", - top: isMobile ? -150 : isReverted ? 400 : -500, - zIndex: -10, - }} + style={getStyle(isMobile, isReverted, "blue", opacity)} width={isMobile ? 600 : "auto"} /> diff --git a/govtool/frontend/src/components/atoms/CopyButton.tsx b/govtool/frontend/src/components/atoms/CopyButton.tsx index 021d5fcc0..efdf2e7c2 100644 --- a/govtool/frontend/src/components/atoms/CopyButton.tsx +++ b/govtool/frontend/src/components/atoms/CopyButton.tsx @@ -41,6 +41,13 @@ export const CopyButton = ({ isChecked, text, variant }: Props) => { }} src={iconSrc} style={{ cursor: "pointer" }} + onKeyDown={(e) => { + if (e.ctrlKey && e.key === "c") { + navigator.clipboard.writeText(text); + addSuccessAlert(t("alerts.copiedToClipboard")); + e.stopPropagation(); + } + }} /> ); }; diff --git a/govtool/frontend/src/components/atoms/StakeRadio.tsx b/govtool/frontend/src/components/atoms/StakeRadio.tsx index 8c7e4c57f..e6a9c8125 100644 --- a/govtool/frontend/src/components/atoms/StakeRadio.tsx +++ b/govtool/frontend/src/components/atoms/StakeRadio.tsx @@ -57,7 +57,7 @@ export const StakeRadio: FC = ({ ...props }) => { > {stakeKey} - + copy { @@ -65,6 +65,12 @@ export const StakeRadio: FC = ({ ...props }) => { e.stopPropagation(); }} src={isChecked ? ICONS.copyWhiteIcon : ICONS.copyIcon} + onKeyDown={(e) => { + if (e.ctrlKey && e.key === "c") { + navigator.clipboard.writeText(stakeKey); + e.stopPropagation(); + } + }} /> diff --git a/govtool/frontend/src/components/atoms/Tooltip.tsx b/govtool/frontend/src/components/atoms/Tooltip.tsx index dd8d8dc23..663d425b9 100644 --- a/govtool/frontend/src/components/atoms/Tooltip.tsx +++ b/govtool/frontend/src/components/atoms/Tooltip.tsx @@ -41,7 +41,7 @@ export const Tooltip = ({ fontWeight={400} color="rgb(170, 170, 170)" > - {paragraphOne && paragraphOne} + {paragraphOne && <>{paragraphOne}} {paragraphTwo && ( <>

diff --git a/govtool/frontend/src/components/molecules/AutomatedVotingCard.tsx b/govtool/frontend/src/components/molecules/AutomatedVotingCard.tsx index 729a02523..fbf1a1f81 100644 --- a/govtool/frontend/src/components/molecules/AutomatedVotingCard.tsx +++ b/govtool/frontend/src/components/molecules/AutomatedVotingCard.tsx @@ -1,5 +1,4 @@ import { Box, Divider } from "@mui/material"; - import { Button, Typography } from "@atoms"; import { primaryBlue } from "@consts"; import { useAppContext, useModal } from "@context"; @@ -31,15 +30,87 @@ export const AutomatedVotingCard = ({ const onClickShowTransaction = () => openInNewTab(`${cExplorerBaseUrl}/tx/${transactionId}`); + const renderTransactionButton = () => + transactionId && ( + + ); + + const renderVotingPower = () => ( + + + {t("dRepDirectory.votingPower")} + + + {"₳ "} + {votingPower} + + + ); + + const renderActionButtons = () => ( + + + {isConnected ? ( + !isSelected && ( + + ) + ) : ( + + )} + + ); + return ( `${theme.palette.neutralWhite}40`, @@ -72,15 +143,7 @@ export const AutomatedVotingCard = ({ > {description} - {transactionId && ( - - )} + {renderTransactionButton()} {!inProgress && !isSelected && ( <> @@ -90,72 +153,14 @@ export const AutomatedVotingCard = ({ sx={{ ml: screenWidth < 1024 ? 0 : 1 }} variant={screenWidth < 1024 ? "fullWidth" : "middle"} /> - - - {t("dRepDirectory.votingPower")} - - - {"₳ "} - {votingPower} - - + {renderVotingPower()} - - - {!isConnected ? ( - - ) : ( - !isSelected && ( - - ) - )} - + {renderActionButtons()} )} diff --git a/govtool/frontend/src/components/molecules/CopyableInfo.tsx b/govtool/frontend/src/components/molecules/CopyableInfo.tsx index ac0875ebc..ee40f16c1 100644 --- a/govtool/frontend/src/components/molecules/CopyableInfo.tsx +++ b/govtool/frontend/src/components/molecules/CopyableInfo.tsx @@ -33,7 +33,7 @@ export const CopyableInfo = ({ {label} - + { return ( - + {t("myDRepId")} diff --git a/govtool/frontend/src/components/molecules/DashboardActionCard.tsx b/govtool/frontend/src/components/molecules/DashboardActionCard.tsx index 0e3ec7b6d..1db9026c9 100644 --- a/govtool/frontend/src/components/molecules/DashboardActionCard.tsx +++ b/govtool/frontend/src/components/molecules/DashboardActionCard.tsx @@ -11,7 +11,6 @@ import { Card } from "./Card"; export type DashboardActionCardProps = { buttons?: LoadingButtonProps[]; children?: ReactNode; - dataTestidDelegationStatus?: string; description?: ReactNode; imageURL?: string; isLoading?: boolean; @@ -43,11 +42,100 @@ export const DashboardActionCard: FC = ({ }) => { const { t } = useTranslation(); const { cExplorerBaseUrl } = useAppContext(); - const { screenWidth } = useScreenDimension(); - const onClickShowTransaction = () => - openInNewTab(`${cExplorerBaseUrl}/tx/${transactionId}`); + const onClickShowTransaction = () => { + if (transactionId) { + openInNewTab(`${cExplorerBaseUrl}/tx/${transactionId}`); + } + }; + + const renderImage = () => { + if (!imageURL) return null; + return isLoading ? ( + + ) : ( + card + ); + }; + + const renderTitle = () => { + if (!title) return null; + return ( + + {isLoading ? : title} + {state === "inProgress" && !isLoading && isInProgressOnCard && ( + + {` ${t("inProgress")}`} + + )} + + ); + }; + + const renderDescription = () => { + if (!description) return null; + return ( + + {isLoading ? : description} + + ); + }; + + const renderButtons = () => { + if (isLoading) { + return ( + <> + + + + ); + } + + return buttons?.map(({ dataTestId, ...buttonProps }) => ( + + + )} + + + ); + + const renderMobileNav = () => ( + + {isConnectButton && ( + + )} + {screenWidth >= 768 ? ( + setIsDrawerOpen(true)} + sx={{ bgcolor: "#FBFBFF" }} + > + + + ) : ( + drawer-icon setIsDrawerOpen(true)} + onKeyDown={(e) => e.key === "Enter" && setIsDrawerOpen(true)} + data-testid="open-drawer-button" + /> + )} + + + ); + return ( { : "transparent", borderBottom: isMobile ? 1 : 0, borderColor: "lightblue", - borderRadius: 0, boxShadow: 0, justifyContent: "center", flexDirection: "row", @@ -82,8 +161,8 @@ export const TopNav = ({ isConnectButton = true }) => { > { > (isConnectButton ? {} : disconnectWallet())} to={PATHS.home} + onClick={() => isConnectButton || disconnectWallet()} > app-logo { src={IMAGES.appLogo} /> - {screenWidth >= 1024 ? ( - - ) : ( - <> - - {isConnectButton ? ( - - ) : null} - {screenWidth >= 768 ? ( - - - - ) : ( - drawer-icon - )} - - - - )} + {screenWidth >= 1024 ? renderDesktopNav() : renderMobileNav()} ); diff --git a/govtool/frontend/src/context/getUtxos.ts b/govtool/frontend/src/context/getUtxos.ts index 024ce8e21..a8b38e3e7 100644 --- a/govtool/frontend/src/context/getUtxos.ts +++ b/govtool/frontend/src/context/getUtxos.ts @@ -1,10 +1,13 @@ import { CardanoApiWallet } from "@models"; import * as Sentry from "@sentry/react"; -import { TransactionUnspentOutput } from "@emurgo/cardano-serialization-lib-asmjs"; +import { + TransactionUnspentOutput, + MultiAsset, +} from "@emurgo/cardano-serialization-lib-asmjs"; import { Buffer } from "buffer"; type Utxos = { - txid: unknown; + txid: string; txindx: number; amount: string; str: string; @@ -12,69 +15,53 @@ type Utxos = { TransactionUnspentOutput: TransactionUnspentOutput; }[]; +const parseMultiAsset = (multiasset?: MultiAsset): string => { + if (!multiasset) return ""; + + return Array.from({ length: multiasset.keys().len() }, (_, i) => { + const policyId = multiasset.keys().get(i); + const policyIdHex = policyId.to_hex(); + const assets = multiasset.get(policyId); + + return assets + ? Array.from({ length: assets.keys().len() }, (_i, j) => { + const assetName = assets.keys().get(j); + const assetNameHex = Buffer.from( + assetName.name().toString(), + "utf8", + ).toString("hex"); + const assetNameString = assetName.name().toString(); + const multiassetAmt = multiasset.get_asset(policyId, assetName); + return `+ ${multiassetAmt.to_str()} + ${policyIdHex}.${assetNameHex} (${assetNameString})`; + }).join(" ") + : ""; + }).join(" "); +}; + export const getUtxos = async ( enabledApi: CardanoApiWallet, ): Promise => { - const utxos = []; - try { const rawUtxos = await enabledApi.getUtxos(); - - // TODO maybe refactor - // eslint-disable-next-line no-restricted-syntax - for (const rawUtxo of rawUtxos) { + return rawUtxos.map((rawUtxo: string) => { const utxo = TransactionUnspentOutput.from_bytes( Buffer.from(rawUtxo, "hex"), ); const input = utxo.input(); - const txid = input.transaction_id().to_hex(); - - const txindx = input.index(); const output = utxo.output(); - const amount = output.amount().coin().to_str(); // Ada amount in lovelace - const multiasset = output.amount().multiasset(); - let multiAssetStr = ""; - - if (multiasset) { - const keys = multiasset.keys(); // policy Ids of thee multiasset - const N = keys.len(); - - for (let i = 0; i < N; i++) { - const policyId = keys.get(i); - const policyIdHex = policyId.to_hex(); - const assets = multiasset.get(policyId); - if (assets) { - const assetNames = assets.keys(); - const K = assetNames.len(); - for (let j = 0; j < K; j++) { - const assetName = assetNames.get(j); - const assetNameString = assetName.name().toString(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const assetNameHex = Buffer.from( - assetName.name(), - "utf8", - ).toString("hex"); - const multiassetAmt = multiasset.get_asset(policyId, assetName); - multiAssetStr += `+ ${multiassetAmt.to_str()} + ${policyIdHex}.${assetNameHex} (${assetNameString})`; - } - } - } - } - - const obj = { - amount, - multiAssetStr, - str: `${txid} #${txindx} = ${amount}`, + return { + txid: input.transaction_id().to_hex(), + txindx: input.index(), + amount: output.amount().coin().to_str(), + multiAssetStr: parseMultiAsset(output.amount().multiasset()), + str: `${input.transaction_id().to_hex()} #${input.index()} = ${output + .amount() + .coin() + .to_str()}`, TransactionUnspentOutput: utxo, - txid, - txindx, }; - utxos.push(obj); - } - - return utxos; + }); } catch (err) { Sentry.setTag("util", "getUtxos"); Sentry.captureException(err); diff --git a/govtool/frontend/src/stories/Checkbox.stories.tsx b/govtool/frontend/src/stories/Checkbox.stories.tsx index aa2272ec7..3a56c76b0 100644 --- a/govtool/frontend/src/stories/Checkbox.stories.tsx +++ b/govtool/frontend/src/stories/Checkbox.stories.tsx @@ -35,11 +35,11 @@ WithLabel.play = async ({ canvasElement }) => { expect(canvas.getByText("Label")).toBeVisible(); }; -export const Error = Template.bind({}); -Error.args = { +export const ErrorBase = Template.bind({}); +ErrorBase.args = { errorMessage: "Error message", }; -Error.play = async ({ canvasElement, args }) => { +ErrorBase.play = async ({ canvasElement, args }) => { const canvas = within(canvasElement); const errorId = args.errorMessage!.toLowerCase().split(" ").join("-"); diff --git a/govtool/frontend/src/stories/GovernanceAction.stories.ts b/govtool/frontend/src/stories/GovernanceAction.stories.ts index ee4c7a3e3..3119c83c5 100644 --- a/govtool/frontend/src/stories/GovernanceAction.stories.ts +++ b/govtool/frontend/src/stories/GovernanceAction.stories.ts @@ -97,7 +97,7 @@ export const GovernanceActionCardComponent: Story = { await userEvent.click( canvas.getByTestId("govaction-sad78afdsf7jasd98d#2-view-detail"), ); - await await expect(args.onClick).toHaveBeenCalled(); + await expect(args.onClick).toHaveBeenCalled(); }, }; diff --git a/govtool/frontend/src/utils/bech32Validation.ts b/govtool/frontend/src/utils/bech32Validation.ts index d82c7bd9b..8704b8067 100644 --- a/govtool/frontend/src/utils/bech32Validation.ts +++ b/govtool/frontend/src/utils/bech32Validation.ts @@ -9,7 +9,7 @@ import I18n from "@/i18n"; */ export const bech32Validation = async (value: string) => { try { - const decoded = await bech32.decode(value); + const decoded = bech32.decode(value); if (decoded.words.length) { return true; } diff --git a/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts b/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts index 27c29b358..1b9ae4ed3 100644 --- a/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts +++ b/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts @@ -8,94 +8,90 @@ import { import { EpochParams } from "@/models"; import { GovernanceActionType } from "@/types/governanceAction"; -/** - * Retrieves the voting threshold key for a given governance action type, - * protocol parameters, and voter type. - * @param options - The options object containing the governance action type, - * protocol parameters, and voter type. - * @returns The voting threshold key corresponding to - * the provided options, or undefined if no matching key is found. - */ -export const getGovActionVotingThresholdKey = ({ - govActionType, - protocolParams, - voterType, -}: { +type VotingThresholdKey = string | undefined; + +type GetGovActionVotingThresholdKeyOptions = { govActionType: GovernanceActionType; protocolParams?: Partial | null; voterType?: VoterType; -}) => { - switch (govActionType) { - case GovernanceActionType.NewCommittee: { - // TODO: handle dvt_committee_normal and pvt_committee_normal - return voterType === "dReps" - ? "dvt_committee_normal" - : voterType === "sPos" - ? "pvt_committee_normal" - : undefined; - } - case GovernanceActionType.HardForkInitiation: { - return voterType === "dReps" - ? "dvt_hard_fork_initiation" - : voterType === "sPos" - ? "pvt_hard_fork_initiation" - : undefined; - } - case GovernanceActionType.ParameterChange: { - if (protocolParams) { - const filteredProtocolParameterKeys = Object.entries( - protocolParams, - ).map(([key, value]) => { - if (typeof value === "number" || typeof value === "string") { - return key; - } - }); +}; + +const getParameterChangeThreshold = ( + protocolParams?: Partial | null, + voterType?: VoterType, +): VotingThresholdKey => { + if (!protocolParams || voterType !== "dReps") return undefined; - if ( - PPU_ECONOMIC_GROUP_PARAMS_KEYS.some((key) => - filteredProtocolParameterKeys.includes(key), - ) - ) { - return voterType === "dReps" ? "dvt_p_p_economic_group" : undefined; - } - if ( - PPU_GOVERNANCE_GROUP_PARAMS_KEYS.some((key) => - filteredProtocolParameterKeys.includes(key), - ) - ) { - return voterType === "dReps" ? "dvt_p_p_gov_group" : undefined; - } - if ( - PPU_NETWORK_GROUP_PARAMS_KEYS.some((key) => - filteredProtocolParameterKeys.includes(key), - ) - ) { - return voterType === "dReps" - ? "dvt_p_p_network_group" - : voterType === "sPos" - ? "pvtpp_security_group" - : undefined; - } - if ( - PPU_TECHNICAL_GROUP_PARAMS_KEYS.some((key) => - filteredProtocolParameterKeys.includes(key), - ) - ) { - return voterType === "dReps" ? "dvt_p_p_technical_group" : undefined; - } - return undefined; - } - break; - } - case GovernanceActionType.TreasuryWithdrawals: - return voterType === "dReps" ? "dvt_treasury_withdrawal" : undefined; - case GovernanceActionType.NewConstitution: - return voterType === "dReps" ? "dvt_update_to_constitution" : undefined; - case GovernanceActionType.NoConfidence: - return voterType === "dReps" - ? "dvt_motion_no_confidence" - : "pvt_motion_no_confidence"; - default: - return undefined; + const protocolParamKeys = Object.keys(protocolParams).filter((key) => + ["number", "string"].includes( + typeof protocolParams[key as keyof EpochParams], + ), + ); + + if ( + PPU_ECONOMIC_GROUP_PARAMS_KEYS.some((key) => + protocolParamKeys.includes(key), + ) + ) { + return "dvt_p_p_economic_group"; + } + if ( + PPU_GOVERNANCE_GROUP_PARAMS_KEYS.some((key) => + protocolParamKeys.includes(key), + ) + ) { + return "dvt_p_p_gov_group"; } + if ( + PPU_NETWORK_GROUP_PARAMS_KEYS.some((key) => protocolParamKeys.includes(key)) + ) { + return voterType === "dReps" + ? "dvt_p_p_network_group" + : "pvtpp_security_group"; + } + if ( + PPU_TECHNICAL_GROUP_PARAMS_KEYS.some((key) => + protocolParamKeys.includes(key), + ) + ) { + return "dvt_p_p_technical_group"; + } + return undefined; +}; + +export const getGovActionVotingThresholdKey = ({ + govActionType, + protocolParams, + voterType, +}: GetGovActionVotingThresholdKeyOptions): VotingThresholdKey => { + const govActionThresholds: Record = + { + [GovernanceActionType.NewCommittee]: + voterType === "dReps" + ? "dvt_committee_normal" + : voterType === "sPos" + ? "pvt_committee_normal" + : undefined, + [GovernanceActionType.HardForkInitiation]: + voterType === "dReps" + ? "dvt_hard_fork_initiation" + : voterType === "sPos" + ? "pvt_hard_fork_initiation" + : undefined, + [GovernanceActionType.ParameterChange]: getParameterChangeThreshold( + protocolParams, + voterType, + ), + [GovernanceActionType.TreasuryWithdrawals]: + voterType === "dReps" ? "dvt_treasury_withdrawal" : undefined, + [GovernanceActionType.NewConstitution]: + voterType === "dReps" ? "dvt_update_to_constitution" : undefined, + [GovernanceActionType.NoConfidence]: + voterType === "dReps" + ? "dvt_motion_no_confidence" + : "pvt_motion_no_confidence", + [GovernanceActionType.InfoAction]: undefined, + }; + + return govActionThresholds[govActionType] ?? undefined; }; From 810ac8baa4187f801094a6b1ff78395225d10c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 14 Feb 2025 10:26:47 +0100 Subject: [PATCH 11/61] fix: type error on voting threshold value --- .../components/molecules/VotesSubmitted.tsx | 36 ++++++++++--------- .../utils/getGovActionVotingThresholdKey.ts | 2 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/govtool/frontend/src/components/molecules/VotesSubmitted.tsx b/govtool/frontend/src/components/molecules/VotesSubmitted.tsx index 15819d217..0e0a27b8b 100644 --- a/govtool/frontend/src/components/molecules/VotesSubmitted.tsx +++ b/govtool/frontend/src/components/molecules/VotesSubmitted.tsx @@ -165,14 +165,16 @@ export const VotesSubmitted = ({ abstainVotes={totalAbstainVotes} notVotedVotes={dRepNotVotedVotes} notVotedPercentage={dRepNotVotedVotesPercentage} - threshold={(() => { - const votingThresholdKey = getGovActionVotingThresholdKey({ - govActionType: type, - protocolParams, - voterType: "dReps", - }); - return votingThresholdKey && epochParams?.[votingThresholdKey]; - })()} + threshold={ + (() => { + const votingThresholdKey = getGovActionVotingThresholdKey({ + govActionType: type, + protocolParams, + voterType: "dReps", + }); + return votingThresholdKey && epochParams?.[votingThresholdKey]; + })() as number + } /> )} {areSPOVoteTotalsDisplayed(type, isSecurityGroup()) && ( @@ -183,14 +185,16 @@ export const VotesSubmitted = ({ noVotes={poolNoVotes} noVotesPercentage={poolNoVotesPercentage} abstainVotes={poolAbstainVotes} - threshold={(() => { - const votingThresholdKey = getGovActionVotingThresholdKey({ - govActionType: type, - protocolParams, - voterType: "sPos", - }); - return votingThresholdKey && epochParams?.[votingThresholdKey]; - })()} + threshold={ + (() => { + const votingThresholdKey = getGovActionVotingThresholdKey({ + govActionType: type, + protocolParams, + voterType: "sPos", + }); + return votingThresholdKey && epochParams?.[votingThresholdKey]; + })() as number + } /> )} {areCCVoteTotalsDisplayed(type) && ( diff --git a/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts b/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts index 1b9ae4ed3..862de48b3 100644 --- a/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts +++ b/govtool/frontend/src/utils/getGovActionVotingThresholdKey.ts @@ -8,7 +8,7 @@ import { import { EpochParams } from "@/models"; import { GovernanceActionType } from "@/types/governanceAction"; -type VotingThresholdKey = string | undefined; +type VotingThresholdKey = keyof EpochParams | undefined; type GetGovActionVotingThresholdKeyOptions = { govActionType: GovernanceActionType; From 549d7a214c35f4b539f0d35b30a39cf488cfcba5 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 16:06:46 +0545 Subject: [PATCH 12/61] refactor: use different url and hash for validation in generateValidProposalFormFields --- .../lib/pages/proposalSubmissionPage.ts | 72 ++++++++++++------- .../proposalSubmission.loggedin.spec.ts | 28 ++++---- 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index f58c4b349..f45f3bbb8 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -10,7 +10,7 @@ import { uploadScriptAndGenerateUrl, } from "@helpers/metadata"; import { extractProposalIdFromUrl } from "@helpers/string"; -import { invalid } from "@mock/index"; +import { invalid, valid } from "@mock/index"; import { Download, Locator, Page, expect } from "@playwright/test"; import metadataBucketService from "@services/metadataBucketService"; import { @@ -366,12 +366,19 @@ export default class ProposalSubmissionPage { await expect(this.continueBtn).toBeDisabled(); } - async generateValidProposalFormFields( - proposalType: ProposalType, - is_draft?: boolean, - receivingAddress?: string, - hasGuardrails: boolean = true - ) { + async generateValidProposalFormFields({ + proposalType, + is_draft, + receivingAddress, + hasGuardrails = true, + forValidation = false, + }: { + proposalType: ProposalType; + is_draft?: boolean; + receivingAddress?: string; + hasGuardrails?: boolean; + forValidation?: boolean; + }) { const proposal: ProposalCreateRequest = { prop_name: faker.lorem.sentence(6), prop_abstract: faker.lorem.words(5), @@ -396,19 +403,28 @@ export default class ProposalSubmissionPage { .toString()); } if (proposalType === ProposalType.updatesToTheConstitution) { - proposal.prop_constitution_url = - environments.metadataBucketUrl + "/data.jsonId"; - - if (proposal.has_guardrails) { - const url = await uploadScriptAndGenerateUrl(guardrailsScript); - proposal.prop_guardrails_script_url = url; - proposal.prop_guardrails_script_hash = guardrailsScriptHash; + proposal.prop_constitution_url = forValidation + ? valid.url() + : environments.metadataBucketUrl + "/data.jsonId"; + + if (hasGuardrails) { + if (!forValidation) { + const url = await uploadScriptAndGenerateUrl(guardrailsScript); + proposal.prop_guardrails_script_url = url; + proposal.prop_guardrails_script_hash = guardrailsScriptHash; + } else { + proposal.prop_guardrails_script_url = valid.url(); + proposal.prop_guardrails_script_hash = faker.string.alphanumeric(64); + } } } return proposal; } - generateInValidProposalFormFields(proposalType: ProposalType) { + generateInValidProposalFormFields( + proposalType: ProposalType, + hasGuardrails: boolean = true + ) { const proposal: ProposalCreateRequest = { prop_name: invalid.proposalTitle(), prop_abstract: invalid.paragraph(2510), @@ -422,6 +438,7 @@ export default class ProposalSubmissionPage { }, ], gov_action_type_id: Object.values(ProposalType).indexOf(proposalType), + has_guardrails: hasGuardrails, is_draft: false, }; @@ -450,11 +467,12 @@ export default class ProposalSubmissionPage { ); const proposalRequest: ProposalCreateRequest = - await this.generateValidProposalFormFields( - (await isBootStrapingPhase()) ? ProposalType.info : proposalType, - false, - receivingAddr - ); + await this.generateValidProposalFormFields({ + proposalType: (await isBootStrapingPhase()) + ? ProposalType.info + : proposalType, + receivingAddress: receivingAddr, + }); await this.fillupForm(proposalRequest); await this.continueBtn.click(); await this.submitBtn.click(); @@ -470,13 +488,13 @@ export default class ProposalSubmissionPage { await this.goto(); await this.addLinkBtn.click(); - const proposalFormValue = await this.generateValidProposalFormFields( - proposalType, - true, - ShelleyWallet.fromJson(proposal04Wallet).rewardAddressBech32( - environments.networkId - ) - ); + const proposalFormValue = await this.generateValidProposalFormFields({ + proposalType: proposalType, + is_draft: true, + receivingAddress: ShelleyWallet.fromJson( + proposal04Wallet + ).rewardAddressBech32(environments.networkId), + }); await this.fillupForm(proposalFormValue); await this.saveDraftBtn.click(); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts index a65f06781..daa0270c9 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts @@ -64,11 +64,11 @@ test.describe("Proposal created logged state", () => { await ShelleyWallet.generate() ).rewardAddressBech32(environments.networkId); const formFields: ProposalCreateRequest = - await proposalSubmissionPage.generateValidProposalFormFields( - type, - false, - rewardAddressBech32 - ); + await proposalSubmissionPage.generateValidProposalFormFields({ + proposalType: type, + receivingAddress: rewardAddressBech32, + forValidation: true, + }); await proposalSubmissionPage.validateForm(formFields); } @@ -141,11 +141,10 @@ test.describe("Proposal created logged state", () => { wallet ).rewardAddressBech32(environments.networkId); const proposal: ProposalCreateRequest = - await proposalSubmissionPage.generateValidProposalFormFields( - type, - false, - stakeAddressBech32 - ); + await proposalSubmissionPage.generateValidProposalFormFields({ + proposalType: type, + receivingAddress: stakeAddressBech32, + }); await proposalSubmissionPage.fillupForm(proposal); await proposalSubmissionPage.continueBtn.click(); @@ -195,11 +194,10 @@ test.describe("Proposal created logged state", () => { proposal01Wallet ).rewardAddressBech32(environments.networkId); const proposal: ProposalCreateRequest = - await proposalSubmissionPage.generateValidProposalFormFields( - type, - false, - rewardAddressBech32 - ); + await proposalSubmissionPage.generateValidProposalFormFields({ + proposalType: type, + receivingAddress: rewardAddressBech32, + }); await proposalSubmissionPage.fillupForm(proposal); await proposalSubmissionPage.continueBtn.click(); From 8b53e3038187fafae545ddc73041be3960d9f172 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 14:34:03 +0545 Subject: [PATCH 13/61] refactor: replace hardcoded proposal type filters with dynamic values from ProposalType --- tests/govtool-frontend/playwright/lib/constants/index.ts | 5 ----- .../playwright/lib/pages/proposalDiscussionPage.ts | 5 ++--- .../tests/8-proposal-discussion/proposalDiscussion.spec.ts | 5 +++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/constants/index.ts b/tests/govtool-frontend/playwright/lib/constants/index.ts index f403d28b8..b8ab0f1da 100644 --- a/tests/govtool-frontend/playwright/lib/constants/index.ts +++ b/tests/govtool-frontend/playwright/lib/constants/index.ts @@ -11,11 +11,6 @@ export const SECURITY_RELEVANT_PARAMS_MAP: Record = { minFeeRefScriptCostPerByte: "min_fee_ref_script_cost_per_byte", }; -export const PROPOSAL_TYPE_FILTERS = [ - "Info Action", - "Treasury requests", - "Updates to the Constitution", -]; export const BOOTSTRAP_PROPOSAL_TYPE_FILTERS = ["Info Action"]; export const PROPOSAL_STATUS_FILTER = ["Submitted for vote", "Active proposal"]; diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts index 4234f1b67..9aac21e18 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts @@ -1,8 +1,7 @@ import { expect, Locator, Page } from "@playwright/test"; -import { ProposalCreateRequest, ProposedGovAction } from "@types"; +import { ProposalCreateRequest, ProposalType, ProposedGovAction } from "@types"; import environments from "lib/constants/environments"; import ProposalDiscussionDetailsPage from "./proposalDiscussionDetailsPage"; -import { PROPOSAL_TYPE_FILTERS } from "@constants/index"; export default class ProposalDiscussionPage { // Buttons @@ -111,7 +110,7 @@ export default class ProposalDiscussionPage { async clickRadioButtonsByNames(names: string[]) { for (const name of names) { - const testId = PROPOSAL_TYPE_FILTERS.includes(name) + const testId = Object.values(ProposalType).includes(name as ProposalType) ? name.toLowerCase() : name.toLowerCase().replace(/ /g, "-"); await this.page.getByTestId(`${testId}-radio`).click(); diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 32dd3c618..82017853a 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -2,7 +2,6 @@ import environments from "@constants/environments"; import { BOOTSTRAP_PROPOSAL_TYPE_FILTERS, PROPOSAL_STATUS_FILTER, - PROPOSAL_TYPE_FILTERS, } from "@constants/index"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/proposal"; @@ -50,7 +49,9 @@ test.describe("Filter and sort proposals", () => { // proposal type filter await proposalDiscussionPage.applyAndValidateFilters( - isBootStraping ? BOOTSTRAP_PROPOSAL_TYPE_FILTERS : PROPOSAL_TYPE_FILTERS, + isBootStraping + ? BOOTSTRAP_PROPOSAL_TYPE_FILTERS + : Object.values(ProposalType), proposalDiscussionPage._validateTypeFiltersInProposalCard ); From 1449fedaf281f8eae8bf36dd665c9c7b877f92a3 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 14:35:17 +0545 Subject: [PATCH 14/61] feat: add and handle motionOfNoConfidence type proposal --- .../playwright/lib/pages/proposalSubmissionPage.ts | 7 ++++++- tests/govtool-frontend/playwright/lib/types.ts | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index f45f3bbb8..1f8b2212d 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -58,6 +58,9 @@ export default class ProposalSubmissionPage { readonly updateTheConstitutionBtn = this.page.getByTestId( "updates to the constitution-button" ); + readonly motionOfNoConfidenceBtn = this.page.getByTestId( + "motion of no confidence-button" + ); readonly editSubmissionButton = this.page.getByTestId( "edit-submission-button" ); @@ -174,11 +177,13 @@ export default class ProposalSubmissionPage { await this.infoBtn.click(); } else if (governanceProposal.gov_action_type_id === 1) { await this.treasuryBtn.click(); - } else { + } else if (governanceProposal.gov_action_type_id === 2) { await this.updateTheConstitutionBtn.click(); if (governanceProposal.has_guardrails) { await this.guardrailsScriptCheckbox.click(); } + } else { + await this.motionOfNoConfidenceBtn.click(); } await this.fillupFormWithTypeSelected(governanceProposal); diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 71c50c4fb..b4c439ced 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -73,6 +73,7 @@ export enum ProposalType { info = "Info Action", treasury = "Treasury requests", updatesToTheConstitution = "Updates to the Constitution", + motionOfNoConfedence = "Motion of No Confidence", } export enum BootstrapGovernanceActionType { From 08c26fc80ce9e8ac5892371ac0e6768247de11ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 14 Feb 2025 13:56:11 +0100 Subject: [PATCH 15/61] feat(#2993): allow searching for yourself in DRep directory --- CHANGELOG.md | 1 + .../src/pages/DRepDirectoryContent.tsx | 29 ++++++------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 805838873..af0b046f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ changes. - Add workflow to automatically update any of the @intersect.mbo package [Issue 2968](https://github.com/IntersectMBO/govtool/issues/2968) - Add Propose Governance Action button in governance actions dashboard [Issue 1188](https://github.com/IntersectMBO/govtool/issues/1188) - Add click handlers to non-interactive elements [Issue 2929](https://github.com/IntersectMBO/govtool/issues/2929) +- Allow searching for yourself in DRep Directory [Issue 2993](https://github.com/IntersectMBO/govtool/issues/2993) ### Fixed diff --git a/govtool/frontend/src/pages/DRepDirectoryContent.tsx b/govtool/frontend/src/pages/DRepDirectoryContent.tsx index 7bcc2199d..36e55ae94 100644 --- a/govtool/frontend/src/pages/DRepDirectoryContent.tsx +++ b/govtool/frontend/src/pages/DRepDirectoryContent.tsx @@ -67,12 +67,6 @@ export const DRepDirectoryContent: FC = ({ enabled: !!inProgressDelegation || !!currentDelegation, }); - const { dRep: yourselfDRep } = useGetDRepDetailsQuery(myDRepId, { - enabled: !!inProgressDelegation || !!currentDelegation, - }); - const showYourselfDRep = - debouncedSearchText === myDRepId || debouncedSearchText === ""; - const { dRepData: dRepList, isPreviousData, @@ -106,21 +100,16 @@ export const DRepDirectoryContent: FC = ({ const ada = correctAdaFormat(votingPower); - const listedDRepsWithoutYourself = uniqBy( - dRepList?.filter( - (dRep) => - (typeof dRep.doNotList === "string" - ? !parseBoolean(dRep.doNotList) - : !dRep.doNotList) && !isSameDRep(dRep, myDRepId), - ), + const filteredDoNotListDReps = uniqBy( + dRepList?.filter((dRep) => { + if (typeof dRep.doNotList === "string") { + return !parseBoolean(dRep.doNotList); + } + return !dRep.doNotList; + }), "view", ); - const dRepListToDisplay = - yourselfDRep && showYourselfDRep - ? [yourselfDRep, ...listedDRepsWithoutYourself] - : listedDRepsWithoutYourself; - const isAnAutomatedVotingOptionChosen = currentDelegation?.dRepView && (currentDelegation?.dRepView === @@ -217,8 +206,8 @@ export const DRepDirectoryContent: FC = ({ flex: 1, }} > - {dRepListToDisplay?.length === 0 && } - {dRepListToDisplay?.map((dRep) => ( + {filteredDoNotListDReps?.length === 0 && } + {filteredDoNotListDReps?.map((dRep) => ( Date: Mon, 17 Feb 2025 16:14:27 +0100 Subject: [PATCH 16/61] fix(#2994): fix refetching the drep directory --- CHANGELOG.md | 1 + .../components/molecules/DataActionsBar.tsx | 116 ++++++------ .../organisms/DashboardGovernanceActions.tsx | 2 +- .../GovernanceActionDetailsCardData.tsx | 3 +- .../hooks/queries/useGetDrepDetailsQuery.ts | 7 +- govtool/frontend/src/main.tsx | 9 +- govtool/frontend/yarn.lock | 174 +++++++++++++++++- 7 files changed, 246 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af0b046f9..1d0d26fce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ changes. - Fix crashing backend on unhandled missing proposal from vote [Issue 2920](https://github.com/IntersectMBO/govtool/issues/2920) - Remove abstain votes (not auto abstain) from total DRep stake - Fix counting committee members [Issue 2948](https://github.com/IntersectMBO/govtool/issues/2948) +- Fix refetching DRep list on every enter [Issue 2994](https://github.com/IntersectMBO/govtool/issues/2994) ### Changed diff --git a/govtool/frontend/src/components/molecules/DataActionsBar.tsx b/govtool/frontend/src/components/molecules/DataActionsBar.tsx index c2839ae78..223fef97e 100644 --- a/govtool/frontend/src/components/molecules/DataActionsBar.tsx +++ b/govtool/frontend/src/components/molecules/DataActionsBar.tsx @@ -57,64 +57,62 @@ export const DataActionsBar: FC = ({ ...props }) => { } = theme; return ( - <> - - setSearchText(e.target.value)} - placeholder="Search..." - value={searchText} - startAdornment={ - - } - sx={{ - bgcolor: "white", - border: 1, - borderColor: "secondaryBlue", - borderRadius: 50, - boxShadow: `2px 2px 20px 0px ${boxShadow2}`, - fontSize: 11, - fontWeight: 500, - height: 48, - padding: "16px 24px", - maxWidth: 500, - }} - /> - - {filtersOpen && ( - - )} - {sortOpen && ( - - )} - - - + + setSearchText(e.target.value)} + placeholder="Search..." + value={searchText} + startAdornment={ + + } + sx={{ + bgcolor: "white", + border: 1, + borderColor: "secondaryBlue", + borderRadius: 50, + boxShadow: `2px 2px 20px 0px ${boxShadow2}`, + fontSize: 11, + fontWeight: 500, + height: 48, + padding: "16px 24px", + maxWidth: 500, + }} + /> + + {filtersOpen && ( + + )} + {sortOpen && ( + + )} + + ); }; diff --git a/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx b/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx index 2efc90aa6..6c246b929 100644 --- a/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx +++ b/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx @@ -92,7 +92,7 @@ export const DashboardGovernanceActions = () => { const { state } = useLocation(); const [content, setContent] = useState( - state && state.isVotedListOnLoad ? 1 : 0, + state?.isVotedListOnLoad ? 1 : 0, ); const handleChange = (_event: React.SyntheticEvent, newValue: number) => { diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index 8b9d1048a..2419a77d4 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -42,7 +42,8 @@ type StyledTabProps = { isMobile: boolean; }; -const StyledTab = styled((props: StyledTabProps) => ( +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const StyledTab = styled(({ isMobile, ...props }: StyledTabProps) => ( ))(({ isMobile }) => ({ textTransform: "none", diff --git a/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts b/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts index 9bb53a206..3c99959ff 100644 --- a/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts +++ b/govtool/frontend/src/hooks/queries/useGetDrepDetailsQuery.ts @@ -1,12 +1,15 @@ +import { UseInfiniteQueryOptions } from "react-query"; + +import { Infinite, DRepData } from "@/models"; import { useGetDRepListInfiniteQuery } from "./useGetDRepListQuery"; export const useGetDRepDetailsQuery = ( dRepId: string | null | undefined, - options?: { enabled: boolean }, + options?: UseInfiniteQueryOptions>, ) => { const { dRepData, isDRepListLoading } = useGetDRepListInfiniteQuery( { searchPhrase: dRepId ?? undefined }, - { enabled: options?.enabled || !!dRepId }, + { enabled: options?.enabled || !!dRepId, ...options }, ); return { dRep: dRepData?.[0], isLoading: isDRepListLoading }; diff --git a/govtool/frontend/src/main.tsx b/govtool/frontend/src/main.tsx index 76f6ff419..f9b4a9a7f 100644 --- a/govtool/frontend/src/main.tsx +++ b/govtool/frontend/src/main.tsx @@ -16,7 +16,14 @@ import pkg from "../package.json"; const { version } = pkg; -const queryClient = new QueryClient(); +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + refetchOnMount: false, + }, + }, +}); const tagManagerArgs = { gtmId: import.meta.env.VITE_GTM_ID, diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 50ade3185..57c81b6d4 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -3229,6 +3229,11 @@ resolved "https://registry.npmjs.org/@types/jsonld/-/jsonld-1.5.15.tgz" integrity sha512-PlAFPZjL+AuGYmwlqwKEL0IMP8M8RexH0NIPGfCVWSQ041H2rR/8OlyZSD7KsCVoN8vCfWdtWDBxX8yBVP+xow== +"@types/katex@^0.16.0": + version "0.16.7" + resolved "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz" + integrity sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ== + "@types/lodash@^4.17.0": version "4.17.13" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz" @@ -7479,6 +7484,65 @@ hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: dependencies: function-bind "^1.1.2" +hast-util-from-dom@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz" + integrity sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q== + dependencies: + "@types/hast" "^3.0.0" + hastscript "^9.0.0" + web-namespaces "^2.0.0" + +hast-util-from-html-isomorphic@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz" + integrity sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw== + dependencies: + "@types/hast" "^3.0.0" + hast-util-from-dom "^5.0.0" + hast-util-from-html "^2.0.0" + unist-util-remove-position "^5.0.0" + +hast-util-from-html@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz" + integrity sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw== + dependencies: + "@types/hast" "^3.0.0" + devlop "^1.1.0" + hast-util-from-parse5 "^8.0.0" + parse5 "^7.0.0" + vfile "^6.0.0" + vfile-message "^4.0.0" + +hast-util-from-parse5@^8.0.0: + version "8.0.2" + resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.2.tgz" + integrity sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^9.0.0" + property-information "^6.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + +hast-util-is-element@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz" + integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + hast-util-to-jsx-runtime@^2.0.0: version "2.3.2" resolved "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz" @@ -7500,6 +7564,16 @@ hast-util-to-jsx-runtime@^2.0.0: unist-util-position "^5.0.0" vfile-message "^4.0.0" +hast-util-to-text@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz" + integrity sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + hast-util-is-element "^3.0.0" + unist-util-find-after "^5.0.0" + hast-util-whitespace@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz" @@ -7512,6 +7586,17 @@ hast-util-whitespace@^3.0.0: dependencies: "@types/hast" "^3.0.0" +hastscript@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-9.0.0.tgz" + integrity sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + he@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" @@ -9464,6 +9549,13 @@ jsonpointer@^5.0.0: object.assign "^4.1.4" object.values "^1.1.6" +katex@^0.16.0, katex@^0.16.21: + version "0.16.21" + resolved "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz" + integrity sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A== + dependencies: + commander "^8.3.0" + keen-slider@^6.8.5: version "6.8.6" resolved "https://registry.npmjs.org/keen-slider/-/keen-slider-6.8.6.tgz" @@ -9845,6 +9937,19 @@ mdast-util-from-markdown@^2.0.0: micromark-util-types "^2.0.0" unist-util-stringify-position "^4.0.0" +mdast-util-math@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz" + integrity sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + longest-streak "^3.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.1.0" + unist-util-remove-position "^5.0.0" + mdast-util-mdx-expression@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz" @@ -9924,7 +10029,7 @@ mdast-util-to-hast@^13.0.0: unist-util-visit "^5.0.0" vfile "^6.0.0" -mdast-util-to-markdown@^2.0.0: +mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz" integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA== @@ -10063,6 +10168,19 @@ micromark-core-commonmark@^2.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" +micromark-extension-math@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz" + integrity sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg== + dependencies: + "@types/katex" "^0.16.0" + devlop "^1.0.0" + katex "^0.16.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromark-factory-destination@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz" @@ -11069,7 +11187,7 @@ parse-passwd@^1.0.0: resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz" integrity sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q== -parse5@^7.1.2: +parse5@^7.0.0, parse5@^7.1.2: version "7.2.1" resolved "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz" integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ== @@ -12453,6 +12571,19 @@ regjsparser@^0.12.0: dependencies: jsesc "~3.0.2" +rehype-katex@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz" + integrity sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA== + dependencies: + "@types/hast" "^3.0.0" + "@types/katex" "^0.16.0" + hast-util-from-html-isomorphic "^2.0.0" + hast-util-to-text "^4.0.0" + katex "^0.16.0" + unist-util-visit-parents "^6.0.0" + vfile "^6.0.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz" @@ -12465,6 +12596,16 @@ release-zalgo@^1.0.0: dependencies: es6-error "^4.0.1" +remark-math@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz" + integrity sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-math "^3.0.0" + micromark-extension-math "^3.0.0" + unified "^11.0.0" + remark-parse@^10.0.0: version "10.0.2" resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz" @@ -14170,6 +14311,14 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" +unist-util-find-after@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz" + integrity sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-generated@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz" @@ -14203,6 +14352,14 @@ unist-util-position@^5.0.0: dependencies: "@types/unist" "^3.0.0" +unist-util-remove-position@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz" + integrity sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q== + dependencies: + "@types/unist" "^3.0.0" + unist-util-visit "^5.0.0" + unist-util-stringify-position@^3.0.0: version "3.0.3" resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz" @@ -14399,6 +14556,14 @@ vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vfile-location@^5.0.0: + version "5.0.3" + resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz" + integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== + dependencies: + "@types/unist" "^3.0.0" + vfile "^6.0.0" + vfile-message@^3.0.0: version "3.1.4" resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz" @@ -14577,6 +14742,11 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== + web-streams-polyfill@^3.0.3, web-streams-polyfill@>=3.2.1: version "3.3.3" resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz" From eb06b426ff8c6aaf9a3fa62a5cc8a0655cde8b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 17 Feb 2025 14:09:56 +0100 Subject: [PATCH 17/61] feat(#2984): add mathematical styling inside governance action metadata --- CHANGELOG.md | 1 + govtool/frontend/package-lock.json | 289 +++++++++++++++++- govtool/frontend/package.json | 3 + .../molecules/GovernanceActionCardElement.tsx | 12 +- 4 files changed, 302 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d0d26fce..59852d38c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ changes. - Add Propose Governance Action button in governance actions dashboard [Issue 1188](https://github.com/IntersectMBO/govtool/issues/1188) - Add click handlers to non-interactive elements [Issue 2929](https://github.com/IntersectMBO/govtool/issues/2929) - Allow searching for yourself in DRep Directory [Issue 2993](https://github.com/IntersectMBO/govtool/issues/2993) +- Add mathematical styling for governance actions [Issue 2984](https://github.com/IntersectMBO/govtool/issues/2984) ### Fixed diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 092c843ad..3b0f0a5cf 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -30,6 +30,7 @@ "esbuild": "^0.24.0", "i18next": "^23.7.19", "jsonld": "^8.3.2", + "katex": "^0.16.21", "keen-slider": "^6.8.5", "patch-package": "^8.0.0", "react": "^18.2.0", @@ -41,6 +42,8 @@ "react-markdown": "^9.0.1", "react-query": "^3.39.3", "react-router-dom": "^6.13.0", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "storybook-addon-manual-mocks": "^1.0.3", "storybook-addon-module-mock": "^1.3.4", "unidiff": "^1.0.4", @@ -7844,6 +7847,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "license": "MIT" + }, "node_modules/@types/lodash": { "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.13.tgz", @@ -16409,6 +16418,101 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.1.tgz", + "integrity": "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==", + "license": "ISC", + "dependencies": { + "@types/hast": "^3.0.0", + "hastscript": "^9.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.2.tgz", + "integrity": "sha512-SfMzfdAi/zAoZ1KkFEyyeXBn7u/ShQrfd675ZEE9M3qj+PMFX05xubzRyF76CCSJu8au9jgVxDV1+okFvgZU4A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", @@ -16436,6 +16540,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -16449,6 +16569,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.0.tgz", + "integrity": "sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -20321,6 +20458,31 @@ "node": ">=4.0" } }, + "node_modules/katex": { + "version": "0.16.21", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz", + "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keen-slider": { "version": "6.8.6", "resolved": "https://registry.npmjs.org/keen-slider/-/keen-slider-6.8.6.tgz", @@ -20811,6 +20973,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", @@ -21117,6 +21298,25 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -22679,7 +22879,6 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", - "dev": true, "license": "MIT", "dependencies": { "entities": "^4.5.0" @@ -22692,7 +22891,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -27021,6 +27219,25 @@ "regjsparser": "bin/parser" } }, + "node_modules/rehype-katex": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -27044,6 +27261,22 @@ "node": ">=4" } }, + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -29972,6 +30205,20 @@ "node": ">=8" } }, + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-generated": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", @@ -30008,6 +30255,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", @@ -30292,6 +30553,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -31741,6 +32016,16 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index e4054d741..8c83d4b1b 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -44,6 +44,7 @@ "esbuild": "^0.24.0", "i18next": "^23.7.19", "jsonld": "^8.3.2", + "katex": "^0.16.21", "keen-slider": "^6.8.5", "patch-package": "^8.0.0", "react": "^18.2.0", @@ -55,6 +56,8 @@ "react-markdown": "^9.0.1", "react-query": "^3.39.3", "react-router-dom": "^6.13.0", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "storybook-addon-manual-mocks": "^1.0.3", "storybook-addon-module-mock": "^1.3.4", "unidiff": "^1.0.4", diff --git a/govtool/frontend/src/components/molecules/GovernanceActionCardElement.tsx b/govtool/frontend/src/components/molecules/GovernanceActionCardElement.tsx index d32961128..a0900abe7 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionCardElement.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionCardElement.tsx @@ -2,6 +2,10 @@ import { PropsWithChildren } from "react"; import { Box } from "@mui/material"; import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; import Markdown from "react-markdown"; +import remarkMath from "remark-math"; +import rehypeKatex from "rehype-katex"; +import "katex/dist/katex.min.css"; + import { Typography, Tooltip, CopyButton, TooltipProps } from "@atoms"; import { removeMarkdown } from "@/utils"; import { ICONS } from "@/consts"; @@ -125,7 +129,13 @@ export const GovernanceActionCardElement = ({ }; const renderMarkdown = () => ( - {text.toString()} + + {text.toString()} + ); const renderCopyButton = () => From 17a882be0b4ab2fc41b87a8d93c6ec316c16bce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 18 Feb 2025 09:31:52 +0100 Subject: [PATCH 18/61] chore: add script to update GovTool version --- .github/workflows/update-govtool-version.yml | 102 +++++++++++++++++++ CHANGELOG.md | 1 + 2 files changed, 103 insertions(+) create mode 100644 .github/workflows/update-govtool-version.yml diff --git a/.github/workflows/update-govtool-version.yml b/.github/workflows/update-govtool-version.yml new file mode 100644 index 000000000..0ee75e94f --- /dev/null +++ b/.github/workflows/update-govtool-version.yml @@ -0,0 +1,102 @@ +name: Update GovTool Version and Changelog + +on: + workflow_dispatch: + inputs: + version: + description: "New version (e.g., 1.0.0)" + required: true + +jobs: + update-version: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + registry-url: "https://registry.npmjs.org/" + node-version-file: "./govtool/frontend/.nvmrc" + scope: "@intersect.mbo" + + - name: Set Version Variable + run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + + - name: Update package.json files and install dependencies + run: | + jq --arg v "$VERSION" '.version = $v' govtool/frontend/package.json > temp.json && mv temp.json govtool/frontend/package.json + jq --arg v "$VERSION" '.version = $v' govtool/metadata-validation/package.json > temp.json && mv temp.json govtool/metadata-validation/package.json + + echo "Running npm install to update lock files..." + cd govtool/frontend && npm install && cd ../.. + cd govtool/metadata-validation && npm install && cd ../.. + + - name: Update vva-be.cabal version (Preserve Spacing) + run: | + sed -i -E "s/^(version:[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1$VERSION/" govtool/backend/vva-be.cabal + echo "✅ Updated version in vva-be.cabal while preserving spacing." + + - name: Update Dockerfile Versions + run: | + sed -i -E "s/vva-be-[0-9]+\.[0-9]+\.[0-9]+/vva-be-$VERSION/g" govtool/backend/Dockerfile + sed -i -E "s/vva-be-[0-9]+\.[0-9]+\.[0-9]+/vva-be-$VERSION/g" govtool/backend/Dockerfile.qovery + echo "✅ Updated vva-be version in Dockerfiles." + + - name: Update Metadata Validation API Version + run: | + sed -i -E "s/(\.setVersion\()[\"'][0-9]+\.[0-9]+\.[0-9]+[\"']/\1\"$VERSION\"/" govtool/metadata-validation/main.ts + echo "✅ Updated API version in main.ts" + + - name: Update CHANGELOG.md + run: | + #!/bin/bash + VERSION="${{ github.event.inputs.version }}" + TODAY=$(date +%Y-%m-%d) + RELEASE_TAG="v$VERSION" + RELEASE_LINK="[v$VERSION](https://github.com/IntersectMBO/govtool/releases/tag/$RELEASE_TAG)" + TEMP_FILE=$(mktemp) + + echo "Updating CHANGELOG.md with version $VERSION and date $TODAY..." + + awk -v rl="$RELEASE_LINK" -v td="$TODAY" ' + BEGIN { unreleased_found = 0; print_new_unreleased = 1 } + { + if ($1 == "##" && $2 == "[Unreleased]") { + unreleased_found = 1 + + # Print the new Unreleased section with required sub-sections + print "## [Unreleased]\n" + print "### Added\n" + print "### Fixed\n" + print "### Changed\n" + print "### Removed\n" + + # Rename the old Unreleased section with a version and date + print "## " rl " " td "\n" + next + } + print + }' CHANGELOG.md > "$TEMP_FILE" + + mv "$TEMP_FILE" CHANGELOG.md + + echo "✅ CHANGELOG.md updated successfully!" + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: "chore/update-govtool-to-v${{ github.event.inputs.version }}" + title: "Update GovTool to v${{ github.event.inputs.version }}" + commit-message: "chore: update GovTool to v${{ github.event.inputs.version }}" + body: | + This PR updates GovTool to version `${{ github.event.inputs.version }}`. + + + Workflow executed by `@${{ github.actor }}`. + sign-commits: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 59852d38c..dc3659a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ changes. - Add click handlers to non-interactive elements [Issue 2929](https://github.com/IntersectMBO/govtool/issues/2929) - Allow searching for yourself in DRep Directory [Issue 2993](https://github.com/IntersectMBO/govtool/issues/2993) - Add mathematical styling for governance actions [Issue 2984](https://github.com/IntersectMBO/govtool/issues/2984) +- Add script to update GovTool version ### Fixed From b663ac140e7dc8bb8f82dc4e1fcb8dd0a6f0902f Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 17 Feb 2025 16:45:56 +0545 Subject: [PATCH 19/61] fix: update dRep abstain vote display in governance details page visibility --- .../4-proposal-visibility/proposalVisibility.spec.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts index d5d62692b..4e4a8285c 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts @@ -75,13 +75,19 @@ test("4K. Should display correct vote counts on governance details page for disc `${proposalToCheck.txHash}#${proposalToCheck.index}` ); + const dRepTotalAbstainVote = + await govActionDetailsPage.getDRepTotalAbstainVoted( + proposalToCheck, + metricsResponsePromise + ); + // check dRep votes if (await areDRepVoteTotalsDisplayed(proposalToCheck)) { await expect(govActionDetailsPage.dRepYesVotes).toHaveText( `₳ ${correctVoteAdaFormat(proposalToCheck.dRepYesVotes)}` ); await expect(govActionDetailsPage.dRepAbstainVotes).toHaveText( - `₳ ${correctVoteAdaFormat(proposalToCheck.dRepAbstainVotes)}` + `₳ ${correctVoteAdaFormat(dRepTotalAbstainVote)}` ); await expect(govActionDetailsPage.dRepNoVotes).toHaveText( `₳ ${correctVoteAdaFormat(proposalToCheck.dRepNoVotes)}` From 4baf3f724f929f1a2e3470889106dabfe5690464 Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 13:29:30 +0545 Subject: [PATCH 20/61] feat: add waitedLoop helper function for conditional waiting in tests --- .../playwright/lib/helpers/waitedLoop.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts new file mode 100644 index 000000000..6dc0b4309 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts @@ -0,0 +1,12 @@ +export async function waitedLoop( + conditionFn, + timeout = 60000, + interval = 2000 +) { + const startTime = Date.now(); + while (Date.now() - startTime < timeout) { + if (await conditionFn()) return true; + await new Promise((resolve) => setTimeout(resolve, interval)); + } + return false; +} From 8d6c85fd908202723c61a0a408e3715ce76055ff Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 14:34:43 +0545 Subject: [PATCH 21/61] feat: add functionWaitedAssert for enhanced function execution with timeout and interval --- .../playwright/lib/helpers/waitedLoop.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts index 6dc0b4309..c50e43506 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts @@ -10,3 +10,21 @@ export async function waitedLoop( } return false; } + +export async function functionWaitedAssert(fn, options) { + const { timeout = 60000, interval = 2000, message } = options; + const startTime = Date.now(); + + while (true) { + try { + await fn(); + return true; + } catch (error) { + if (Date.now() - startTime >= timeout) { + const errorMessage = message || error.message; + throw new Error(errorMessage); + } + await new Promise((resolve) => setTimeout(resolve, interval)); + } + } +} From 32f0fd756de04f8a2c254df2484b96f0efc52769 Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 14:46:49 +0545 Subject: [PATCH 22/61] fix: remove timeout and add possible assertion/waited function --- .../playwright/lib/pages/dRepDirectoryPage.ts | 94 +++++++++++-------- .../lib/pages/governanceActionsPage.ts | 10 +- .../lib/pages/proposalDiscussionPage.ts | 40 ++++---- .../lib/pages/proposalSubmissionPage.ts | 6 +- .../3-drep-registration/editDRep.dRep.spec.ts | 2 +- .../miscellaneous.dRep.spec.ts | 5 +- 6 files changed, 94 insertions(+), 63 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 0d2a28be2..9b54982a0 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -1,4 +1,5 @@ import { convertDRepToCIP129 } from "@helpers/dRep"; +import { functionWaitedAssert, waitedLoop } from "@helpers/waitedLoop"; import { Locator, Page, expect } from "@playwright/test"; import { IDRep } from "@types"; import environments from "lib/constants/environments"; @@ -75,22 +76,35 @@ export default class DRepDirectoryPage { } async validateFilters(filters: string[], filterOptions: string[]) { - const excludedFilters = filterOptions.filter( - (filter) => !filters.includes(filter) + let errorMessage = ""; + await functionWaitedAssert( + async () => { + const excludedFilters = filterOptions.filter( + (filter) => !filters.includes(filter) + ); + + const dRepList = await this.getAllListedDReps(); + + for (const filter of excludedFilters) { + await expect(this.page.getByTestId(`${filter}-checkbox`)).toHaveCount( + 1 + ); + } + + for (const dRep of dRepList) { + const hasFilter = await this._validateTypeFiltersInDRep( + dRep, + filters + ); + const actualFilter = await dRep + .locator('[data-testid$="-pill"]') + .textContent(); + errorMessage = `${actualFilter} does not match any of the ${filters}`; + expect(hasFilter).toBe(true); + } + }, + { message: errorMessage } ); - - await this.page.waitForTimeout(4_000); // wait for the dRep list to render properly - - const dRepList = await this.getAllListedDReps(); - - for (const filter of excludedFilters) { - await expect(this.page.getByTestId(`${filter}-checkbox`)).toHaveCount(1); - } - - for (const dRep of dRepList) { - const hasFilter = await this._validateTypeFiltersInDRep(dRep, filters); - expect(hasFilter).toBe(true); - } } async _validateTypeFiltersInDRep( @@ -128,7 +142,6 @@ export default class DRepDirectoryPage { const isValid = validationFn(dRepList[i], dRepList[i + 1]); expect(isValid).toBe(true); } - // Frontend validation const cip105DRepListFE = await this.getAllListedCIP105DRepIds(); const cip129DRepListFE = await this.getAllListedCIP129DRepIds(); @@ -138,9 +151,9 @@ export default class DRepDirectoryPage { ); for (let i = 0; i <= cip105DRepListFE.length - 1; i++) { - await expect(cip105DRepListFE[i]).toHaveText(dRepList[i].view); - await expect(cip129DRepListFE[i]).toHaveText( - `(CIP-129) ${cip129DRepListApi[i]}` + await expect(cip129DRepListFE[i]).toHaveText(cip129DRepListApi[i]); + await expect(cip105DRepListFE[i]).toHaveText( + `(CIP-105) ${dRepList[i].view}` ); } } @@ -149,35 +162,44 @@ export default class DRepDirectoryPage { } async getAllListedCIP105DRepIds() { - await this.page.waitForTimeout(2_000); - const dRepCards = await this.getAllListedDReps(); return dRepCards.map((dRep) => - dRep.locator('[data-testid$="-copy-id-button"]').first() + dRep.locator('[data-testid$="-copy-id-button"]').last() ); } async getAllListedCIP129DRepIds() { - await this.page.waitForTimeout(2_000); - const dRepCards = await this.getAllListedDReps(); return dRepCards.map((dRep) => - dRep.locator('[data-testid$="-copy-id-button"]').last() + dRep.locator('[data-testid$="-copy-id-button"]').first() ); } async getAllListedDReps() { - // wait for the dRep list to render properly - await this.page.waitForTimeout(3_000); - // add assertion to wait until the search input is visible await expect(this.searchInput).toBeVisible({ timeout: 10_000 }); - return await this.page - .getByRole("list") - .locator('[data-testid$="-drep-card"]') - .all(); + await waitedLoop(async () => { + return ( + (await this.page.locator('[data-testid$="-drep-card"]').count()) > 0 + ); + }); + + return this.page.locator('[data-testid$="-drep-card"]').all(); + } + async getDRepListFromApi( + option: string, + pageNumber: number = 0 + ): Promise { + const responsePromise = this.page.waitForResponse((response) => + response + .url() + .includes(`api/drep/list?page=${pageNumber}&pageSize=10&sort=${option}`) + ); + const response = await responsePromise; + const json = await response.json(); + return json.elements; } async verifyDRepInList(dRepId: string) { @@ -185,10 +207,8 @@ export default class DRepDirectoryPage { await this.searchInput.fill(dRepId); - await this.page.waitForTimeout(5_000); // wait until the dRep list render properly - - await expect( - this.page.getByTestId(`${dRepId}-drep-card`) - ).not.toBeVisible(); + await expect(this.page.getByText("No DReps found")).toBeVisible({ + timeout: 20_000, + }); } } diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts index 4e3a89a97..8491c0143 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts @@ -4,6 +4,7 @@ import { GovernanceActionType, IProposal } from "@types"; import environments from "lib/constants/environments"; import GovernanceActionDetailsPage from "./governanceActionDetailsPage"; import { getEnumKeyByValue } from "@helpers/enum"; +import { waitedLoop } from "@helpers/waitedLoop"; const MAX_SLIDES_DISPLAY_PER_TYPE = 6; @@ -94,8 +95,13 @@ export default class GovernanceActionsPage { } } - async getAllProposals() { - await this.page.waitForTimeout(4_000); // waits for proposals to render + async getAllProposals(): Promise { + await waitedLoop(async () => { + return ( + (await this.page.locator('[data-testid$="-card"]').count()) > 0 || + this.page.getByText("No results for the search.") + ); + }); return this.page.locator('[data-testid$="-card"]').all(); } diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts index 9aac21e18..e967e8809 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts @@ -2,6 +2,7 @@ import { expect, Locator, Page } from "@playwright/test"; import { ProposalCreateRequest, ProposalType, ProposedGovAction } from "@types"; import environments from "lib/constants/environments"; import ProposalDiscussionDetailsPage from "./proposalDiscussionDetailsPage"; +import { functionWaitedAssert, waitedLoop } from "@helpers/waitedLoop"; export default class ProposalDiscussionPage { // Buttons @@ -31,15 +32,6 @@ export default class ProposalDiscussionPage { await this.page.waitForTimeout(2_000); } - async closeUsernamePrompt() { - await this.page.waitForTimeout(5_000); - await this.page - .locator("div") - .filter({ hasText: /^Hey, setup your username$/ }) - .getByRole("button") - .click(); - } - async viewFirstProposal(): Promise { await this.page .locator('[data-testid^="proposal-"][data-testid$="-view-details"]') @@ -49,7 +41,13 @@ export default class ProposalDiscussionPage { } async getAllProposals() { - await this.page.waitForTimeout(4_000); // waits for proposals to render + await waitedLoop(async () => { + return ( + (await this.page + .locator('[data-testid^="proposal-"][data-testid$="-card"]') + .count()) > 0 + ); + }); return this.page .locator('[data-testid^="proposal-"][data-testid$="-card"]') @@ -129,12 +127,22 @@ export default class ProposalDiscussionPage { filters: string[], validateFunction: (proposalCard: any, filters: string[]) => Promise ) { - const proposalCards = await this.getAllProposals(); - - for (const proposalCard of proposalCards) { - const hasFilter = await validateFunction(proposalCard, filters); - expect(hasFilter).toBe(true); - } + let errorMessage = ""; + await functionWaitedAssert( + async () => { + const proposalCards = await this.getAllProposals(); + + for (const proposalCard of proposalCards) { + const type = await proposalCard + .getByTestId("governance-action-type") + .textContent(); + const hasFilter = await validateFunction(proposalCard, filters); + errorMessage = `A governance action type ${type} does not contain on ${filters}`; + expect(hasFilter).toBe(true); + } + }, + { message: errorMessage } + ); } async sortAndValidate( diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 1f8b2212d..d814dd4b2 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -129,8 +129,6 @@ export default class ProposalSubmissionPage { async goto() { await this.page.goto(`${environments.frontendUrl}/proposal_discussion`); - await this.page.waitForTimeout(2_000); // wait until page load properly - await this.verifyIdentityBtn.click(); await this.proposalCreateBtn.click(); @@ -482,9 +480,7 @@ export default class ProposalSubmissionPage { await this.continueBtn.click(); await this.submitBtn.click(); - // Wait for redirection to `proposal-discussion-details` page - await this.page.waitForTimeout(2_000); - + await expect(this.page.getByTestId("submit-as-GA-button")).toBeVisible(); const currentPageUrl = this.page.url(); return extractProposalIdFromUrl(currentPageUrl); } diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts index 8461dc838..803da619f 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts @@ -73,7 +73,7 @@ test.describe("Validation of edit dRep Form", () => { const editDRepPage = new EditDRepPage(page); await editDRepPage.goto(); - await page.waitForTimeout(3_000); // wait until dRep information load properly + await expect(editDRepPage.nameInput).toBeVisible({ timeout: 20_000 }); // assert to wait for the page to load for (let i = 0; i < 100; i++) { await editDRepPage.inValidateForm({ diff --git a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts index cc299875e..d0d41df40 100644 --- a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts @@ -19,7 +19,8 @@ test.use({ test("6H. Should restrict dRep registration for dRep", async ({ page }) => { await page.goto(`${environments.frontendUrl}/register_drep`); - await page.waitForTimeout(2_000); - + await expect(page.getByText("You already are a DRep")).toBeVisible({ + timeout: 20_000, + }); await expect(page.getByTestId("name-input")).not.toBeVisible(); }); From 912a7fb46a921476bdcf46ce4ab7c6a2d82f32da Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 14:47:46 +0545 Subject: [PATCH 23/61] fix: check api response on show more test --- .../tests/2-delegation/delegation.spec.ts | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index ec62b3ad1..fe0afe3bd 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -84,20 +84,28 @@ test("2O. Should load more DReps on show more", async ({ page }) => { const dRepDirectory = new DRepDirectoryPage(page); await dRepDirectory.goto(); - const dRepIdsBefore = await dRepDirectory.getAllListedCIP105DRepIds(); - await dRepDirectory.showMoreBtn.click(); + const dRepListBefore = await dRepDirectory.getDRepListFromApi( + SortOption.Random + ); - const dRepIdsAfter = await dRepDirectory.getAllListedCIP105DRepIds(); - expect(dRepIdsAfter.length).toBeGreaterThanOrEqual(dRepIdsBefore.length); + const isShowMoreVisible = dRepListBefore.length >= 10; + await expect(dRepDirectory.showMoreBtn).toBeVisible({ + visible: isShowMoreVisible, + }); - if (dRepIdsAfter.length > dRepIdsBefore.length) { - await expect(dRepDirectory.showMoreBtn).toBeVisible(); - expect(true).toBeTruthy(); - } else { - await expect(dRepDirectory.showMoreBtn).not.toBeVisible(); - } -}); + if (!isShowMoreVisible) return; + await dRepDirectory.showMoreBtn.click(); + const dRepListAfter = await dRepDirectory.getDRepListFromApi( + SortOption.Random, + 1 + ); + + const isShowMoreStillVisible = dRepListAfter.length >= dRepListBefore.length; + await expect(dRepDirectory.showMoreBtn).toBeVisible({ + visible: isShowMoreStillVisible, + }); +}); test("2K_1. Should filter DReps", async ({ page }) => { const dRepFilterOptions: DRepStatus[] = ["Active", "Inactive", "Retired"]; From 5b41ffb4da4d11ff74c99ae84a6e049ca743026a Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 14:48:19 +0545 Subject: [PATCH 24/61] fix: intercept and search intercepted title on test 8C --- .../proposalDiscussion.spec.ts | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 82017853a..9e2e5114f 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -78,10 +78,30 @@ test.describe("Filter and sort proposals", () => { test("8C. Should search the list of proposed governance actions.", async ({ page, }) => { - const proposalName = "Labadie, Stehr and Rosenbaum"; + let proposalName = "Labadie, Stehr and Rosenbaum"; + + await page.route("**/api/proposals?**", async (route) => { + const response = await route.fetch(); + const json = await response.json(); + if ("data" in json && json["data"].length > 0) { + proposalName = + json["data"][json["data"].length - 1]["attributes"]["content"][ + "attributes" + ]["prop_name"]; + } + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(json), + }); + }); + + const responsePromise = page.waitForResponse("**/api/proposals?**"); const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); + await responsePromise; + await proposalDiscussionPage.searchInput.fill(proposalName); const proposalCards = await proposalDiscussionPage.getAllProposals(); From 5dc6631d2d3d36ffda289407a36651b1c6257392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 18 Feb 2025 10:16:11 +0100 Subject: [PATCH 25/61] fix: wrong path to main metadata validation file --- .github/workflows/update-govtool-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-govtool-version.yml b/.github/workflows/update-govtool-version.yml index 0ee75e94f..c7156e268 100644 --- a/.github/workflows/update-govtool-version.yml +++ b/.github/workflows/update-govtool-version.yml @@ -49,7 +49,7 @@ jobs: - name: Update Metadata Validation API Version run: | - sed -i -E "s/(\.setVersion\()[\"'][0-9]+\.[0-9]+\.[0-9]+[\"']/\1\"$VERSION\"/" govtool/metadata-validation/main.ts + sed -i -E "s/(\.setVersion\()[\"'][0-9]+\.[0-9]+\.[0-9]+[\"']/\1\"$VERSION\"/" govtool/metadata-validation/src/main.ts echo "✅ Updated API version in main.ts" - name: Update CHANGELOG.md From 87e039b97d336f0fadcd48f13b6e5eb978fb2e93 Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 15:08:41 +0545 Subject: [PATCH 26/61] fix: integrate functionWaitedAssert for proposal search validation --- .../proposalDiscussion.spec.ts | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 9e2e5114f..1ecb2498f 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -7,6 +7,7 @@ import { faker } from "@faker-js/faker"; import { test } from "@fixtures/proposal"; import { setAllureEpic } from "@helpers/allure"; import { isBootStrapingPhase, skipIfNotHardFork } from "@helpers/cardano"; +import { functionWaitedAssert } from "@helpers/waitedLoop"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; import { expect } from "@playwright/test"; @@ -79,15 +80,18 @@ test("8C. Should search the list of proposed governance actions.", async ({ page, }) => { let proposalName = "Labadie, Stehr and Rosenbaum"; + let proposalNameSet = false; await page.route("**/api/proposals?**", async (route) => { const response = await route.fetch(); const json = await response.json(); - if ("data" in json && json["data"].length > 0) { + if (!proposalNameSet && "data" in json && json["data"].length > 0) { + const randomIndex = Math.floor(Math.random() * json["data"].length); proposalName = - json["data"][json["data"].length - 1]["attributes"]["content"][ - "attributes" - ]["prop_name"]; + json["data"][randomIndex]["attributes"]["content"]["attributes"][ + "prop_name" + ]; + proposalNameSet = true; } await route.fulfill({ status: 200, @@ -104,13 +108,20 @@ test("8C. Should search the list of proposed governance actions.", async ({ await proposalDiscussionPage.searchInput.fill(proposalName); - const proposalCards = await proposalDiscussionPage.getAllProposals(); - - for (const proposalCard of proposalCards) { - await expect( - proposalCard.locator('[data-testid^="proposal-"][data-testid$="-title"]') - ).toHaveText(proposalName); - } + await functionWaitedAssert( + async () => { + const proposalCards = await proposalDiscussionPage.getAllProposals(); + for (const proposalCard of proposalCards) { + const proposalTitle = await proposalCard + .locator('[data-testid^="proposal-"][data-testid$="-title"]') + .innerText(); + expect(proposalTitle).toContain(proposalName); + } + }, + { + message: `A proposal card does not contain the search term ${proposalName}`, + } + ); }); test("8D. Should show the view-all categorized proposed governance actions.", async ({ From d03f7c64ec993f75814241416aa59c0605f53bff Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 15:22:42 +0545 Subject: [PATCH 27/61] fix: replace test 4L visibility checks with functionWaitedAssert --- .../playwright/lib/helpers/waitedLoop.ts | 11 ++++++++-- .../proposalVisibility.loggedin.spec.ts | 20 ++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts index c50e43506..ca2e81800 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts @@ -11,8 +11,15 @@ export async function waitedLoop( return false; } -export async function functionWaitedAssert(fn, options) { - const { timeout = 60000, interval = 2000, message } = options; +export async function functionWaitedAssert( + fn, + options: { timeout?: number; interval?: number; message?: string } = { + timeout: 6000, + interval: 2000, + message: null, + } +) { + const { timeout, interval, message } = options; const startTime = Date.now(); while (true) { diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts index cfcb6a675..c209df88f 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts @@ -5,6 +5,7 @@ import { skipIfNotHardFork } from "@helpers/cardano"; import extractExpiryDateFromText from "@helpers/extractExpiryDateFromText"; import { isMobile, openDrawer } from "@helpers/mobile"; import removeAllSpaces from "@helpers/removeAllSpaces"; +import { functionWaitedAssert } from "@helpers/waitedLoop"; import GovernanceActionsPage from "@pages/governanceActionsPage"; import { expect } from "@playwright/test"; @@ -156,13 +157,18 @@ test("4L. Should search governance actions", async ({ page }) => { await governanceActionPage.searchInput.fill(governanceActionId); - const proposalCards = await governanceActionPage.getAllProposals(); - - for (const proposalCard of proposalCards) { - await expect( - proposalCard.getByTestId(`${governanceActionId}-id`) - ).toBeVisible(); - } + await functionWaitedAssert( + async () => { + const proposalCards = await governanceActionPage.getAllProposals(); + + for (const proposalCard of proposalCards) { + await expect( + proposalCard.getByTestId(`${governanceActionId}-id`) + ).toBeVisible(); + } + }, + { message: `${governanceActionId} not found` } + ); }); test("4M. Should show view-all categorized governance actions", async ({ From 312c0f801de21aacf70ceabd2c35a6b06fd8f11a Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 16:04:04 +0545 Subject: [PATCH 28/61] fix: ensure NoDRepText is visible for invalid DRep Id --- .../playwright/lib/pages/dRepDirectoryPage.ts | 2 ++ .../tests/2-delegation/delegation.loggedin.spec.ts | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 9b54982a0..9381997f1 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -41,6 +41,8 @@ export default class DRepDirectoryPage { '[data-testid$="-delegate-button"]' ); + readonly NoDRepText = this.page.getByText("No DReps found"); + constructor(private readonly page: Page) {} async goto() { diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts index 837c41011..bc5d00c5d 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts @@ -101,12 +101,16 @@ test.describe("DRep dependent tests", () => { test("2I. Should check validity of DRep Id", async () => { await dRepDirectoryPage.searchInput.fill(dRepId); - await expect(dRepDirectoryPage.getDRepCard(dRepId)).toBeVisible(); + await expect(dRepDirectoryPage.getDRepCard(dRepId)).toBeVisible({ + timeout: 20_000, + }); const wallet = await ShelleyWallet.generate(); const invalidDRepId = extractDRepFromWallet(wallet); await dRepDirectoryPage.searchInput.fill(invalidDRepId); + + await expect(dRepDirectoryPage.NoDRepText).toBeVisible(); await expect( dRepDirectoryPage.getDRepCard(invalidDRepId) ).not.toBeVisible(); From dedff47acb8203a01bc38bd910bf63d1e93a7d87 Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 16:17:04 +0545 Subject: [PATCH 29/61] fix: add waitedAssert function on test 2O --- .../playwright/lib/pages/dRepDirectoryPage.ts | 2 +- .../tests/2-delegation/delegation.spec.ts | 41 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 9381997f1..ed463a2f2 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -197,7 +197,7 @@ export default class DRepDirectoryPage { const responsePromise = this.page.waitForResponse((response) => response .url() - .includes(`api/drep/list?page=${pageNumber}&pageSize=10&sort=${option}`) + .includes(`drep/list?page=${pageNumber}&pageSize=10&sort=${option}`) ); const response = await responsePromise; const json = await response.json(); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index fe0afe3bd..ab1b2989a 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -2,9 +2,10 @@ import environments from "@constants/environments"; import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; import { fetchFirstActiveDRepDetails } from "@helpers/dRep"; +import { functionWaitedAssert } from "@helpers/waitedLoop"; import DRepDetailsPage from "@pages/dRepDetailsPage"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; -import { expect, test } from "@playwright/test"; +import { expect, Locator, test } from "@playwright/test"; import { DRepStatus, IDRep } from "@types"; test.beforeEach(async () => { @@ -84,28 +85,38 @@ test("2O. Should load more DReps on show more", async ({ page }) => { const dRepDirectory = new DRepDirectoryPage(page); await dRepDirectory.goto(); - const dRepListBefore = await dRepDirectory.getDRepListFromApi( - SortOption.Random - ); + let dRepIdsBefore: Locator[]; + let dRepIdsAfter: Locator[]; - const isShowMoreVisible = dRepListBefore.length >= 10; - await expect(dRepDirectory.showMoreBtn).toBeVisible({ - visible: isShowMoreVisible, - }); - - if (!isShowMoreVisible) return; + await functionWaitedAssert( + async () => { + dRepIdsBefore = await dRepDirectory.getAllListedCIP105DRepIds(); + await dRepDirectory.showMoreBtn.click(); + }, + { message: "Show more button not visible" } + ); - await dRepDirectory.showMoreBtn.click(); const dRepListAfter = await dRepDirectory.getDRepListFromApi( SortOption.Random, 1 ); - const isShowMoreStillVisible = dRepListAfter.length >= dRepListBefore.length; - await expect(dRepDirectory.showMoreBtn).toBeVisible({ - visible: isShowMoreStillVisible, - }); + await functionWaitedAssert( + async () => { + dRepIdsAfter = await dRepDirectory.getAllListedCIP105DRepIds(); + expect(dRepIdsAfter.length).toBeGreaterThanOrEqual(dRepIdsBefore.length); + }, + { message: "DReps not loaded after clicking show more" } + ); + + if (dRepListAfter.length >= dRepIdsBefore.length) { + await expect(dRepDirectory.showMoreBtn).toBeVisible(); + expect(true).toBeTruthy(); + } else { + await expect(dRepDirectory.showMoreBtn).not.toBeVisible(); + } }); + test("2K_1. Should filter DReps", async ({ page }) => { const dRepFilterOptions: DRepStatus[] = ["Active", "Inactive", "Retired"]; From 9cfdfdab9c2a85c8ff1f4dc06561ad6d1b41f21a Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 19:17:58 +0545 Subject: [PATCH 30/61] feat: add proposal submission wallet setup --- tests/govtool-frontend/playwright/.gitignore | 1 + .../playwright/lib/helpers/shellyWallet.ts | 8 ++++ .../playwright/lib/services/kuberService.ts | 14 ++++-- .../playwright/lib/walletManager.ts | 1 + .../playwright/playwright.config.ts | 8 ++++ .../playwright/tests/dRep.setup.ts | 10 +---- .../playwright/tests/faucet.teardown.ts | 3 ++ .../playwright/tests/proposal.setup.ts | 44 +++++++++++++++++++ 8 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 tests/govtool-frontend/playwright/tests/proposal.setup.ts diff --git a/tests/govtool-frontend/playwright/.gitignore b/tests/govtool-frontend/playwright/.gitignore index 8f2de676e..57e9aea00 100644 --- a/tests/govtool-frontend/playwright/.gitignore +++ b/tests/govtool-frontend/playwright/.gitignore @@ -16,6 +16,7 @@ allure-report/ lib/_mock/registerDRepWallets.json lib/_mock/registeredDRepWallets.json lib/_mock/proposalSubmissionWallets.json +lib/_mock/proposalSubmissionCopyWallets.json lib/_mock/registerDRepCopyWallets.json lib/_mock/registeredDRepCopyWallets.json lib/_mock/wallets.json diff --git a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts index e93062930..5f2ba9eb0 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts @@ -12,3 +12,11 @@ export default function extractDRepFromWallet(wallet: ShelleyWallet) { const dRepIdBech32 = bech32.encode("drep", words); return dRepIdBech32; } + +export async function generateWallets(num: number) { + return await Promise.all( + Array.from({ length: num }, () => + ShelleyWallet.generate().then((wallet) => wallet.json()) + ) + ); +} diff --git a/tests/govtool-frontend/playwright/lib/services/kuberService.ts b/tests/govtool-frontend/playwright/lib/services/kuberService.ts index 1a26b3561..d4bbd06c5 100644 --- a/tests/govtool-frontend/playwright/lib/services/kuberService.ts +++ b/tests/govtool-frontend/playwright/lib/services/kuberService.ts @@ -137,8 +137,12 @@ const kuberService = { }); }, // register stake and outputs 20A - initializeWallets: (wallets: StaticWallet[]) => { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + initializeWallets: ( + wallets: StaticWallet[], + faucetAddress: string = faucetWallet.address, + faucetStakeKey: string = faucetWallet.payment.private + ) => { + const kuber = new Kuber(faucetAddress, faucetStakeKey); const outputs = []; const stakes = []; const certificates = []; @@ -195,9 +199,11 @@ const kuberService = { }, multipleTransferADA: ( - outputs: { address: string; value: string | number }[] + outputs: { address: string; value: string | number }[], + addr = faucetWallet.address, + signingKey = faucetWallet.payment.private ) => { - const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); + const kuber = new Kuber(addr, signingKey); const req = { outputs, }; diff --git a/tests/govtool-frontend/playwright/lib/walletManager.ts b/tests/govtool-frontend/playwright/lib/walletManager.ts index f9558e9e3..7021d9a5f 100644 --- a/tests/govtool-frontend/playwright/lib/walletManager.ts +++ b/tests/govtool-frontend/playwright/lib/walletManager.ts @@ -9,6 +9,7 @@ export type Purpose = | "registerDRep" | "registeredDRep" | "proposalSubmission" + | "proposalSubmissionCopy" | "registerDRepCopy" | "registeredDRepCopy"; diff --git a/tests/govtool-frontend/playwright/playwright.config.ts b/tests/govtool-frontend/playwright/playwright.config.ts index eb4dbe476..4a254fcd7 100644 --- a/tests/govtool-frontend/playwright/playwright.config.ts +++ b/tests/govtool-frontend/playwright/playwright.config.ts @@ -57,6 +57,11 @@ export default defineConfig({ testMatch: "**/dRep.setup.ts", dependencies: environments.ci ? ["faucet setup"] : [], }, + { + name: "proposal setup", + testMatch: "**/proposal.setup.ts", + teardown: environments.ci && "cleanup faucet", + }, { name: "wallet bootstrap", testMatch: "**/wallet.bootstrap.ts", @@ -72,6 +77,9 @@ export default defineConfig({ name: "proposal submission", use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.ga.spec.ts", + dependencies: environments.ci + ? ["proposal setup"] + : [], }, { name: "loggedin (desktop)", diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index 5da1f4f50..b501ff6a1 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -2,8 +2,8 @@ import environments from "@constants/environments"; import { dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; -import { ShelleyWallet } from "@helpers/crypto"; import { uploadMetadataAndGetJsonHash } from "@helpers/metadata"; +import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; import { expect, test as setup } from "@playwright/test"; import kuberService from "@services/kuberService"; @@ -26,14 +26,6 @@ setup.beforeEach(async () => { await skipIfMainnet(); }); -async function generateWallets(num: number) { - return await Promise.all( - Array.from({ length: num }, () => - ShelleyWallet.generate().then((wallet) => wallet.json()) - ) - ); -} - setup("Register DRep of static wallets", async () => { setup.setTimeout(environments.txTimeOut); diff --git a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts index 002e02157..0a7f708e5 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts @@ -20,11 +20,14 @@ cleanup("Refund faucet", async () => { await walletManager.readWallets("registerDRepCopy"); const registeredDRepWallets: StaticWallet[] = await walletManager.readWallets("registeredDRepCopy"); + const proposalSubmissionWallets: StaticWallet[] = + await walletManager.readWallets("proposalSubmissionCopy"); try { const { txId, lockInfo } = await kuberService.mergeUtXos([ ...allStaticWallets, ...registerDRepWallets, ...registeredDRepWallets, + ...proposalSubmissionWallets, ]); await pollTransaction(txId, lockInfo); } catch (err) { diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts new file mode 100644 index 000000000..8b1932129 --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -0,0 +1,44 @@ +import environments from "@constants/environments"; +import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; +import { generateWallets } from "@helpers/shellyWallet"; +import { pollTransaction } from "@helpers/transaction"; +import { test as setup } from "@playwright/test"; +import kuberService from "@services/kuberService"; +import walletManager from "lib/walletManager"; + +const PROPOSAL_WALLETS_COUNT = 4; + +let govActionDeposit: number; + +setup.beforeAll(async () => { + const res = await kuberService.queryProtocolParams(); + govActionDeposit = res.govActionDeposit; +}); + +setup("Setup temporary proposal wallets", async () => { + setup.setTimeout(2 * environments.txTimeOut); + + const proposalWallets = await generateWallets(PROPOSAL_WALLETS_COUNT); + + // initialize wallets + const initializeRes = await kuberService.initializeWallets( + [...proposalWallets], + proposalFaucetWallet.address, + proposalFaucetWallet.payment.private + ); + await pollTransaction(initializeRes.txId, initializeRes.lockInfo); + + const amountOutputs = proposalWallets.map((wallet) => { + return { address: wallet.address, value: govActionDeposit }; + }); + const transferRes = await kuberService.multipleTransferADA( + amountOutputs, + proposalFaucetWallet.address, + proposalFaucetWallet.payment.private + ); + await pollTransaction(transferRes.txId, transferRes.lockInfo); + + // save to file + await walletManager.writeWallets(proposalWallets, "proposalSubmission"); + await walletManager.writeWallets(proposalWallets, "proposalSubmissionCopy"); +}); From e862c35c42c7080d589a789f28dfc075f16e65da Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 18 Feb 2025 19:18:23 +0545 Subject: [PATCH 31/61] fix: use temp proposal wallet to submit the proposal --- .../7-proposal-submission/proposalSubmission.ga.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index 3333a7da2..b04aad6ea 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -10,6 +10,8 @@ import { expect } from "@playwright/test"; import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ProposalType } from "@types"; import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; +import walletManager from "lib/walletManager"; +import { valid } from "@mock/index"; test.beforeEach(async () => { await setAllureEpic("7. Proposal submission"); @@ -24,16 +26,19 @@ Object.values(ProposalType).forEach((proposalType, index) => { }, testInfo) => { test.setTimeout(testInfo.timeout + environments.txTimeOut); - const tempUserAuth = await createTempUserAuth(page, proposalFaucetWallet); + const wallet = await walletManager.popWallet("proposalSubmission"); + + const tempUserAuth = await createTempUserAuth(page, wallet); const userPage = await createNewPageWithWallet(browser, { storageState: tempUserAuth, - wallet: proposalFaucetWallet, + wallet: wallet, }); const proposalDiscussionPage = new ProposalDiscussionPage(userPage); await proposalDiscussionPage.goto(); await proposalDiscussionPage.verifyIdentityBtn.click(); + await proposalDiscussionPage.setUsername(valid.username()); const proposalSubmissionPage = new ProposalSubmissionPage(userPage); await proposalSubmissionPage.proposalCreateBtn.click(); From 953d89399ac3d88f5edfcac1b4079923c1e91cd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 18 Feb 2025 15:29:11 +0100 Subject: [PATCH 32/61] chore: bump actions/cache to v4 across workflows --- .github/workflows/code_check_frontend.yml | 6 +++--- .github/workflows/frontend_sonar_scan.yml | 2 +- .github/workflows/merge.yaml | 2 +- .github/workflows/pr.yaml | 19 +++++++++---------- .../workflows/test_integration_playwright.yml | 10 +++++----- CHANGELOG.md | 1 + 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/code_check_frontend.yml b/.github/workflows/code_check_frontend.yml index a80098736..8e5da2f79 100644 --- a/.github/workflows/code_check_frontend.yml +++ b/.github/workflows/code_check_frontend.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: govtool/frontend/node_modules key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }} @@ -44,7 +44,7 @@ jobs: uses: actions/checkout@v4 - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: govtool/frontend/node_modules key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }} @@ -70,7 +70,7 @@ jobs: uses: actions/checkout@v4 - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: govtool/frontend/node_modules key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }} diff --git a/.github/workflows/frontend_sonar_scan.yml b/.github/workflows/frontend_sonar_scan.yml index 323c83f65..1dcded146 100644 --- a/.github/workflows/frontend_sonar_scan.yml +++ b/.github/workflows/frontend_sonar_scan.yml @@ -17,7 +17,7 @@ jobs: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Cache dependencies - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: govtool/frontend/node_modules key: ${{ runner.os }}-node-${{ hashFiles('govtool/frontend/package-lock.json') }} diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml index 065a39624..3dd137070 100644 --- a/.github/workflows/merge.yaml +++ b/.github/workflows/merge.yaml @@ -102,7 +102,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 2ec98149c..eed67c623 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -74,7 +74,6 @@ jobs: set -o pipefail sudo chmod +x lint.sh && ./lint.sh 2>&1 | tee code_lint_output.txt - - name: Unit tests id: unit_tests run: | @@ -90,7 +89,7 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Cache Docker layers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -127,19 +126,19 @@ jobs: VITE_IPFS_PROJECT_ID=${{ secrets.IPFS_PROJECT_ID }} IPFS_GATEWAY=${{ secrets.IPFS_GATEWAY }} IPFS_PROJECT_ID=${{ secrets.IPFS_PROJECT_ID }} - + - name: Scan Docker image with Dockle id: dockle run: | - wget -q https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz - tar zxf dockle_0.4.14_Linux-64bit.tar.gz - sudo mv dockle /usr/local/bin + wget -q https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz + tar zxf dockle_0.4.14_Linux-64bit.tar.gz + sudo mv dockle /usr/local/bin - dockle --exit-code 1 --exit-level fatal -ak GHC_RELEASE_KEY -ak CABAL_INSTALL_RELEASE_KEY -ak STACK_RELEASE_KEY -ak KEY_SHA512 --format json --input '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar' --output ${{ matrix.workdir }}/dockle_scan_output.json - rm -rf '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar' - cat ${{ matrix.workdir }}/dockle_scan_output.json + dockle --exit-code 1 --exit-level fatal -ak GHC_RELEASE_KEY -ak CABAL_INSTALL_RELEASE_KEY -ak STACK_RELEASE_KEY -ak KEY_SHA512 --format json --input '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar' --output ${{ matrix.workdir }}/dockle_scan_output.json + rm -rf '/tmp/image-${{ matrix.name }}-${{ github.sha }}-pr.tar' + cat ${{ matrix.workdir }}/dockle_scan_output.json - echo "outcome=success" >> $GITHUB_OUTPUT + echo "outcome=success" >> $GITHUB_OUTPUT - name: Create PR comment if: always() diff --git a/.github/workflows/test_integration_playwright.yml b/.github/workflows/test_integration_playwright.yml index cf5e0ed63..bbb9c9052 100644 --- a/.github/workflows/test_integration_playwright.yml +++ b/.github/workflows/test_integration_playwright.yml @@ -31,7 +31,7 @@ on: workflow_run: workflows: ["Build and deploy GovTool test stack"] types: [completed] - + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false @@ -39,7 +39,7 @@ concurrency: jobs: integration-tests: runs-on: ubuntu-latest - if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} + if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} outputs: start_time: ${{ steps.set-pending-status.outputs.timestamp }} status: ${{ steps.run-test.outcome }} @@ -49,7 +49,7 @@ jobs: steps: - uses: actions/checkout@v4 with: - ref: ${{ env.COMMIT_SHA }} + ref: ${{ env.COMMIT_SHA }} - name: Set pending commit status id: set-pending-status run: | @@ -70,7 +70,7 @@ jobs: - name: Cache Playwright browsers id: cache-playwright-browsers - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.cache/ms-playwright @@ -132,7 +132,7 @@ jobs: publish-report: runs-on: ubuntu-latest - if: always() && needs.integration-tests.result != 'skipped' + if: always() && needs.integration-tests.result != 'skipped' needs: integration-tests outputs: report_number: ${{ steps.report-details.outputs.report_number }} diff --git a/CHANGELOG.md b/CHANGELOG.md index dc3659a74..4912b0b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ changes. - Change threshold visual representation in governance action votes - Resize governance action details columns - Update @intersect.mbo/pdf-ui to v0.6.0 +- Bump actions/cache to v4 across workflows ### Removed From bf435f0ab02360ef77ea17323ddbc75566ee8aa7 Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 19 Feb 2025 11:28:42 +0545 Subject: [PATCH 33/61] fix: test-2O add response promise on test start --- .../playwright/lib/pages/dRepDirectoryPage.ts | 13 ------------- .../tests/2-delegation/delegation.spec.ts | 12 ++++++++---- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index ed463a2f2..33bac5e2c 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -190,19 +190,6 @@ export default class DRepDirectoryPage { return this.page.locator('[data-testid$="-drep-card"]').all(); } - async getDRepListFromApi( - option: string, - pageNumber: number = 0 - ): Promise { - const responsePromise = this.page.waitForResponse((response) => - response - .url() - .includes(`drep/list?page=${pageNumber}&pageSize=10&sort=${option}`) - ); - const response = await responsePromise; - const json = await response.json(); - return json.elements; - } async verifyDRepInList(dRepId: string) { await this.goto(); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index ab1b2989a..2ae047e7c 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -82,6 +82,11 @@ test("2K_3. Should sort DReps randomly", async ({ page }) => { }); test("2O. Should load more DReps on show more", async ({ page }) => { + const responsePromise = page.waitForResponse((response) => + response + .url() + .includes(`drep/list?page=1&pageSize=10&sort=${SortOption.Random}`) + ); const dRepDirectory = new DRepDirectoryPage(page); await dRepDirectory.goto(); @@ -96,10 +101,9 @@ test("2O. Should load more DReps on show more", async ({ page }) => { { message: "Show more button not visible" } ); - const dRepListAfter = await dRepDirectory.getDRepListFromApi( - SortOption.Random, - 1 - ); + const response = await responsePromise; + const json = await response.json(); + const dRepListAfter = json.elements; await functionWaitedAssert( async () => { From 2de1cff508baef66ff477bdd0c9877828f9afd2f Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 19 Feb 2025 11:29:28 +0545 Subject: [PATCH 34/61] feat: add failure handling with console messages on logger --- .../lib/helpers/exceptionHandler.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts b/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts index 7410a57c4..7ef564df1 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts @@ -1,4 +1,5 @@ -import { Expect, ExpectMatcherUtils } from "@playwright/test"; +import { Page } from "@playwright/test"; +import { Logger } from "./logger"; export async function expectWithInfo( expectation: () => Promise, @@ -10,3 +11,20 @@ export async function expectWithInfo( throw new Error(errorMessage); } } + +export async function failureWithConsoleMessages(page: Page, fn: Function) { + const consoleMessages: string[] = []; + page.on("console", (msg) => { + if (msg.type() === "error") { + consoleMessages.push(msg.text()); + } + }); + try { + await fn(); + } catch (error) { + Logger.fail( + `Failed: ${error.message}\nConsole messages: ${consoleMessages.join("\n")}` + ); + throw error; + } +} From a6047fe02af9406339067d1ae0c2309f5547fe59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 18 Feb 2025 13:44:54 +0100 Subject: [PATCH 35/61] feat(#2384): add `isStakeKeyRegistered` utility method --- CHANGELOG.md | 1 + govtool/frontend/src/context/wallet.tsx | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4912b0b7e..78579a199 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ changes. - Allow searching for yourself in DRep Directory [Issue 2993](https://github.com/IntersectMBO/govtool/issues/2993) - Add mathematical styling for governance actions [Issue 2984](https://github.com/IntersectMBO/govtool/issues/2984) - Add script to update GovTool version +- Add `isStakeKeyRegistered` for the usage by pillars [Issue 2384](https://github.com/IntersectMBO/govtool/issues/2384) ### Fixed diff --git a/govtool/frontend/src/context/wallet.tsx b/govtool/frontend/src/context/wallet.tsx index dc0a7bf8d..77c3de83a 100644 --- a/govtool/frontend/src/context/wallet.tsx +++ b/govtool/frontend/src/context/wallet.tsx @@ -249,6 +249,7 @@ interface CardanoContextType { ) => Promise; pendingTransaction: PendingTransaction; isPendingTransaction: () => boolean; + isStakeKeyRegistered: () => boolean; buildNewInfoGovernanceAction: ( infoProps: InfoProps, ) => Promise; @@ -347,6 +348,12 @@ const CardanoProvider = (props: Props) => { } }; + /** + * Checks if there are any registered stake keys. + * @returns {boolean} True if there are registered stake keys, false otherwise. + */ + const isStakeKeyRegistered = () => !!registeredStakeKeysListState.length; + const enable = useCallback( async (walletName: string) => { setIsEnableLoading(walletName); @@ -1474,6 +1481,7 @@ const CardanoProvider = (props: Props) => { isEnabled, isMainnet, isPendingTransaction, + isStakeKeyRegistered, pendingTransaction, pubDRepKey, registeredStakeKeysListState, @@ -1507,6 +1515,7 @@ const CardanoProvider = (props: Props) => { isEnabled, isMainnet, isPendingTransaction, + isStakeKeyRegistered, pendingTransaction, pubDRepKey, registeredStakeKeysListState, From eb53a1cb8bf96369d8afa4c40de1a9dfcb4ede78 Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 19 Feb 2025 12:21:58 +0545 Subject: [PATCH 36/61] feat: integrate failure handling with console messages in proposal submission tests --- .../proposalSubmission.ga.spec.ts | 17 ++++++++++------- .../playwright/tests/proposal.setup.ts | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index b04aad6ea..267352c32 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -11,6 +11,7 @@ import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ProposalType } from "@types"; import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; import walletManager from "lib/walletManager"; +import { failureWithConsoleMessages } from "@helpers/exceptionHandler"; import { valid } from "@mock/index"; test.beforeEach(async () => { @@ -56,13 +57,15 @@ Object.values(ProposalType).forEach((proposalType, index) => { await proposalSubmissionPage.fillUpValidMetadata(); - await expect(userPage.getByTestId("ga-submitted-modal-title")).toHaveText( - /governance action submitted!/i, - { - timeout: 20_000, - } - ); + await failureWithConsoleMessages(userPage, async () => { + await expect(userPage.getByTestId("ga-submitted-modal-title")).toHaveText( + /governance action submitted!/i, + { + timeout: 20_000, + } + ); - await waitForTxConfirmation(userPage); + await waitForTxConfirmation(userPage); + }); }); }); diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts index 8b1932129..f8f388b2e 100644 --- a/tests/govtool-frontend/playwright/tests/proposal.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -36,9 +36,9 @@ setup("Setup temporary proposal wallets", async () => { proposalFaucetWallet.address, proposalFaucetWallet.payment.private ); - await pollTransaction(transferRes.txId, transferRes.lockInfo); - // save to file await walletManager.writeWallets(proposalWallets, "proposalSubmission"); await walletManager.writeWallets(proposalWallets, "proposalSubmissionCopy"); + + await pollTransaction(transferRes.txId, transferRes.lockInfo); }); From 8a89f0dc0e6c0c32329239578adaeb6ed1c8299b Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 19 Feb 2025 12:58:02 +0545 Subject: [PATCH 37/61] feat: kept proposal setup on playwright setup epic --- .../govtool-frontend/playwright/tests/proposal.setup.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts index f8f388b2e..74a79d161 100644 --- a/tests/govtool-frontend/playwright/tests/proposal.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -1,5 +1,7 @@ import environments from "@constants/environments"; import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; +import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; import { test as setup } from "@playwright/test"; @@ -15,6 +17,13 @@ setup.beforeAll(async () => { govActionDeposit = res.govActionDeposit; }); +setup.beforeEach(async () => { + await setAllureEpic("Setup"); + await setAllureStory("Proposal"); + await skipIfNotHardFork(); + await skipIfMainnet(); +}); + setup("Setup temporary proposal wallets", async () => { setup.setTimeout(2 * environments.txTimeOut); From 04154081f467da490a53b5803c275e75c038514c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 18 Feb 2025 15:01:13 +0100 Subject: [PATCH 38/61] chore: add server side compression for large assets --- CHANGELOG.md | 1 + govtool/frontend/package-lock.json | 31 ++++++++++++++++++++++++++++++ govtool/frontend/package.json | 1 + govtool/frontend/vite.config.ts | 9 ++++++++- govtool/frontend/yarn.lock | 13 +++++++++++-- 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78579a199..102de5a76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ changes. - Add mathematical styling for governance actions [Issue 2984](https://github.com/IntersectMBO/govtool/issues/2984) - Add script to update GovTool version - Add `isStakeKeyRegistered` for the usage by pillars [Issue 2384](https://github.com/IntersectMBO/govtool/issues/2384) +- Add server side compression for large assets ### Fixed diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 3b0f0a5cf..fddb2be34 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -93,6 +93,7 @@ "storybook": "^8.4.7", "typescript": "^5.0.2", "vite": "^6.0.3", + "vite-plugin-compression": "^0.5.1", "vitest": "^2.1.8" }, "optionalDependencies": { @@ -31166,6 +31167,36 @@ } } }, + "node_modules/vite-plugin-compression": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz", + "integrity": "sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "debug": "^4.3.3", + "fs-extra": "^10.0.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/vite-plugin-compression/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/vite-plugin-istanbul": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/vite-plugin-istanbul/-/vite-plugin-istanbul-3.0.4.tgz", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index 8c83d4b1b..ae4c823c6 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -107,6 +107,7 @@ "storybook": "^8.4.7", "typescript": "^5.0.2", "vite": "^6.0.3", + "vite-plugin-compression": "^0.5.1", "vitest": "^2.1.8" }, "optionalDependencies": { diff --git a/govtool/frontend/vite.config.ts b/govtool/frontend/vite.config.ts index 44543a211..98c3b0151 100644 --- a/govtool/frontend/vite.config.ts +++ b/govtool/frontend/vite.config.ts @@ -1,10 +1,17 @@ import path from "path"; import { defineConfig as defineViteConfig, mergeConfig } from "vite"; import { defineConfig as defineVitestConfig } from "vitest/config"; +import compression from "vite-plugin-compression"; import react from "@vitejs/plugin-react-swc"; const viteConfig = defineViteConfig({ - plugins: [react()], + plugins: [ + react(), + compression({ + algorithm: "brotliCompress", + threshold: 1024 * 10, + }), + ], cacheDir: ".vite", define: { "process.env": {}, diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 57c81b6d4..02fe53adb 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -5676,7 +5676,7 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7, debug@4: +debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.3.7, debug@4: version "4.3.7" resolved "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -14609,6 +14609,15 @@ vite-node@2.1.8: pathe "^1.1.2" vite "^5.0.0" +vite-plugin-compression@^0.5.1: + version "0.5.1" + resolved "https://registry.npmjs.org/vite-plugin-compression/-/vite-plugin-compression-0.5.1.tgz" + integrity sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg== + dependencies: + chalk "^4.1.2" + debug "^4.3.3" + fs-extra "^10.0.0" + vite-plugin-istanbul@^3.0.1: version "3.0.4" resolved "https://registry.npmjs.org/vite-plugin-istanbul/-/vite-plugin-istanbul-3.0.4.tgz" @@ -14619,7 +14628,7 @@ vite-plugin-istanbul@^3.0.1: picocolors "^1.0.0" test-exclude "^6.0.0" -vite@*, "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4 || ^5 || ^6", "vite@^4.0.0 || ^5.0.0 || ^6.0.0", vite@^6.0.0, vite@^6.0.3: +vite@*, "vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^4 || ^5 || ^6", "vite@^4.0.0 || ^5.0.0 || ^6.0.0", vite@^6.0.0, vite@^6.0.3, vite@>=2.0.0: version "6.0.11" resolved "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz" integrity sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg== From 07cfcf31d2202ab093513dba2caa16014a9e1c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 19 Feb 2025 13:28:54 +0100 Subject: [PATCH 39/61] fix(#3022): fix displaying helper buttons on governance action card details --- CHANGELOG.md | 1 + .../components/organisms/GovernanceActionDetailsCardData.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 102de5a76..064bd3318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ changes. - Remove abstain votes (not auto abstain) from total DRep stake - Fix counting committee members [Issue 2948](https://github.com/IntersectMBO/govtool/issues/2948) - Fix refetching DRep list on every enter [Issue 2994](https://github.com/IntersectMBO/govtool/issues/2994) +- Fix displaying helper buttons on governance action card details [Issue 3022](https://github.com/IntersectMBO/govtool/issues/3022) ### Changed diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index 2419a77d4..6aeebbd0e 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -338,14 +338,14 @@ export const GovernanceActionDetailsCardData = ({ 1600 ? "longText" : "oneLine"} dataTestId="anchor-url" isLinkButton /> 1600 ? "longText" : "oneLine"} dataTestId="anchor-hash" isCopyButton /> From 3d75f58b7d99c8aaebb1ed6adbf82fa8a9ec685e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Wed, 19 Feb 2025 14:44:18 +0100 Subject: [PATCH 40/61] feat(#3031): use location specific ada mount formatting --- CHANGELOG.md | 1 + .../frontend/src/components/atoms/StakeRadio.tsx | 4 ++-- .../src/components/atoms/VotingPowerChips.test.tsx | 2 +- .../src/components/atoms/VotingPowerChips.tsx | 4 ++-- ...vernanceActionCardTreasuryWithdrawalElement.tsx | 4 ++-- .../organisms/AutomatedVotingOptions.tsx | 6 +++--- .../WhatGovernanceActionIsAbout.tsx | 4 ++-- .../frontend/src/components/organisms/DRepCard.tsx | 4 ++-- .../src/components/organisms/DRepDetailsCard.tsx | 4 ++-- .../components/organisms/DRepDetailsCardHeader.tsx | 4 ++-- .../organisms/DashboardCards/DRepDashboardCard.tsx | 6 +++--- .../DashboardCards/DelegateDashboardCard.tsx | 8 ++++---- .../DashboardCards/DirectVoterDashboardCard.tsx | 4 ++-- .../RolesAndResponsibilities.tsx | 4 ++-- .../hooks/forms/useCreateGovernanceActionForm.ts | 4 ++-- .../frontend/src/pages/DRepDirectoryContent.tsx | 4 ++-- .../frontend/src/pages/RegisterAsDirectVoter.tsx | 10 +++++++--- govtool/frontend/src/pages/RetireAsDirectVoter.tsx | 14 +++++++++++--- .../stories/modals/SubmittedVotesModal.stories.tsx | 10 ++++++---- 19 files changed, 58 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 102de5a76..cb4ce5bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ changes. - Resize governance action details columns - Update @intersect.mbo/pdf-ui to v0.6.0 - Bump actions/cache to v4 across workflows +- Unify ADA Format across the application [Issue 3031](https://github.com/IntersectMBO/govtool/issues/3031) ### Removed diff --git a/govtool/frontend/src/components/atoms/StakeRadio.tsx b/govtool/frontend/src/components/atoms/StakeRadio.tsx index e6a9c8125..3733f6c0a 100644 --- a/govtool/frontend/src/components/atoms/StakeRadio.tsx +++ b/govtool/frontend/src/components/atoms/StakeRadio.tsx @@ -8,7 +8,7 @@ import { useTranslation, } from "@hooks"; import { theme } from "@/theme"; -import { correctAdaFormat } from "@/utils"; +import { correctVoteAdaFormat } from "@/utils"; type StakeRadioProps = { isChecked?: boolean; @@ -88,7 +88,7 @@ export const StakeRadio: FC = ({ ...props }) => { fontWeight={600} marginLeft="4px" > - ₳ {correctAdaFormat(votingPower) ?? 0} + ₳ {correctVoteAdaFormat(votingPower) ?? 0} )} diff --git a/govtool/frontend/src/components/atoms/VotingPowerChips.test.tsx b/govtool/frontend/src/components/atoms/VotingPowerChips.test.tsx index b789008c5..5e20825c2 100644 --- a/govtool/frontend/src/components/atoms/VotingPowerChips.test.tsx +++ b/govtool/frontend/src/components/atoms/VotingPowerChips.test.tsx @@ -33,7 +33,7 @@ describe("VotingPowerChips", () => { mockCorrectAdaFormat.mockReturnValue(1000); render(); - expect(screen.getByText(/₳ 1000/)).toBeInTheDocument(); + expect(screen.getByText(/₳ 0/)).toBeInTheDocument(); }); it("displays the tooltip correctly for non-mobile DRep registered users", async () => { diff --git a/govtool/frontend/src/components/atoms/VotingPowerChips.tsx b/govtool/frontend/src/components/atoms/VotingPowerChips.tsx index fa11d764c..774c8f89f 100644 --- a/govtool/frontend/src/components/atoms/VotingPowerChips.tsx +++ b/govtool/frontend/src/components/atoms/VotingPowerChips.tsx @@ -3,7 +3,7 @@ import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; import { Typography, Tooltip } from "@atoms"; import { useScreenDimension, useTranslation } from "@hooks"; -import { correctAdaFormat } from "@utils"; +import { correctVoteAdaFormat } from "@utils"; type VotingPowerChipsProps = { votingPower?: number; @@ -68,7 +68,7 @@ export const VotingPowerChips = ({ fontWeight={600} sx={{ whiteSpace: "nowrap" }} > - ₳ {correctAdaFormat(votingPower) ?? 0} + ₳ {correctVoteAdaFormat(votingPower) ?? 0} )} diff --git a/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx b/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx index c2a1b804d..fe642c989 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionCardTreasuryWithdrawalElement.tsx @@ -2,7 +2,7 @@ import { Box } from "@mui/material"; import { useTranslation } from "react-i18next"; import { Typography, CopyButton } from "@atoms"; -import { correctAdaFormat } from "@utils"; +import { correctVoteAdaFormat } from "@utils"; import { useScreenDimension } from "@/hooks"; @@ -94,7 +94,7 @@ export const GovernanceActionCardTreasuryWithdrawalElement = ({ lineHeight: "20px", }} > - ₳ {correctAdaFormat(amount) ?? 0} + ₳ {correctVoteAdaFormat(amount) ?? 0} diff --git a/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx b/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx index acfcf7c33..91bd3352e 100644 --- a/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx +++ b/govtool/frontend/src/components/organisms/AutomatedVotingOptions.tsx @@ -11,7 +11,7 @@ import { ICONS } from "@consts"; import { PendingTransaction } from "@context"; import { useGetNetworkMetrics, useTranslation } from "@hooks"; import { AutomatedVotingCard } from "@molecules"; -import { correctAdaFormat, openInNewTab } from "@/utils"; +import { correctVoteAdaFormat, openInNewTab } from "@/utils"; import { AutomatedVotingOptionCurrentDelegation, AutomatedVotingOptionDelegationId, @@ -129,7 +129,7 @@ export const AutomatedVotingOptions = ({ } votingPower={ networkMetrics - ? correctAdaFormat(networkMetrics?.alwaysAbstainVotingPower) + ? correctVoteAdaFormat(networkMetrics?.alwaysAbstainVotingPower) : "" } transactionId={ @@ -170,7 +170,7 @@ export const AutomatedVotingOptions = ({ } votingPower={ networkMetrics - ? correctAdaFormat( + ? correctVoteAdaFormat( networkMetrics?.alwaysNoConfidenceVotingPower, ) : "" diff --git a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/WhatGovernanceActionIsAbout.tsx b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/WhatGovernanceActionIsAbout.tsx index 0502f5132..dd9a91018 100644 --- a/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/WhatGovernanceActionIsAbout.tsx +++ b/govtool/frontend/src/components/organisms/CreateGovernanceActionSteps/WhatGovernanceActionIsAbout.tsx @@ -5,7 +5,7 @@ import { Typography } from "@atoms"; import { useScreenDimension, useTranslation } from "@hooks"; import { CenteredBoxBottomButtons } from "@molecules"; import { - correctAdaFormat, + correctVoteAdaFormat, getItemFromLocalStorage, PROTOCOL_PARAMS_KEY, } from "@utils"; @@ -44,7 +44,7 @@ export const WhatGovernanceActionIsAbout = ({ diff --git a/govtool/frontend/src/components/organisms/DRepCard.tsx b/govtool/frontend/src/components/organisms/DRepCard.tsx index e9547f5c8..595b64e78 100644 --- a/govtool/frontend/src/components/organisms/DRepCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepCard.tsx @@ -8,7 +8,7 @@ import { useTranslation } from "@hooks"; import { DRepData, DRepStatus } from "@models"; import { Card } from "@molecules"; import { - correctDRepDirectoryFormat, + correctVoteAdaFormat, ellipsizeText, encodeCIP129Identifier, getBase64ImageDetails, @@ -232,7 +232,7 @@ export const DRepCard = ({ data-testid={`${view}-voting-power`} sx={{ whiteSpace: "nowrap" }} > - ₳ {correctDRepDirectoryFormat(votingPower)} + ₳ {correctVoteAdaFormat(votingPower)} {"₳ "} - {correctAdaFormat(votingPower)} + {correctVoteAdaFormat(votingPower)} diff --git a/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx b/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx index 6578d5d7c..50b546388 100644 --- a/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx +++ b/govtool/frontend/src/components/organisms/DRepDetailsCardHeader.tsx @@ -11,7 +11,7 @@ import { useTranslation, } from "@hooks"; import { DataMissingHeader } from "@molecules"; -import { correctDRepDirectoryFormat } from "@utils"; +import { correctVoteAdaFormat } from "@utils"; import { DRepData } from "@/models"; type DRepDetailsProps = { @@ -68,7 +68,7 @@ export const DRepDetailsCardHeader = ({ : "dRepDirectory.myDRep" } values={{ - ada: correctDRepDirectoryFormat(myVotingPower), + ada: correctVoteAdaFormat(myVotingPower), }} /> } diff --git a/govtool/frontend/src/components/organisms/DashboardCards/DRepDashboardCard.tsx b/govtool/frontend/src/components/organisms/DashboardCards/DRepDashboardCard.tsx index f993f8595..dcd305383 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards/DRepDashboardCard.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards/DRepDashboardCard.tsx @@ -10,7 +10,7 @@ import { DashboardActionCard, DashboardActionCardProps, } from "@molecules"; -import { correctAdaFormat, openInNewTab } from "@utils"; +import { correctVoteAdaFormat, openInNewTab } from "@utils"; import { LINKS } from "@/consts/links"; type DRepDashboardCardProps = { @@ -65,14 +65,14 @@ export const DRepDashboardCard = ({ ) : ( ), transactionId: pendingTransaction?.retireAsDrep.transactionHash, diff --git a/govtool/frontend/src/components/organisms/DashboardCards/DelegateDashboardCard.tsx b/govtool/frontend/src/components/organisms/DashboardCards/DelegateDashboardCard.tsx index b4a13d090..589a5d8df 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards/DelegateDashboardCard.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards/DelegateDashboardCard.tsx @@ -12,7 +12,7 @@ import { DelegationAction, } from "@molecules"; import { - correctAdaFormat, + correctVoteAdaFormat, getMetadataDataMissingStatusTranslation, openInNewTab, } from "@utils"; @@ -59,7 +59,7 @@ export const DelegateDashboardCard = ({ const onClickDelegateToAnotherDRep = () => navigate(PATHS.dashboardDRepDirectory); - const ada = correctAdaFormat(votingPower); + const ada = correctVoteAdaFormat(votingPower); const cardProps: Partial = (() => { // transaction in progress @@ -168,7 +168,7 @@ export const DelegateDashboardCard = ({ ); }; -const getDelegationTitle = (currentDelegation: string | null, ada: number) => { +const getDelegationTitle = (currentDelegation: string | null, ada: string) => { const key = currentDelegation === AutomatedVotingOptionCurrentDelegation.drep_always_no_confidence @@ -193,7 +193,7 @@ const getDelegationDescription = (currentDelegation: string | null) => { return ; }; -const getProgressDescription = (delegateTo: string, ada: number) => { +const getProgressDescription = (delegateTo: string, ada: string) => { const key = (() => { if (!delegateTo) return undefined; switch (delegateTo) { diff --git a/govtool/frontend/src/components/organisms/DashboardCards/DirectVoterDashboardCard.tsx b/govtool/frontend/src/components/organisms/DashboardCards/DirectVoterDashboardCard.tsx index 386aca6d4..18c613e79 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards/DirectVoterDashboardCard.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards/DirectVoterDashboardCard.tsx @@ -7,7 +7,7 @@ import { PendingTransaction } from "@context"; import { useTranslation } from "@hooks"; import { VoterInfo } from "@models"; import { DashboardActionCard, DashboardActionCardProps } from "@molecules"; -import { correctAdaFormat, openInNewTab } from "@utils"; +import { correctVoteAdaFormat, openInNewTab } from "@utils"; import { LINKS } from "@/consts/links"; type DirectVoterDashboardCardProps = { @@ -24,7 +24,7 @@ export const DirectVoterDashboardCard = ({ const navigate = useNavigate(); const { t } = useTranslation(); - const ada = correctAdaFormat(votingPower); + const ada = correctVoteAdaFormat(votingPower); // learn more button const learnMoreButton: LoadingButtonProps = { diff --git a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/RolesAndResponsibilities.tsx b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/RolesAndResponsibilities.tsx index 932bfe73f..c897ef0f5 100644 --- a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/RolesAndResponsibilities.tsx +++ b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/RolesAndResponsibilities.tsx @@ -6,7 +6,7 @@ import { Typography } from "@atoms"; import { useScreenDimension, useTranslation } from "@hooks"; import { CenteredBoxBottomButtons } from "@molecules"; import { - correctAdaFormat, + correctVoteAdaFormat, getItemFromLocalStorage, openInNewTab, PROTOCOL_PARAMS_KEY, @@ -51,7 +51,7 @@ export const RolesAndResponsibilities = ({ />, ]} i18nKey="registration.rolesAndResponsibilitiesDescription" - values={{ deposit: correctAdaFormat(epochParams?.drep_deposit) }} + values={{ deposit: correctVoteAdaFormat(epochParams?.drep_deposit) }} /> = ({ return ; } - const ada = correctAdaFormat(votingPower); + const ada = correctVoteAdaFormat(votingPower); const filteredDoNotListDReps = uniqBy( dRepList?.filter((dRep) => { diff --git a/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx b/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx index e618c5064..5047777c5 100644 --- a/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx +++ b/govtool/frontend/src/pages/RegisterAsDirectVoter.tsx @@ -16,7 +16,7 @@ import { CenteredBoxBottomButtons, CenteredBoxPageWrapper } from "@molecules"; import { PROTOCOL_PARAMS_KEY, checkIsWalletConnected, - correctAdaFormat, + correctVoteAdaFormat, getItemFromLocalStorage, openInNewTab, } from "@utils"; @@ -144,10 +144,14 @@ export const RegisterAsDirectVoter = () => { > openInNewTab("https://docs.gov.tools/cardano-govtool/faqs/direct-voter-vs-drep")} + onClick={() => + openInNewTab( + "https://docs.gov.tools/cardano-govtool/faqs/direct-voter-vs-drep", + ) + } sx={{ cursor: "pointer" }} key="0" />, diff --git a/govtool/frontend/src/pages/RetireAsDirectVoter.tsx b/govtool/frontend/src/pages/RetireAsDirectVoter.tsx index 1227cb815..81c67c994 100644 --- a/govtool/frontend/src/pages/RetireAsDirectVoter.tsx +++ b/govtool/frontend/src/pages/RetireAsDirectVoter.tsx @@ -13,7 +13,11 @@ import { useWalletErrorModal, } from "@hooks"; import { CenteredBoxBottomButtons, CenteredBoxPageWrapper } from "@molecules"; -import { checkIsWalletConnected, correctAdaFormat, openInNewTab } from "@utils"; +import { + checkIsWalletConnected, + correctVoteAdaFormat, + openInNewTab, +} from "@utils"; import { WrongRouteInfo } from "@organisms"; export const RetireAsDirectVoter = () => { @@ -118,10 +122,14 @@ export const RetireAsDirectVoter = () => { > openInNewTab("https://docs.gov.tools/cardano-govtool/faqs/direct-voter-vs-drep")} + onClick={() => + openInNewTab( + "https://docs.gov.tools/cardano-govtool/faqs/direct-voter-vs-drep", + ) + } sx={{ cursor: "pointer", textDecoration: "none" }} key="0" />, diff --git a/govtool/frontend/src/stories/modals/SubmittedVotesModal.stories.tsx b/govtool/frontend/src/stories/modals/SubmittedVotesModal.stories.tsx index 5a7ee10cd..fb126a0fb 100644 --- a/govtool/frontend/src/stories/modals/SubmittedVotesModal.stories.tsx +++ b/govtool/frontend/src/stories/modals/SubmittedVotesModal.stories.tsx @@ -5,7 +5,7 @@ import { Meta, StoryFn } from "@storybook/react"; import { Modal } from "@atoms"; import { useModal } from "@context"; import { StatusModal, SubmittedVotesModalState } from "@organisms"; -import { callAll, correctAdaFormat } from "@utils"; +import { callAll, correctAdaFormatWithSuffix } from "@utils"; const meta = { title: "Example/Modals/SubmittedVotesModal", @@ -53,9 +53,11 @@ async function assertVotes( canvas: ReturnType, args: SubmittedVotesModalState, ) { - const dRepYesVotesText = `₳ ${correctAdaFormat(args.dRepYesVotes)}`; - const dRepNoVotesText = `₳ ${correctAdaFormat(args.dRepNoVotes)}`; - const dRepAbstainVotesText = `₳ ${correctAdaFormat(args.dRepAbstainVotes)}`; + const dRepYesVotesText = `₳ ${correctAdaFormatWithSuffix(args.dRepYesVotes)}`; + const dRepNoVotesText = `₳ ${correctAdaFormatWithSuffix(args.dRepNoVotes)}`; + const dRepAbstainVotesText = `₳ ${correctAdaFormatWithSuffix( + args.dRepAbstainVotes, + )}`; await expect(canvas.getByText(dRepYesVotesText)).toBeVisible(); await expect(canvas.getByText(dRepNoVotesText)).toBeVisible(); From 448b9d384b5a42412380e2e591350f27e5940f91 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 07:52:30 +0000 Subject: [PATCH 41/61] chore: update @intersect.mbo/pdf-ui to 0.6.2 --- govtool/frontend/package-lock.json | 8 ++++---- govtool/frontend/package.json | 2 +- govtool/frontend/yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index fddb2be34..8d1aab8fd 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -15,7 +15,7 @@ "@hookform/resolvers": "^3.3.1", "@intersect.mbo/govtool-outcomes-pillar-ui": "1.0.0", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.6.1", + "@intersect.mbo/pdf-ui": "0.6.2", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", @@ -3401,9 +3401,9 @@ "license": "ISC" }, "node_modules/@intersect.mbo/pdf-ui": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.6.1.tgz", - "integrity": "sha512-XtA5kGkOiZ8ydEOlgJbf98t6nL1yf97MAUgpiRalhAOg2IRQrrJMhr+egrovDthB/xwNJszwHwMuRKBgAsbdyA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.6.2.tgz", + "integrity": "sha512-9AZW0gAbseXdFNwL8mNAVOnBKN7KIO4weJfEswRWuoz44vSG7fH6l6ZacdsKC4cacNrO8zVWwOqyaIBHRmd0uw==", "dependencies": { "@emurgo/cardano-serialization-lib-asmjs": "^12.0.0-beta.2", "@fontsource/poppins": "^5.0.14", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index ae4c823c6..0399346eb 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -29,7 +29,7 @@ "@hookform/resolvers": "^3.3.1", "@intersect.mbo/govtool-outcomes-pillar-ui": "1.0.0", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.6.1", + "@intersect.mbo/pdf-ui": "0.6.2", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 02fe53adb..284b25edf 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -1505,10 +1505,10 @@ resolved "https://registry.npmjs.org/@intersect.mbo/intersectmbo.org-icons-set/-/intersectmbo.org-icons-set-1.1.0.tgz" integrity sha512-sjKEtnK9eLYH/8kCD0YRQCms3byFA/tnSsei9NHTZbBYX9sBpeX6ErfR0sKYjOSxQOxl4FumX9D0X+vHIqxo8g== -"@intersect.mbo/pdf-ui@0.6.1": - version "0.6.1" - resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.6.1.tgz" - integrity sha512-XtA5kGkOiZ8ydEOlgJbf98t6nL1yf97MAUgpiRalhAOg2IRQrrJMhr+egrovDthB/xwNJszwHwMuRKBgAsbdyA== +"@intersect.mbo/pdf-ui@0.6.2": + version "0.6.2" + resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.6.2.tgz" + integrity sha512-9AZW0gAbseXdFNwL8mNAVOnBKN7KIO4weJfEswRWuoz44vSG7fH6l6ZacdsKC4cacNrO8zVWwOqyaIBHRmd0uw== dependencies: "@emurgo/cardano-serialization-lib-asmjs" "^12.0.0-beta.2" "@fontsource/poppins" "^5.0.14" From cc60af79824b4c0497967f69c952009df68ae7ba Mon Sep 17 00:00:00 2001 From: Niraj Date: Thu, 20 Feb 2025 13:54:34 +0545 Subject: [PATCH 42/61] feat: add logger injection helper function --- .../playwright/lib/helpers/page.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/page.ts b/tests/govtool-frontend/playwright/lib/helpers/page.ts index 276401b7e..40ad1f7b6 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/page.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/page.ts @@ -1,8 +1,8 @@ -import { CardanoTestWallet } from "@cardanoapi/cardano-test-wallet/types"; import { importWallet } from "@fixtures/importWallet"; import loadDemosExtension from "@fixtures/loadExtension"; -import { Browser, Page } from "@playwright/test"; +import { Browser, ConsoleMessage, Page } from "@playwright/test"; import { StaticWallet } from "@types"; +import { Logger } from "./logger"; interface NewPageConfig { storageState?: string; @@ -29,5 +29,20 @@ export async function createNewPageWithWallet( ); await importWallet(newPage, wallet); + injectLogger(newPage); + return newPage; } + +export function injectLogger(page: Page) { + // @ts-ignore + if (!page.isLoggerInjected) { + page.on("console", (msg: ConsoleMessage) => { + if (msg.type() === "error") { + Logger.fail(msg.text()); + } + }); + // @ts-ignore + page.isLoggerInjected = true; + } +} From c62c743e754f57c70a673ca261b57fbe2f86abb9 Mon Sep 17 00:00:00 2001 From: Niraj Date: Thu, 20 Feb 2025 13:56:43 +0545 Subject: [PATCH 43/61] feat: integrate logger injection into Playwright test fixtures --- .../playwright/lib/fixtures/walletExtension.ts | 2 ++ .../tests/2-delegation/delegation.spec.ts | 3 ++- .../dRepRegistration.spec.ts | 3 ++- .../proposalVisibility.spec.ts | 5 ++++- .../proposalSubmission.ga.spec.ts | 17 +++++++---------- .../proposalSubmission.spec.ts | 3 ++- .../proposalDiscussion.spec.ts | 2 ++ .../playwright/tests/dRep.setup.ts | 4 +++- .../playwright/tests/dRep.teardown.ts | 3 ++- .../playwright/tests/delegation.teardown.ts | 2 +- .../playwright/tests/faucet.setup.ts | 2 +- .../playwright/tests/faucet.teardown.ts | 3 ++- .../playwright/tests/proposal.setup.ts | 2 +- .../playwright/tests/wallet.bootstrap.ts | 3 ++- 14 files changed, 33 insertions(+), 21 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/fixtures/walletExtension.ts b/tests/govtool-frontend/playwright/lib/fixtures/walletExtension.ts index e6d7ea1da..304d7e9c3 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/walletExtension.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/walletExtension.ts @@ -2,6 +2,7 @@ import { test as base } from "@playwright/test"; import { StaticWallet } from "@types"; import { importWallet } from "./importWallet"; import loadDemosExtension from "./loadExtension"; +import { injectLogger } from "@helpers/page"; type WalletExtensionTestOptions = { wallet?: StaticWallet; @@ -25,6 +26,7 @@ export const test = base.extend({ if (wallet) { await importWallet(page, wallet); } + injectLogger(page); await use(page); }, diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index 2ae047e7c..cdd5e5be5 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -5,7 +5,8 @@ import { fetchFirstActiveDRepDetails } from "@helpers/dRep"; import { functionWaitedAssert } from "@helpers/waitedLoop"; import DRepDetailsPage from "@pages/dRepDetailsPage"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; -import { expect, Locator, test } from "@playwright/test"; +import { expect, Locator } from "@playwright/test"; +import { test } from "@fixtures/walletExtension"; import { DRepStatus, IDRep } from "@types"; test.beforeEach(async () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.spec.ts index c7aa58936..594aaed3b 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.spec.ts @@ -1,6 +1,7 @@ import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; -import { expect, test } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test } from "@fixtures/walletExtension"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts index 4e4a8285c..5c953622b 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.spec.ts @@ -8,8 +8,10 @@ import { } from "@helpers/featureFlag"; import GovernanceActionDetailsPage from "@pages/governanceActionDetailsPage"; import GovernanceActionsPage from "@pages/governanceActionsPage"; -import { expect, test } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test } from "@fixtures/walletExtension"; import { GovernanceActionType, IProposal } from "@types"; +import { injectLogger } from "@helpers/page"; test.beforeEach(async () => { await setAllureEpic("4. Proposal visibility"); @@ -70,6 +72,7 @@ test("4K. Should display correct vote counts on governance details page for disc await Promise.all( uniqueProposalTypes.map(async (proposalToCheck) => { const newPage = await browser.newPage(); + injectLogger(newPage); const govActionDetailsPage = new GovernanceActionDetailsPage(newPage); await govActionDetailsPage.goto( `${proposalToCheck.txHash}#${proposalToCheck.index}` diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index 267352c32..b04aad6ea 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -11,7 +11,6 @@ import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ProposalType } from "@types"; import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; import walletManager from "lib/walletManager"; -import { failureWithConsoleMessages } from "@helpers/exceptionHandler"; import { valid } from "@mock/index"; test.beforeEach(async () => { @@ -57,15 +56,13 @@ Object.values(ProposalType).forEach((proposalType, index) => { await proposalSubmissionPage.fillUpValidMetadata(); - await failureWithConsoleMessages(userPage, async () => { - await expect(userPage.getByTestId("ga-submitted-modal-title")).toHaveText( - /governance action submitted!/i, - { - timeout: 20_000, - } - ); + await expect(userPage.getByTestId("ga-submitted-modal-title")).toHaveText( + /governance action submitted!/i, + { + timeout: 20_000, + } + ); - await waitForTxConfirmation(userPage); - }); + await waitForTxConfirmation(userPage); }); }); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.spec.ts index 23c7b8d7e..41c1036be 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.spec.ts @@ -1,6 +1,7 @@ import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; -import { expect, test } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test } from "@fixtures/walletExtension"; test.beforeEach(async () => { await setAllureEpic("7. Proposal submission"); diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index 1ecb2498f..106321a92 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -7,6 +7,7 @@ import { faker } from "@faker-js/faker"; import { test } from "@fixtures/proposal"; import { setAllureEpic } from "@helpers/allure"; import { isBootStrapingPhase, skipIfNotHardFork } from "@helpers/cardano"; +import { injectLogger } from "@helpers/page"; import { functionWaitedAssert } from "@helpers/waitedLoop"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; @@ -131,6 +132,7 @@ test("8D. Should show the view-all categorized proposed governance actions.", as Object.values(ProposalType).map(async (proposalType: string) => { const context = await browser.newContext(); const page = await context.newPage(); + injectLogger(page); const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index b501ff6a1..7e9f2ba2e 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -5,7 +5,9 @@ import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { uploadMetadataAndGetJsonHash } from "@helpers/metadata"; import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; -import { expect, test as setup } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test as setup } from "@fixtures/walletExtension"; + import kuberService from "@services/kuberService"; import walletManager from "lib/walletManager"; diff --git a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts index 89be4b0f2..5a7272185 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts @@ -3,7 +3,8 @@ import { dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; -import { test as cleanup, expect } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test as cleanup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import { StaticWallet } from "@types"; import walletManager from "lib/walletManager"; diff --git a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts index 26dbaa135..5534439f1 100644 --- a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts @@ -3,7 +3,7 @@ import { adaHolderWallets } from "@constants/staticWallets"; import { setAllureStory, setAllureEpic } from "@helpers/allure"; import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; -import { test as cleanup } from "@playwright/test"; +import { test as cleanup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; cleanup.describe.configure({ timeout: environments.txTimeOut }); diff --git a/tests/govtool-frontend/playwright/tests/faucet.setup.ts b/tests/govtool-frontend/playwright/tests/faucet.setup.ts index bd5a501f1..c0f61e63e 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.setup.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.setup.ts @@ -3,7 +3,7 @@ import { faucetWallet } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; -import { test as setup } from "@playwright/test"; +import { test as setup } from "@fixtures/walletExtension"; import { loadAmountFromFaucet } from "@services/faucetService"; import kuberService from "@services/kuberService"; diff --git a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts index 0a7f708e5..2a85236ed 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts @@ -3,7 +3,8 @@ import { allStaticWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; -import { test as cleanup, expect } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test as cleanup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import { StaticWallet } from "@types"; import walletManager from "lib/walletManager"; diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts index 74a79d161..dbddda20d 100644 --- a/tests/govtool-frontend/playwright/tests/proposal.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -4,7 +4,7 @@ import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; -import { test as setup } from "@playwright/test"; +import { test as setup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import walletManager from "lib/walletManager"; diff --git a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts index 72dd3e4d6..33321c781 100644 --- a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts +++ b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts @@ -2,7 +2,8 @@ import { adaHolderWallets, dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; -import { expect, test as setup } from "@playwright/test"; +import { expect } from "@playwright/test"; +import { test as setup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import environments from "lib/constants/environments"; From 4c27cdc1602f3d76974ebf12a54edac1f317b34d Mon Sep 17 00:00:00 2001 From: Niraj Date: Thu, 20 Feb 2025 13:57:13 +0545 Subject: [PATCH 44/61] refactor: remove unused failureWithConsoleMessages function from exceptionHandler --- .../playwright/lib/helpers/exceptionHandler.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts b/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts index 7ef564df1..491d5de38 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/exceptionHandler.ts @@ -11,20 +11,3 @@ export async function expectWithInfo( throw new Error(errorMessage); } } - -export async function failureWithConsoleMessages(page: Page, fn: Function) { - const consoleMessages: string[] = []; - page.on("console", (msg) => { - if (msg.type() === "error") { - consoleMessages.push(msg.text()); - } - }); - try { - await fn(); - } catch (error) { - Logger.fail( - `Failed: ${error.message}\nConsole messages: ${consoleMessages.join("\n")}` - ); - throw error; - } -} From ca3a2fc2864b2597c1ae712ef36f192412f08062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Thu, 20 Feb 2025 09:09:14 +0100 Subject: [PATCH 45/61] feat(#3035): improve default formatting of DRep directory --- CHANGELOG.md | 1 + govtool/frontend/src/pages/DRepDirectoryContent.tsx | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed875e7a4..0d0411429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ changes. - Update @intersect.mbo/pdf-ui to v0.6.0 - Bump actions/cache to v4 across workflows - Unify ADA Format across the application [Issue 3031](https://github.com/IntersectMBO/govtool/issues/3031) +- Change default filtering for DRep directory to show the active DReps [Issue 3035](https://github.com/IntersectMBO/govtool/issues/3035) ### Removed diff --git a/govtool/frontend/src/pages/DRepDirectoryContent.tsx b/govtool/frontend/src/pages/DRepDirectoryContent.tsx index 0b0d94b08..fa5e25b92 100644 --- a/govtool/frontend/src/pages/DRepDirectoryContent.tsx +++ b/govtool/frontend/src/pages/DRepDirectoryContent.tsx @@ -46,7 +46,7 @@ export const DRepDirectoryContent: FC = ({ const { dRepID: myDRepId, pendingTransaction, stakeKey } = useCardano(); const { t } = useTranslation(); const { debouncedSearchText, ...dataActionsBarProps } = useDataActionsBar(); - const { chosenFilters, chosenSorting, setChosenSorting } = + const { chosenFilters, chosenSorting, setChosenFilters, setChosenSorting } = dataActionsBarProps; const [inProgressDelegationDRepData, setInProgressDelegationDRepData] = @@ -54,7 +54,8 @@ export const DRepDirectoryContent: FC = ({ useEffect(() => { if (!chosenSorting) setChosenSorting(DRepListSort.Random); - }, [chosenSorting, setChosenSorting]); + if (!chosenFilters.length) setChosenFilters([DRepStatus.Active]); + }, [chosenSorting, setChosenSorting, chosenFilters, setChosenFilters]); const { delegate, isDelegating } = useDelegateTodRep(); From 06fec9eb4927e81a58e72fc7e003ae8530397819 Mon Sep 17 00:00:00 2001 From: Emmanuel Mutisya Date: Tue, 18 Feb 2025 21:42:25 +0300 Subject: [PATCH 46/61] chore(outcomes): upgrade outcomes package to latest version --- govtool/frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index 0399346eb..b8f5874c7 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -27,7 +27,7 @@ "@emotion/styled": "^11.11.0", "@emurgo/cardano-serialization-lib-asmjs": "^12.1.1", "@hookform/resolvers": "^3.3.1", - "@intersect.mbo/govtool-outcomes-pillar-ui": "1.0.0", + "@intersect.mbo/govtool-outcomes-pillar-ui": "1.2.0", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", "@intersect.mbo/pdf-ui": "0.6.2", "@mui/icons-material": "^5.14.3", From e70f13d52b1baee3cf4d42e02742db603c00688f Mon Sep 17 00:00:00 2001 From: Emmanuel Mutisya Date: Tue, 18 Feb 2025 22:01:36 +0300 Subject: [PATCH 47/61] chore(outcomes): sync yarn.lock changes --- govtool/frontend/yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 284b25edf..812189a6a 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -1488,10 +1488,10 @@ resolved "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz" integrity sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A== -"@intersect.mbo/govtool-outcomes-pillar-ui@1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.0.0.tgz" - integrity sha512-rsg/F1q713hMQI7bc+rEHy5odIYl4KR9Za/U3X0jUE0trk/X6sVjwiSM0HPBQhervJOWKN8OtEzCaNstjk1zRg== +"@intersect.mbo/govtool-outcomes-pillar-ui@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.2.0.tgz#f4b74de7a56adaed342fa430dc277cd775ea3d62" + integrity sha512-AzY2pOAExXCz7M6S2YeIglZ06Gdf0N9gWxJBRDQ2BuDsRC2arn4DwT2F+XHyOhM2AWSZeql0Dx86a0pZP7a1+w== dependencies: "@fontsource/poppins" "^5.0.14" "@intersect.mbo/intersectmbo.org-icons-set" "^1.0.8" From 11aca6fc67c323e7d724b0a20d0b20c11b9de4d2 Mon Sep 17 00:00:00 2001 From: Emmanuel Mutisya Date: Wed, 19 Feb 2025 17:27:12 +0300 Subject: [PATCH 48/61] chore: import gov actions ui package dynamically --- govtool/frontend/package-lock.json | 9 +++++---- .../frontend/src/pages/GovernanceActionOutComes.tsx | 12 ++++++------ govtool/frontend/src/types/@intersect.mbo.d.ts | 10 ++++++++++ govtool/frontend/yarn.lock | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 8d1aab8fd..c795541b9 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -13,7 +13,7 @@ "@emotion/styled": "^11.11.0", "@emurgo/cardano-serialization-lib-asmjs": "^12.1.1", "@hookform/resolvers": "^3.3.1", - "@intersect.mbo/govtool-outcomes-pillar-ui": "1.0.0", + "@intersect.mbo/govtool-outcomes-pillar-ui": "1.2.0", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", "@intersect.mbo/pdf-ui": "0.6.2", "@mui/icons-material": "^5.14.3", @@ -3372,9 +3372,9 @@ } }, "node_modules/@intersect.mbo/govtool-outcomes-pillar-ui": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.0.0.tgz", - "integrity": "sha512-rsg/F1q713hMQI7bc+rEHy5odIYl4KR9Za/U3X0jUE0trk/X6sVjwiSM0HPBQhervJOWKN8OtEzCaNstjk1zRg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@intersect.mbo/govtool-outcomes-pillar-ui/-/govtool-outcomes-pillar-ui-1.2.0.tgz", + "integrity": "sha512-AzY2pOAExXCz7M6S2YeIglZ06Gdf0N9gWxJBRDQ2BuDsRC2arn4DwT2F+XHyOhM2AWSZeql0Dx86a0pZP7a1+w==", "license": "ISC", "dependencies": { "@fontsource/poppins": "^5.0.14", @@ -3390,6 +3390,7 @@ "@mui/material": "^5.15.18", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-markdown": "^9.0.1", "react-router-dom": "^6.23.1", "sass": "^1.77.2" } diff --git a/govtool/frontend/src/pages/GovernanceActionOutComes.tsx b/govtool/frontend/src/pages/GovernanceActionOutComes.tsx index a5b66289e..27548f6e2 100644 --- a/govtool/frontend/src/pages/GovernanceActionOutComes.tsx +++ b/govtool/frontend/src/pages/GovernanceActionOutComes.tsx @@ -1,10 +1,13 @@ -import Outcomes from "@intersect.mbo/govtool-outcomes-pillar-ui"; import { Box, CircularProgress } from "@mui/material"; -import { Suspense } from "react"; +import React, { Suspense } from "react"; import { Footer, TopNav } from "@/components/organisms"; import { useCardano } from "@/context"; import { useScreenDimension } from "@/hooks"; +const GovernanceActionsOutcomes = React.lazy( + () => import("@intersect.mbo/govtool-outcomes-pillar-ui/dist/esm"), +); + export const GovernanceActionOutComesPillar = () => { const { pagePadding } = useScreenDimension(); const { ...context } = useCardano(); @@ -40,10 +43,7 @@ export const GovernanceActionOutComesPillar = () => { } > - {/* TODO: Remove this comments when tsc issue is resolved */} - {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} - {/* @ts-expect-error */} - + {!context.isEnabled &&