Compare commits
119
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3355ce84df | ||
|
|
ec5d1a7775 | ||
|
|
380974c9c3 | ||
|
|
7ab536fd41 | ||
|
|
a3c41c8075 | ||
|
|
e47b868c53 | ||
|
|
b6286cd0f3 | ||
|
|
f66e976b66 | ||
|
|
866e7232db | ||
|
|
5a8ff90890 | ||
|
|
7b8f654906 | ||
|
|
7df012a38f | ||
|
|
341d01508f | ||
|
|
d6f39049bd | ||
|
|
1d06be8f4e | ||
|
|
5eba8fe28f | ||
|
|
2ba0e9a1b2 | ||
|
|
43d3754c64 | ||
|
|
aae5c44fa4 | ||
|
|
878bed9c7a | ||
|
|
6f9f432c90 | ||
|
|
3f01b93159 | ||
|
|
473c244d7b | ||
|
|
d6a32f5090 | ||
|
|
71540a90fb | ||
|
|
cefdbe6a3c | ||
|
|
3928dd5c0e | ||
|
|
1521bab4c4 | ||
|
|
b3036d520f | ||
|
|
429a5a23d3 | ||
|
|
5b02fd5d54 | ||
|
|
b8309a76e7 | ||
|
|
e8ae085c06 | ||
|
|
fdcd24847c | ||
|
|
e054db39b5 | ||
|
|
a01e48d508 | ||
|
|
0d96c487d9 | ||
|
|
011e4e4cec | ||
|
|
d6e2432955 | ||
|
|
18c034b910 | ||
|
|
849cbb43c4 | ||
|
|
cd34cb181f | ||
|
|
97b3f4decf | ||
|
|
0465fb8ca9 | ||
|
|
22af89e78c | ||
|
|
adfd2f41b6 | ||
|
|
d9b1aa6da3 | ||
|
|
205f369cdc | ||
|
|
9f63fde123 | ||
|
|
f2c70e6da4 | ||
|
|
e8ff1b0b60 | ||
|
|
f5989b0022 | ||
|
|
653ca034f2 | ||
|
|
ef25552311 | ||
|
|
0a8439d125 | ||
|
|
702ea0c6b4 | ||
|
|
0f2b86770a | ||
|
|
cd6d350047 | ||
|
|
c5a06c57ac | ||
|
|
5bb31fa38d | ||
|
|
fd8f38803c | ||
|
|
a22f8f0ef1 | ||
|
|
c2d5c71f35 | ||
|
|
f88c35648e | ||
|
|
348c61530e | ||
|
|
f364dabe2f | ||
|
|
1ae1fdff5e | ||
|
|
3ed615c36e | ||
|
|
6b50816234 | ||
|
|
f5e67a0c2d | ||
|
|
e4d4646878 | ||
|
|
bbd1536c18 | ||
|
|
f8444c0c88 | ||
|
|
b1adf776c0 | ||
|
|
ad898ab0e8 | ||
|
|
5b0fffc5cb | ||
|
|
a9dbc0f6eb | ||
|
|
a71786817f | ||
|
|
9ee0cb7b65 | ||
|
|
8c4aa41240 | ||
|
|
91ac977704 | ||
|
|
1190033776 | ||
|
|
b99e2235b4 | ||
|
|
002bc4f188 | ||
|
|
0c2af8c75f | ||
|
|
a305c5b8a9 | ||
|
|
4c3ceb94f3 | ||
|
|
2215864d0c | ||
|
|
589785ce09 | ||
|
|
babd99088d | ||
|
|
d155909fe4 | ||
|
|
1d3298cdc9 | ||
|
|
c2baaa2dd9 | ||
|
|
e2c4c4a841 | ||
|
|
7a89dc984d | ||
|
|
19580fb9ce | ||
|
|
0721099d7d | ||
|
|
9ee2810c51 | ||
|
|
9f8f99b50b | ||
|
|
3208f762fd | ||
|
|
7a06c946d1 | ||
|
|
70e172045d | ||
|
|
06c540666e | ||
|
|
f81503b8f7 | ||
|
|
1699e33cbd | ||
|
|
5280b79927 | ||
|
|
34526d527e | ||
|
|
7b9aae700d | ||
|
|
e9cb2ad217 | ||
|
|
6dd4536fdd | ||
|
|
522eb521b9 | ||
|
|
3aa0e974c2 | ||
|
|
a0eb381ab1 | ||
|
|
a51ab4d98d | ||
|
|
67643afd74 | ||
|
|
145539e0c0 | ||
|
|
48109b584c | ||
|
|
a4512e6064 | ||
|
|
45adac2932 |
@@ -14,8 +14,7 @@ What we need to achieve and who for
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] What do we need to do first
|
||||
- [ ] and then what?
|
||||
- [ ] Etc.
|
||||
- [ ]
|
||||
- [ ]
|
||||
|
||||
## Additional details / background info
|
||||
|
||||
@@ -22,11 +22,14 @@ So that
|
||||
|
||||
## Tasks
|
||||
|
||||
- [ ] Explore and sketch
|
||||
- [ ] UX (if needed)
|
||||
- [ ] Design (if needed)
|
||||
- [ ] Team and stakeholder review
|
||||
- [ ] Visual Design
|
||||
- [ ] Team review
|
||||
- [ ] Etc.
|
||||
- [ ] Specs reviewed and created or adjusted
|
||||
- [ ] Implementation
|
||||
- [ ] Testing (unit and/or e2e)
|
||||
- [ ] Code review
|
||||
- [ ] QA review
|
||||
|
||||
## Sketch
|
||||
|
||||
|
||||
@@ -48,19 +48,20 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
id: ${{ github.event.release.id }}
|
||||
body: |
|
||||
---
|
||||
|
||||
___
|
||||
|
||||
# Deployments
|
||||
* https://explorer.vega.xyz
|
||||
* https://governance.vega.xyz
|
||||
|
||||
# IPFS releases
|
||||
Tye IPFS hash of this release of the Trading app is:
|
||||
The IPFS hash of this release of the Trading app is:
|
||||
|
||||
CIDv0: ${{ env.IPFS_V0 }}
|
||||
CIDv1: ${{ env.IPFS_V1 }}
|
||||
|
||||
You can always access the latest IPFS release by visiting [vega.trading](https://vega.trading).
|
||||
You can always access the latest IPFS release by visiting [console.vega.xyz](https://console.vega.xyz).
|
||||
|
||||
You can also access Trading directly from an IPFS gateway.
|
||||
BEWARE: The Trading interface uses [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported. You should always use an IPFS gateway that enforces [origin separation](https://ipfs.github.io/public-gateway-checker/).
|
||||
|
||||
@@ -5,6 +5,7 @@ on:
|
||||
branches:
|
||||
- release/*
|
||||
- develop
|
||||
- main
|
||||
tags:
|
||||
- v*
|
||||
pull_request:
|
||||
@@ -112,15 +113,19 @@ jobs:
|
||||
preview_governance="not deployed"
|
||||
preview_trading="not deployed"
|
||||
preview_explorer="not deployed"
|
||||
if [[ $affected == *"governance"* ]]; then
|
||||
preview_tools="not deployed"
|
||||
if echo "$affected" | grep -q governance; then
|
||||
echo "Governance is affected"
|
||||
projects_e2e+='"governance-e2e" '
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"trading"* ]]; then
|
||||
if echo "$affected" | grep -q trading; then
|
||||
echo "Trading is affected"
|
||||
projects_e2e+='"trading-e2e" '
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"explorer"* ]]; then
|
||||
if echo "$affected" | grep -q explorer; then
|
||||
echo "Explorer is affected"
|
||||
projects_e2e+='"explorer-e2e" '
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
@@ -130,13 +135,30 @@ jobs:
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
projects="$(echo $projects_e2e | sed 's|-e2e||g')"
|
||||
if echo "$affected" | grep -q multisig-signer; then
|
||||
echo "Tools are affected"
|
||||
# tools are only applicable to check previews or deploy from develop to mainnet
|
||||
if [[ "${{ github.event_name }}" = "pull_request" ]]; then
|
||||
echo "Deploying tools on preview"
|
||||
preview_tools=$(printf "https://%s.%s.vega.rocks" "tools" "$branch_slug")
|
||||
projects+=' "multisig-signer" '
|
||||
fi
|
||||
if [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
echo "Deploying tools on s3"
|
||||
projects+=' "multisig-signer" '
|
||||
fi
|
||||
fi
|
||||
projects_e2e=${projects_e2e%?}
|
||||
projects_e2e=[${projects_e2e// /,}]
|
||||
projects=${projects%?}
|
||||
projects=[${projects// /,}]
|
||||
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
|
||||
echo PROJECTS=$(echo $projects_e2e | sed 's|-e2e||g') >> $GITHUB_ENV
|
||||
echo PROJECTS=$projects >> $GITHUB_ENV
|
||||
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
|
||||
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
|
||||
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
|
||||
echo PREVIEW_TOOLS=$preview_tools >> $GITHUB_ENV
|
||||
|
||||
outputs:
|
||||
projects: ${{ env.PROJECTS }}
|
||||
@@ -144,11 +166,12 @@ jobs:
|
||||
preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
|
||||
preview_trading: ${{ env.PREVIEW_TRADING }}
|
||||
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
||||
preview_tools: ${{ env.PREVIEW_TOOLS }}
|
||||
|
||||
cypress:
|
||||
needs: lint-test-build
|
||||
name: '(CI) cypress'
|
||||
if: ${{ needs.lint-test-build.outputs.projects != '[]' }}
|
||||
if: ${{ needs.lint-test-build.outputs.projects-e2e != '[]' }}
|
||||
uses: ./.github/workflows/cypress-run.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
@@ -170,6 +193,7 @@ jobs:
|
||||
- publish-dist
|
||||
- lint-test-build
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
timeout-minutes: 60
|
||||
name: '(CD) comment preview links'
|
||||
steps:
|
||||
- name: Find Comment
|
||||
@@ -179,6 +203,35 @@ jobs:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
body-includes: Previews
|
||||
|
||||
- name: Wait for deployments
|
||||
run: |
|
||||
# https://stackoverflow.com/questions/3183444/check-for-valid-link-url
|
||||
regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_governance }}" =~ $regex ]]; then
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_governance }}"; do
|
||||
echo "waiting for governance preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_explorer }}" =~ $regex ]]; then
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_explorer }}"; do
|
||||
echo "waiting for explorer preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_trading }}" =~ $regex ]]; then
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_trading }}"; do
|
||||
echo "waiting for trading preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
if [[ "${{ needs.lint-test-build.outputs.preview_tools }}" =~ $regex ]]; then
|
||||
until curl -L --fail "${{ needs.lint-test-build.outputs.preview_tools }}"; do
|
||||
echo "waiting for tools preview"
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
|
||||
- name: Create comment
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
||||
@@ -189,16 +242,11 @@ jobs:
|
||||
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
|
||||
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
||||
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
||||
|
||||
cypress-check:
|
||||
name: '(CI) cypress - check'
|
||||
runs-on: ubuntu-latest
|
||||
needs: cypress
|
||||
steps:
|
||||
- run: echo Done!
|
||||
* tools: ${{ needs.lint-test-build.outputs.preview_tools }}
|
||||
|
||||
# Report single result at the end, to avoid mess with required checks in PR
|
||||
cypress-result:
|
||||
cypress-check:
|
||||
name: '(CI) cypress - check'
|
||||
if: ${{ always() }}
|
||||
needs: cypress
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
project: ${{ fromJSON(inputs.projects) }}
|
||||
name: ${{ matrix.project }}
|
||||
runs-on: self-hosted-runner
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 100
|
||||
steps:
|
||||
# Checks if skip cache was requested
|
||||
- name: Set skip-nx-cache flag
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
name: Generate tranches
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */6 * * *'
|
||||
|
||||
jobs:
|
||||
master:
|
||||
name: Generate Queries
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
- name: Use Node.js 16
|
||||
id: Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.15.1
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
- name: Generate queries
|
||||
run: node ./scripts/get-tranches.js
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: 'chore: update tranches'
|
||||
commit_options: '--no-verify --signoff'
|
||||
skip_fetch: true
|
||||
skip_checkout: true
|
||||
@@ -59,26 +59,47 @@ jobs:
|
||||
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
- name: Define variables
|
||||
- name: Define dist variables
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: |
|
||||
envName=''
|
||||
domain="vega.rocks"
|
||||
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
||||
envName="mainnet"
|
||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
||||
bucketName=''
|
||||
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
if [[ "${{ matrix.app }}" = "multisig-signer" ]]; then
|
||||
envName="mainnet"
|
||||
bucketName="tools.vega.xyz"
|
||||
fi
|
||||
if [[ "${envName}" = "mainnet" ]]; then
|
||||
domain="vega.xyz"
|
||||
fi
|
||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
||||
envName="mainnet"
|
||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ "${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }}" = "true" ]]; then
|
||||
envName="mainnet"
|
||||
fi
|
||||
|
||||
if [[ "${envName}" = "mainnet" ]]; then
|
||||
domain="vega.xyz"
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
fi
|
||||
elif [[ "${envName}" = "testnet" ]]; then
|
||||
domain="fairground.wtf"
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||
fi
|
||||
|
||||
echo "bucket name: ${bucketName}"
|
||||
echo "env name: ${envName}"
|
||||
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||
|
||||
- name: Build local dist
|
||||
@@ -155,7 +176,7 @@ jobs:
|
||||
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||
- name: Publish dist to s3
|
||||
uses: jakejarvis/s3-sync-action@master
|
||||
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') }}
|
||||
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') && ( matrix.app != 'trading' || (matrix.app == 'trading' && !endsWith(github.ref, 'main') ) ) }}
|
||||
with:
|
||||
args: --acl private --follow-symlinks --delete
|
||||
env:
|
||||
@@ -187,8 +208,19 @@ jobs:
|
||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
||||
https://api.fleek.co/graphql
|
||||
|
||||
- name: Update vega.trading DNS to redirect to the new console
|
||||
- name: Check out ipfs-redirect
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'vegaprotocol/ipfs-redirect'
|
||||
path: 'ipfs-redirect'
|
||||
fetch-depth: '0'
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
|
||||
- name: Update console.vega.xyz DNS to redirect to the new console
|
||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
run: |
|
||||
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
|
||||
tar -xzf kubo.tgz
|
||||
@@ -197,26 +229,52 @@ jobs:
|
||||
new_hash=$(cat ${{ matrix.app }}-ipfs-hash)
|
||||
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
|
||||
|
||||
# Generate console URL
|
||||
new_console_url_type=ipfs
|
||||
# new_console_url_type=ipns
|
||||
new_console_url_domain=cf-ipfs.com
|
||||
# new_console_url_domain=dweb.link
|
||||
new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
|
||||
echo "new_console_url=${new_console_url}"
|
||||
ls -al ipfs-redirect
|
||||
|
||||
# Update record in DNSimple
|
||||
# docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
|
||||
dnsimple_account_id=84895
|
||||
dnsimple_zone_name=vega.trading
|
||||
dnsimple_record_id=44409591
|
||||
# see: https://dnsimple.com/a/84895/domains/vega.trading/records/44409591/edit
|
||||
echo $new_hash > ipfs-redirect/cidv0.txt
|
||||
echo $new_cid > ipfs-redirect/cidv1.txt
|
||||
|
||||
curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-X PATCH \
|
||||
-d "{
|
||||
\"content\": \"${new_console_url}\"
|
||||
}" \
|
||||
https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
|
||||
(
|
||||
cd ipfs-redirect
|
||||
|
||||
git status
|
||||
cat .git/config
|
||||
git config --global user.email "vega-ci-bot@vega.xyz"
|
||||
git config --global user.name "vega-ci-bot"
|
||||
|
||||
branch_name="update-hash-${{ github.ref }}"
|
||||
git checkout -b "$branch_name"
|
||||
commit_msg="Automated hash update from ${{ github.ref }}"
|
||||
git add cidv0.txt cidv1.txt
|
||||
git commit -m "$commit_msg"
|
||||
git push -u origin "$branch_name"
|
||||
pr_url="$(gh pr create --title "${commit_msg}" --body 'automated pull request to update CIDs')"
|
||||
echo $pr_url
|
||||
# once auto merge get's enabled on documentation repo let's do follow up
|
||||
sleep 5
|
||||
gh pr merge "${pr_url}" --delete-branch --squash --admin
|
||||
)
|
||||
|
||||
# # Generate console URL
|
||||
# new_console_url_type=ipfs
|
||||
# # new_console_url_type=ipns
|
||||
# new_console_url_domain=cf-ipfs.com
|
||||
# # new_console_url_domain=dweb.link
|
||||
# new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
|
||||
# echo "new_console_url=${new_console_url}"
|
||||
|
||||
# # Update record in DNSimple
|
||||
# # docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
|
||||
# dnsimple_account_id=84895
|
||||
# dnsimple_zone_name=console.vega.xyz
|
||||
# dnsimple_record_id=44409591
|
||||
# # see: https://dnsimple.com/a/84895/domains/console.vega.xyz/records/44409591/edit
|
||||
|
||||
# curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
|
||||
# -H 'Accept: application/json' \
|
||||
# -H 'Content-Type: application/json' \
|
||||
# -X PATCH \
|
||||
# -d "{
|
||||
# \"content\": \"${new_console_url}\"
|
||||
# }" \
|
||||
# https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
|
||||
|
||||
@@ -43,7 +43,17 @@ jobs:
|
||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
||||
https://api.fleek.co/graphql
|
||||
|
||||
- name: Update vega.trading DNS to redirect to the new console
|
||||
- name: Check out ipfs-redirect
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'vegaprotocol/ipfs-redirect'
|
||||
path: 'ipfs-redirect'
|
||||
fetch-depth: '0'
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
|
||||
- name: Update console.vega.xyz DNS to redirect to the new console
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
run: |
|
||||
curl -L https://dist.ipfs.tech/kubo/v0.20.0/kubo_v0.20.0_linux-amd64.tar.gz -o kubo.tgz
|
||||
tar -xzf kubo.tgz
|
||||
@@ -51,27 +61,24 @@ jobs:
|
||||
which ipfs
|
||||
new_hash=$(cat ipfs-hash)
|
||||
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
|
||||
git config --global user.email "vega-ci-bot@vega.xyz"
|
||||
git config --global user.name "vega-ci-bot"
|
||||
echo $new_hash > ipfs-redirect/cidv0.txt
|
||||
echo $new_cid > ipfs-redirect/cidv1.txt
|
||||
|
||||
# Generate console URL
|
||||
new_console_url_type=ipfs
|
||||
# new_console_url_type=ipns
|
||||
new_console_url_domain=cf-ipfs.com
|
||||
# new_console_url_domain=dweb.link
|
||||
new_console_url="https://${new_cid}.${new_console_url_type}.${new_console_url_domain}/"
|
||||
echo "new_console_url=${new_console_url}"
|
||||
(
|
||||
cd ipfs-redirect
|
||||
|
||||
# Update record in DNSimple
|
||||
# docs: https://developer.dnsimple.com/v2/zones/records/#updateZoneRecord
|
||||
dnsimple_account_id=84895
|
||||
dnsimple_zone_name=vega.trading
|
||||
dnsimple_record_id=44409591
|
||||
# see: https://dnsimple.com/a/84895/domains/vega.trading/records/44409591/edit
|
||||
|
||||
curl -H 'Authorization: Bearer ${{ secrets.DNSIMPLE_API_TOKEN }}' \
|
||||
-H 'Accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-X PATCH \
|
||||
-d "{
|
||||
\"content\": \"${new_console_url}\"
|
||||
}" \
|
||||
https://api.dnsimple.com/v2/${dnsimple_account_id}/zones/${dnsimple_zone_name}/records/${dnsimple_record_id}
|
||||
git status
|
||||
branch_name="rollback-to-$new_hash"
|
||||
git checkout -b "$branch_name"
|
||||
commit_msg="hash rollback to $new_hash"
|
||||
git add cidv0.txt cidv1.txt
|
||||
git commit -m "$commit_msg"
|
||||
git push -u origin "$branch_name" --force-with-lease
|
||||
pr_url="$(gh pr create --title "${commit_msg}" --body 'automated pull request to update CIDs')"
|
||||
echo $pr_url
|
||||
# once auto merge get's enabled on documentation repo let's do follow up
|
||||
sleep 5
|
||||
gh pr merge "${pr_url}" --delete-branch --squash --admin
|
||||
)
|
||||
|
||||
@@ -50,3 +50,5 @@ cypress.env.json
|
||||
|
||||
#cypress
|
||||
/apps/**/cypress/reports/
|
||||
/apps/**/cypress/downloads/
|
||||
/apps/**/fixtures/wallet/node**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=http://localhost:26617
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||
NX_TENDERMINT_URL=https://tm.n07.testnet.vega.xyz/tm
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||
|
||||
+5
-4
@@ -3,18 +3,19 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_TOKEN_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases/tag/
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -10,3 +10,4 @@ NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
|
||||
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# .env is stagnet1, so there are no overrides required
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET3":"https://stagnet3.explorer.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET1":"https://stagnet1.explorer.vega.xyz"}'
|
||||
|
||||
@@ -10,3 +10,4 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -7,8 +7,9 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
|
||||
NX_VEGA_GOVERNANCE_URL=https://validator-testnet.governance.vega.xyz
|
||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
||||
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
||||
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { router } from './routes/router-config';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
const splashLoading = (
|
||||
<Splash>
|
||||
@@ -32,7 +33,9 @@ function App() {
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
<Suspense fallback={splashLoading}>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
</Suspense>
|
||||
</NodeGuard>
|
||||
<NodeSwitcherDialog
|
||||
open={nodeSwitcherOpen}
|
||||
|
||||
@@ -4,9 +4,11 @@ import {
|
||||
} from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import { ENV } from '../../config/env';
|
||||
import { Routes } from '../../routes/route-names';
|
||||
import { Link as RouteLink } from 'react-router-dom';
|
||||
|
||||
export const Footer = () => {
|
||||
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
||||
@@ -21,7 +23,7 @@ export const Footer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<footer className="grid grid-rows-2 lg:grid-cols-[1fr_auto] text-xs md:text-md lg:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<div className="flex justify-between gap-2 align-middle">
|
||||
{GIT_COMMIT_HASH && (
|
||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
@@ -56,11 +58,16 @@ export const Footer = () => {
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="pl-2 align-center lg:align-right lg:flex lg:justify-end gap-2 align-middle lg:max-w-xs lg:ml-auto">
|
||||
<RouteLink to={`/${Routes.DISCLAIMER}`} className="underline">
|
||||
Disclaimer
|
||||
</RouteLink>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
const NodeUrl = ({ url }: { url: string }) => {
|
||||
export const NodeUrl = ({ url }: { url: string }) => {
|
||||
// get base url from api url, api sub domain
|
||||
const urlObj = new URL(url);
|
||||
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
||||
import { PriceMonitoringBoundsInfoPanel } from '@vegaprotocol/markets';
|
||||
import {
|
||||
LiquidityInfoPanel,
|
||||
LiquidityMonitoringParametersInfoPanel,
|
||||
@@ -39,133 +40,69 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||
return [];
|
||||
};
|
||||
|
||||
const oraclePanels = isEqual(
|
||||
const showTwoOracles = isEqual(
|
||||
getSigners(settlementData),
|
||||
getSigners(terminationData)
|
||||
)
|
||||
? [
|
||||
{
|
||||
title: t('Settlement Oracle'),
|
||||
content: (
|
||||
<OracleInfoPanel
|
||||
noBorder={false}
|
||||
market={market}
|
||||
type="settlementData"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Termination Oracle'),
|
||||
content: (
|
||||
<OracleInfoPanel
|
||||
noBorder={false}
|
||||
market={market}
|
||||
type="termination"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: t('Oracle'),
|
||||
content: (
|
||||
<OracleInfoPanel
|
||||
noBorder={false}
|
||||
market={market}
|
||||
type="settlementData"
|
||||
/>
|
||||
),
|
||||
},
|
||||
];
|
||||
);
|
||||
|
||||
const panels = [
|
||||
{
|
||||
title: t('Key details'),
|
||||
content: <KeyDetailsInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Instrument'),
|
||||
content: <InstrumentInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Settlement asset'),
|
||||
content: <SettlementAssetInfoPanel market={market} noBorder={false} />,
|
||||
},
|
||||
{
|
||||
title: t('Metadata'),
|
||||
content: <MetadataInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Risk model'),
|
||||
content: <RiskModelInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Risk parameters'),
|
||||
content: <RiskParametersInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
{
|
||||
title: t('Risk factors'),
|
||||
content: <RiskFactorsInfoPanel noBorder={false} market={market} />,
|
||||
},
|
||||
...(market.priceMonitoringSettings?.parameters?.triggers || []).map(
|
||||
(trigger, i) => ({
|
||||
title: t(`Price monitoring trigger ${i + 1}`),
|
||||
content: <MarketInfoTable noBorder={false} data={trigger} />,
|
||||
})
|
||||
),
|
||||
...(market.data?.priceMonitoringBounds || []).map((trigger, i) => ({
|
||||
title: t(`Price monitoring bound ${i + 1}`),
|
||||
content: (
|
||||
<>
|
||||
<MarketInfoTable
|
||||
noBorder={false}
|
||||
data={{
|
||||
maxValidPrice: trigger.maxValidPrice,
|
||||
minValidPrice: trigger.minValidPrice,
|
||||
}}
|
||||
decimalPlaces={market.decimalPlaces}
|
||||
/>
|
||||
<MarketInfoTable
|
||||
noBorder={false}
|
||||
data={{ referencePrice: trigger.referencePrice }}
|
||||
decimalPlaces={
|
||||
market.tradableInstrument.instrument.product.settlementAsset
|
||||
.decimals
|
||||
}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
})),
|
||||
{
|
||||
title: t('Liquidity monitoring parameters'),
|
||||
content: (
|
||||
<LiquidityMonitoringParametersInfoPanel
|
||||
noBorder={false}
|
||||
market={market}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('Liquidity'),
|
||||
content: <LiquidityInfoPanel market={market} noBorder={false} />,
|
||||
},
|
||||
{
|
||||
title: t('Liquidity price range'),
|
||||
content: (
|
||||
<LiquidityPriceRangeInfoPanel market={market} noBorder={false} />
|
||||
),
|
||||
},
|
||||
...oraclePanels,
|
||||
];
|
||||
const headerClassName = 'font-alpha calt text-xl mt-4 border-b-2 pb-2';
|
||||
|
||||
return (
|
||||
<>
|
||||
{panels.map((p) => (
|
||||
<div key={p.title} className="mb-3">
|
||||
<h2 className="font-alpha calt text-xl">{p.title}</h2>
|
||||
{p.content}
|
||||
</div>
|
||||
<div>
|
||||
<h2 className={headerClassName}>{t('Key details')}</h2>
|
||||
<KeyDetailsInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Instrument')}</h2>
|
||||
<InstrumentInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Settlement asset')}</h2>
|
||||
<SettlementAssetInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Metadata')}</h2>
|
||||
<MetadataInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Risk model')}</h2>
|
||||
<RiskModelInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Risk parameters')}</h2>
|
||||
<RiskParametersInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Risk factors')}</h2>
|
||||
<RiskFactorsInfoPanel market={market} />
|
||||
{(market.data?.priceMonitoringBounds || []).map((trigger, i) => (
|
||||
<>
|
||||
<h2 className={headerClassName}>
|
||||
{t('Price monitoring bounds %s', [(i + 1).toString()])}
|
||||
</h2>
|
||||
<PriceMonitoringBoundsInfoPanel
|
||||
market={market}
|
||||
triggerIndex={i + 1}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
{(market.priceMonitoringSettings?.parameters?.triggers || []).map(
|
||||
(trigger, i) => (
|
||||
<>
|
||||
<h2 className={headerClassName}>
|
||||
{t('Price monitoring settings %s', [(i + 1).toString()])}
|
||||
</h2>
|
||||
<MarketInfoTable data={trigger} key={i} />
|
||||
</>
|
||||
)
|
||||
)}
|
||||
<h2 className={headerClassName}>{t('Liquidity monitoring')}</h2>
|
||||
<LiquidityMonitoringParametersInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Liquidity')}</h2>
|
||||
<LiquidityInfoPanel market={market} />
|
||||
<h2 className={headerClassName}>{t('Liquidity price range')}</h2>
|
||||
<LiquidityPriceRangeInfoPanel market={market} />
|
||||
{showTwoOracles ? (
|
||||
<>
|
||||
<h2 className={headerClassName}>{t('Settlement oracle')}</h2>
|
||||
<OracleInfoPanel market={market} type="settlementData" />
|
||||
<h2 className={headerClassName}>{t('Termination oracle')}</h2>
|
||||
<OracleInfoPanel market={market} type="termination" />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h2 className={headerClassName}>{t('Oracle')}</h2>
|
||||
<OracleInfoPanel market={market} type="settlementData" />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -84,15 +84,17 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
||||
<AgGridColumn
|
||||
colId="asset"
|
||||
headerName={t('Settlement asset')}
|
||||
field="tradableInstrument.instrument.product.settlementAsset"
|
||||
field="tradableInstrument.instrument.product.settlementAsset.symbol"
|
||||
hide={window.innerWidth <= BREAKPOINT_MD}
|
||||
cellRenderer={({
|
||||
value,
|
||||
data,
|
||||
}: VegaICellRendererParams<
|
||||
MarketFieldsFragment,
|
||||
'tradableInstrument.instrument.product.settlementAsset'
|
||||
>) =>
|
||||
value ? (
|
||||
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
||||
>) => {
|
||||
const value =
|
||||
data?.tradableInstrument.instrument.product.settlementAsset;
|
||||
return value ? (
|
||||
<ButtonLink
|
||||
onClick={(e) => {
|
||||
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
||||
@@ -102,8 +104,8 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
||||
</ButtonLink>
|
||||
) : (
|
||||
''
|
||||
)
|
||||
}
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<AgGridColumn
|
||||
flex={2}
|
||||
|
||||
+6
-4
@@ -5,12 +5,13 @@ export const ErrorCodes = new Map([
|
||||
[51, 'Transaction failed validation'],
|
||||
[60, 'Transaction could not be decoded'],
|
||||
[70, 'Error'],
|
||||
[71, 'Partial success/error'],
|
||||
[80, 'Unknown command'],
|
||||
[89, 'Rejected as spam'],
|
||||
[0, 'Success'],
|
||||
]);
|
||||
|
||||
export const successCodes = new Set([0]);
|
||||
export const successCodes = new Set([0, 71]);
|
||||
|
||||
interface ChainResponseCodeProps {
|
||||
code: number;
|
||||
@@ -29,11 +30,12 @@ export const ChainResponseCode = ({
|
||||
error,
|
||||
}: ChainResponseCodeProps) => {
|
||||
const isSuccess = successCodes.has(code);
|
||||
|
||||
const successColour =
|
||||
code === 71 ? 'fill-vega-orange' : 'fill-vega-green-600';
|
||||
const icon = isSuccess ? (
|
||||
<Icon name="tick-circle" className="fill-vega-green-550" />
|
||||
<Icon name="tick-circle" className={successColour} />
|
||||
) : (
|
||||
<Icon name="cross" className="fill-vega-pink-550" />
|
||||
<Icon name="cross" className="fill-vega-pink-600" />
|
||||
);
|
||||
const label = ErrorCodes.get(code) || 'Unknown response code';
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
||||
vote={command?.voteSubmission?.value === 'VALUE_YES'}
|
||||
yesText="Proposal vote"
|
||||
noText="Proposal vote"
|
||||
useVoteColour={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,4 +34,17 @@ describe('Vote TX icon', () => {
|
||||
const no = render(<VoteIcon vote={false} />);
|
||||
expect(no.getByRole('img')).toHaveAttribute('aria-label', 'delete icon');
|
||||
});
|
||||
|
||||
it('useVoteColour prop can be used to override coloured background', () => {
|
||||
const no = render(<VoteIcon vote={false} />);
|
||||
expect(no.container.children[0]).toHaveClass('bg-vega-pink-550');
|
||||
|
||||
const monochromeNo = render(
|
||||
<VoteIcon vote={false} useVoteColour={false} />
|
||||
);
|
||||
expect(monochromeNo.container.children[0]).not.toHaveClass(
|
||||
'bg-vega-pink-550'
|
||||
);
|
||||
expect(monochromeNo.container.children[0]).toHaveClass('bg-vega-dark-200');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,6 +8,32 @@ export interface VoteIconProps {
|
||||
yesText?: string;
|
||||
// Defaults to 'Against', but can be any text
|
||||
noText?: string;
|
||||
// If set to false the background will not be coloured
|
||||
useVoteColour?: boolean;
|
||||
}
|
||||
|
||||
function getBgColour(useVoteColour: boolean, vote: boolean) {
|
||||
if (useVoteColour === false) {
|
||||
return 'bg-vega-dark-200';
|
||||
}
|
||||
|
||||
return vote ? 'bg-vega-green-550' : 'bg-vega-pink-550';
|
||||
}
|
||||
|
||||
function getFillColour(useVoteColour: boolean, vote: boolean) {
|
||||
if (useVoteColour === false) {
|
||||
return 'white';
|
||||
}
|
||||
|
||||
return vote ? 'vega-green-300' : 'vega-pink-300';
|
||||
}
|
||||
|
||||
function getTextColour(useVoteColour: boolean, vote: boolean) {
|
||||
if (useVoteColour === false) {
|
||||
return 'white';
|
||||
}
|
||||
|
||||
return vote ? 'vega-green-200' : 'vega-pink-200';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,14 +44,15 @@ export interface VoteIconProps {
|
||||
*/
|
||||
export function VoteIcon({
|
||||
vote,
|
||||
useVoteColour = true,
|
||||
yesText = 'For',
|
||||
noText = 'Against',
|
||||
}: VoteIconProps) {
|
||||
const label = vote ? yesText : noText;
|
||||
const bg = vote ? 'bg-vega-green-550' : 'bg-vega-pink-550';
|
||||
const icon: IconName = vote ? 'tick-circle' : 'delete';
|
||||
const fill = vote ? 'vega-green-300' : 'vega-pink-300';
|
||||
const text = vote ? 'vega-green-200' : 'vega-pink-200';
|
||||
const bg = getBgColour(useVoteColour, vote);
|
||||
const fill = getFillColour(useVoteColour, vote);
|
||||
const text = getTextColour(useVoteColour, vote);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import { OracleDetailsType } from './oracle-details-type';
|
||||
import type { SourceTypeName } from './oracle-details-type';
|
||||
import { OracleDetailsType, isInternalSourceType } from './oracle-details-type';
|
||||
import type { SourceType } from './oracle';
|
||||
import { PropertyKeyType } from '@vegaprotocol/types';
|
||||
|
||||
function renderComponent(type: SourceTypeName) {
|
||||
return <OracleDetailsType type={type} />;
|
||||
function renderComponent(type: SourceType) {
|
||||
return <OracleDetailsType sourceType={type} />;
|
||||
}
|
||||
|
||||
function renderWrappedComponent(type: SourceTypeName) {
|
||||
function renderWrappedComponent(type: SourceType) {
|
||||
return (
|
||||
<table>
|
||||
<tbody>{renderComponent(type)}</tbody>
|
||||
@@ -14,19 +15,53 @@ function renderWrappedComponent(type: SourceTypeName) {
|
||||
);
|
||||
}
|
||||
|
||||
function mock(name: string): SourceType {
|
||||
return {
|
||||
sourceType: {
|
||||
filters: [
|
||||
{
|
||||
__typename: 'Filter',
|
||||
key: {
|
||||
name,
|
||||
type: PropertyKeyType.TYPE_STRING,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('Oracle type view', () => {
|
||||
it('Renders nothing when type is null', () => {
|
||||
const res = render(renderComponent(null as unknown as SourceTypeName));
|
||||
const res = render(renderComponent(null as unknown as SourceType));
|
||||
expect(res.container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('Renders Internal time for internal sources', () => {
|
||||
const res = render(renderWrappedComponent('DataSourceDefinitionInternal'));
|
||||
expect(res.getByText('Internal time')).toBeInTheDocument();
|
||||
it('Renders Internal time for internal sources - timestamp', () => {
|
||||
const s = mock('vegaprotocol.builtin.timestamp');
|
||||
expect(isInternalSourceType(s)).toEqual(true);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('Internal data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders Internal time for internal sources - potential future types', () => {
|
||||
const s = mock('vegaprotocol.builtin.boolean');
|
||||
expect(isInternalSourceType(s)).toEqual(true);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('Internal data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders External data otherwise - prices.external.whatever', () => {
|
||||
const s = mock('prices.external.whatever');
|
||||
expect(isInternalSourceType(s)).toEqual(false);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('External data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders External data otherwise', () => {
|
||||
const res = render(renderWrappedComponent('DataSourceDefinitionExternal'));
|
||||
const s = mock('prices.external.vegaprotocol.builtin.');
|
||||
expect(isInternalSourceType(s)).toEqual(false);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('External data')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,27 +1,51 @@
|
||||
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
||||
import type { SourceType } from './oracle';
|
||||
|
||||
export type SourceTypeName = SourceType['__typename'] | undefined;
|
||||
/**
|
||||
* Basic function to determine if a source is internal or external.
|
||||
*
|
||||
* This should be distinguishable using __typename, but the type is incorrectly
|
||||
* reported at the moment, so instead we check the filters.
|
||||
*
|
||||
* @param s SourceType
|
||||
* @returns boolean True if the source is internal
|
||||
*/
|
||||
export function isInternalSourceType(s: SourceType) {
|
||||
if ('filters' in s.sourceType) {
|
||||
const filters = s.sourceType.filters;
|
||||
|
||||
if (filters) {
|
||||
return (
|
||||
filters?.filter((f) => {
|
||||
return f.key.name?.indexOf('vegaprotocol.builtin.') === 0;
|
||||
}).length > 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
interface OracleDetailsTypeProps {
|
||||
type: SourceTypeName;
|
||||
sourceType: SourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a a single table row for the Oracle Details view that shows
|
||||
* if the oracle is using the internal time oracle or external data
|
||||
*/
|
||||
export function OracleDetailsType({ type }: OracleDetailsTypeProps) {
|
||||
if (!type) {
|
||||
export function OracleDetailsType({ sourceType }: OracleDetailsTypeProps) {
|
||||
if (!sourceType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isInternal = isInternalSourceType(sourceType);
|
||||
|
||||
return (
|
||||
<TableRow modifier="bordered">
|
||||
<TableHeader scope="row">Type</TableHeader>
|
||||
<TableCell modifier="bordered">
|
||||
{type === 'DataSourceDefinitionInternal'
|
||||
? 'Internal time'
|
||||
: 'External data'}
|
||||
{isInternal ? 'Internal data' : 'External data'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
||||
@@ -53,7 +53,7 @@ export const OracleDetails = ({
|
||||
<OracleLink id={id} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<OracleDetailsType type={sourceType.__typename} />
|
||||
<OracleDetailsType sourceType={sourceType} />
|
||||
<OracleSigners sourceType={sourceType} />
|
||||
<OracleMarkets id={id} />
|
||||
<TableRow modifier="bordered">
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
|
||||
export const Disclaimer = () => {
|
||||
return (
|
||||
<section>
|
||||
<div className="px-40 max-sm:px-0 max-md:px-10 mb-4 max-w-5xl">
|
||||
<RouteTitle data-testid="disclaimer-header">
|
||||
{t('Disclaimer')}
|
||||
</RouteTitle>
|
||||
<p className="mt-3">
|
||||
The Vega Block Explorer is an application that allows users to, among
|
||||
other things, browse through blocks, view wallet addresses, network
|
||||
hashrate, transaction data and other key information on the Vega
|
||||
blockchain. It is free, public and open source software. Software
|
||||
upgrades may contain bugs or security vulnerabilities that might
|
||||
result in loss of functionality.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
The Vega Block Explorer uses data from nodes on the Vega Blockchain.
|
||||
The developers of the Vega Block Explorer do not operate or run the
|
||||
Vega Blockchain or any other blockchain.
|
||||
</p>
|
||||
<p className="mt-3 font-semibold">
|
||||
The Vega Block Explorer is provided “as is”. The developers of the
|
||||
Vega Block Explorer make no representations or warranties of any kind,
|
||||
whether express or implied, statutory or otherwise regarding the Vega
|
||||
Block Explorer. They disclaim all warranties of merchantability,
|
||||
quality, fitness for purpose. They disclaim all warranties that the
|
||||
Vega Block Explorer is free of harmful components or errors.
|
||||
</p>
|
||||
<p className="mt-3 font-bold">
|
||||
No developer of the Vega Block Explorer accepts any responsibility
|
||||
for, or liability to users in connection with their use of the Vega
|
||||
Block Explorer.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -10,4 +10,5 @@ export const Routes = {
|
||||
MARKETS: 'markets',
|
||||
ORACLES: 'oracles',
|
||||
NETWORK_PARAMETERS: 'network-parameters',
|
||||
DISCLAIMER: 'disclaimer',
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ import { AssetLink, MarketLink } from '../components/links';
|
||||
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||
import { remove0x } from '@vegaprotocol/utils';
|
||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
||||
import { Disclaimer } from './pages/disclaimer';
|
||||
|
||||
export type Navigable = {
|
||||
path: string;
|
||||
@@ -335,6 +336,17 @@ export const routerConfig: Route[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: Routes.DISCLAIMER,
|
||||
element: <Disclaimer />,
|
||||
handle: {
|
||||
name: t('Disclaimer'),
|
||||
text: t('Disclaimer'),
|
||||
breadcrumb: () => (
|
||||
<Link to={Routes.DISCLAIMER}>{t('Disclaimer')}</Link>
|
||||
),
|
||||
},
|
||||
},
|
||||
...partiesRoutes,
|
||||
...assetsRoutes,
|
||||
...genesisRoutes,
|
||||
|
||||
@@ -26,6 +26,7 @@ module.exports = defineConfig({
|
||||
viewportWidth: 1440,
|
||||
viewportHeight: 900,
|
||||
numTestsKeptInMemory: 5,
|
||||
downloadsFolder: 'cypress/downloads',
|
||||
testIsolation: false,
|
||||
},
|
||||
env: {
|
||||
|
||||
@@ -33,8 +33,9 @@ const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||
const openProposals = '[data-testid="open-proposals"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
const proposalDescriptionToggle = 'proposal-description-toggle';
|
||||
const voteBreakdownToggle = 'vote-breakdown-toggle';
|
||||
const proposalTermsToggle = 'proposal-terms-toggle';
|
||||
const proposalTermsToggle = 'proposal-json-toggle';
|
||||
|
||||
describe(
|
||||
'Governance flow for proposal details',
|
||||
@@ -73,16 +74,28 @@ describe(
|
||||
'contain.text',
|
||||
rawProposal.rationale.title
|
||||
);
|
||||
cy.getByTestId(proposalDescriptionToggle).click();
|
||||
cy.getByTestId('proposal-description-toggle');
|
||||
cy.get(proposalDetailsDescription)
|
||||
.find('p')
|
||||
.should('have.text', proposalDescription);
|
||||
});
|
||||
// 3001-VOTE-008
|
||||
getProposalInformationFromTable('ID')
|
||||
.invoke('text')
|
||||
.should('not.be.empty')
|
||||
.and('have.length', 64);
|
||||
// 3001-VOTE-009
|
||||
getProposalInformationFromTable('Proposed by')
|
||||
.invoke('text')
|
||||
.should('not.be.empty')
|
||||
.and('have.length', 64);
|
||||
cy.getByTestId(proposalTermsToggle).click();
|
||||
// 3001-VOTE-052
|
||||
// 3001-VOTE-052 3001-VOTE-010
|
||||
cy.get('code.language-json')
|
||||
.should('exist')
|
||||
.within(() => {
|
||||
cy.get('.hljs-string').eq(0).should('have.text', '"ProposalTerms"');
|
||||
cy.get('.hljs-attr').eq(0).should('have.text', '"id"');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,8 +103,6 @@ describe(
|
||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
const proposalTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
||||
// const currentDate = new Date(createTenDigitUnixTimeStampForSpecifiedDays(0) * 1000)
|
||||
// const proposedDate = new Date(currentDate.getTime() + 60000)
|
||||
|
||||
submitUniqueRawProposal({
|
||||
proposalTitle: proposalTitle,
|
||||
@@ -109,16 +120,9 @@ describe(
|
||||
closingDate
|
||||
);
|
||||
});
|
||||
cy.wrap(
|
||||
formatDateWithLocalTimezone(
|
||||
new Date(createTenDigitUnixTimeStampForSpecifiedDays(0) * 1000)
|
||||
)
|
||||
).then((proposalDate) => {
|
||||
getProposalInformationFromTable('Proposed on').should(
|
||||
'have.text',
|
||||
proposalDate
|
||||
);
|
||||
});
|
||||
getProposalInformationFromTable('Proposed on')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
|
||||
it('Newly created proposal details - shows default status set to fail', function () {
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
createUpdateNetworkProposalTxBody,
|
||||
createFreeFormProposalTxBody,
|
||||
} from '../../support/proposal.functions';
|
||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||
|
||||
@@ -43,6 +44,7 @@ context(
|
||||
waitForSpinner();
|
||||
cy.connectVegaWallet();
|
||||
ethereumWalletConnect();
|
||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||
navigateTo(navigation.proposals);
|
||||
});
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
governanceProposalType,
|
||||
submitUniqueRawProposal,
|
||||
voteForProposal,
|
||||
waitForProposalSubmitted,
|
||||
waitForProposalSync,
|
||||
} from '../../support/governance.functions';
|
||||
|
||||
@@ -46,11 +45,7 @@ const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||
const rawProposalData = '[data-testid="proposal-data"]';
|
||||
const minVoteButton = '[data-testid="min-vote"]';
|
||||
const maxVoteButton = '[data-testid="max-vote"]';
|
||||
const voteButtons = '[data-testid="vote-buttons"]';
|
||||
const votingDate = '[data-testid="voting-date"]';
|
||||
const voteTwoMinExtraNote = '[data-testid="voting-2-mins-extra"]';
|
||||
const rejectProposalsLink = '[href="/proposals/rejected"]';
|
||||
const feedbackError = '[data-testid="Error"]';
|
||||
const noOpenProposals = '[data-testid="no-open-proposals"]';
|
||||
@@ -106,8 +101,7 @@ context(
|
||||
.and('have.text', 'There are no enacted or rejected proposals');
|
||||
});
|
||||
|
||||
// 3002-PROP-002
|
||||
// 3002-PROP-003
|
||||
// 3002-PROP-002 3002-PROP-003 3001-VOTE-012 3007-PNE-020 3004-PMAC-004 3005-PASN-004 3008-PFRO-016 3003-PMAN-004
|
||||
it('Proposal form - shows how many vega tokens are required to make a proposal', function () {
|
||||
// 3002-PROP-005
|
||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||
@@ -116,23 +110,14 @@ context(
|
||||
).should('be.visible');
|
||||
});
|
||||
|
||||
// Skipping as currently unable to propose using forms other than raw
|
||||
// 3002-PROP-011
|
||||
it.skip('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
||||
cy.get(maxVoteButton).should('be.visible');
|
||||
cy.get(votingDate).should('not.be.empty');
|
||||
cy.get(voteTwoMinExtraNote).should(
|
||||
'contain.text',
|
||||
'we add 2 minutes of extra time'
|
||||
);
|
||||
enterUniqueFreeFormProposalBody('50', generateFreeFormProposalTitle());
|
||||
// 3002-PROP-012
|
||||
// 3002-PROP-016
|
||||
waitForProposalSubmitted();
|
||||
// 3002-PROP-011 3008-PFRO-005
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||
verifyUnstakedBalance(1);
|
||||
createRawProposal();
|
||||
});
|
||||
|
||||
// 3008-PFRO-002 3008-PFRO-004
|
||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated - but also staked', function () {
|
||||
ensureSpecifiedUnstakedTokensAreAssociated('2');
|
||||
verifyUnstakedBalance(2);
|
||||
@@ -148,10 +133,6 @@ context(
|
||||
it.skip('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||
enterUniqueFreeFormProposalBody('0.1', generateFreeFormProposalTitle());
|
||||
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
cy.get('input:invalid')
|
||||
.invoke('prop', 'validationMessage')
|
||||
.should('equal', 'Value must be greater than or equal to 1.');
|
||||
@@ -280,6 +261,20 @@ context(
|
||||
closeDialog();
|
||||
});
|
||||
|
||||
// 3007-PNE-022 3007-PNE-023 3004-PMAC-006 3004-PMAC-007 3005-PASN-006 3005-PASN-007
|
||||
// 3006-PASC-006 3006-PASC-007 3008-PFRO-018 3008-PFRO-019 3003-PMAN-006 3003-PMAN-007
|
||||
it('Unable to submit proposal without valid json', function () {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.getByTestId('input-error-text').should('have.text', 'Required');
|
||||
cy.get(rawProposalData).type('Not a valid json string');
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.getByTestId('input-error-text').should(
|
||||
'have.text',
|
||||
'Must be valid JSON'
|
||||
);
|
||||
});
|
||||
|
||||
// 1005-PROP-009
|
||||
it('Unable to vote on a freeform proposal - when some but not enough vega associated', function () {
|
||||
const proposalTitle = generateFreeFormProposalTitle();
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
import {
|
||||
closeDialog,
|
||||
dissociateFromSecondWalletKey,
|
||||
navigateTo,
|
||||
navigation,
|
||||
turnTelemetryOff,
|
||||
waitForSpinner,
|
||||
} from '../../support/common.functions';
|
||||
import {
|
||||
getDownloadedProposalJsonPath,
|
||||
submitUniqueRawProposal,
|
||||
} from '../../support/governance.functions';
|
||||
import {
|
||||
getProposalInformationFromTable,
|
||||
goToMakeNewProposal,
|
||||
governanceProposalType,
|
||||
voteForProposal,
|
||||
waitForProposalSubmitted,
|
||||
} from '../../support/governance.functions';
|
||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
||||
import {
|
||||
ensureSpecifiedUnstakedTokensAreAssociated,
|
||||
stakingPageAssociateTokens,
|
||||
stakingPageDisassociateAllTokens,
|
||||
} from '../../support/staking.functions';
|
||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||
import {
|
||||
vegaWalletSetSpecifiedApprovalAmount,
|
||||
@@ -26,15 +34,11 @@ const proposalType = '[data-testid="proposal-type"]';
|
||||
const proposalDetails = '[data-testid="proposal-details"]';
|
||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
||||
const proposalValidationDeadline =
|
||||
'[data-testid="proposal-validation-deadline"]';
|
||||
const proposalParameterSelect = '[data-testid="proposal-parameter-select"]';
|
||||
const proposalMarketSelect = '[data-testid="proposal-market-select"]';
|
||||
const newProposalTitle = '[data-testid="proposal-title"]';
|
||||
const newProposalDescription = '[data-testid="proposal-description"]';
|
||||
const newProposalTerms = '[data-testid="proposal-terms"]';
|
||||
const currentParameterValue =
|
||||
'[data-testid="selected-proposal-param-current-value"]';
|
||||
const newProposedParameterValue =
|
||||
'[data-testid="selected-proposal-param-new-value"]';
|
||||
const minVoteDeadline = '[data-testid="min-vote"]';
|
||||
@@ -54,11 +58,10 @@ const proposalTermsSection = 'proposal';
|
||||
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
||||
const fUSDCId =
|
||||
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
|
||||
const epochTimeout = Cypress.env('epochTimeout');
|
||||
const proposalTimeout = { timeout: 14000 };
|
||||
|
||||
// 3001-VOTE-007
|
||||
context.skip(
|
||||
context(
|
||||
'Governance flow - form validations for different governance proposals',
|
||||
{ tags: '@slow' },
|
||||
function () {
|
||||
@@ -79,28 +82,10 @@ context.skip(
|
||||
navigateTo(navigation.proposals);
|
||||
});
|
||||
|
||||
it('Able to submit valid update network parameter proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
// 3002-PROP-006
|
||||
cy.get(newProposalTitle).type('Test update network parameter proposal');
|
||||
// 3002-PROP-007
|
||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||
|
||||
cy.get(proposalParameterSelect).find('option').should('have.length', 117);
|
||||
cy.get(proposalParameterSelect).select(
|
||||
// 3007-PNEC-002
|
||||
'governance_proposal_asset_minEnact'
|
||||
);
|
||||
cy.get(currentParameterValue).should('have.value', '2s');
|
||||
cy.get(newProposedParameterValue).type('5s'); // 3007-PNEC-003
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
waitForProposalSubmitted();
|
||||
});
|
||||
|
||||
it('Unable to submit network parameter with missing/invalid fields', function () {
|
||||
navigateTo(navigation.proposals);
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.get(proposalDownloadBtn).click();
|
||||
cy.get(inputError).should('have.length', 3);
|
||||
cy.get(newProposalTitle).type(
|
||||
'Invalid update network parameter proposal'
|
||||
@@ -111,62 +96,78 @@ context.skip(
|
||||
);
|
||||
cy.get(newProposedParameterValue).type('0');
|
||||
cy.get(proposalVoteDeadline).clear().type('0');
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
cy.get(proposalVoteDeadline).clear().type('9000');
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
|
||||
it('Able to download network param proposal json', function () {
|
||||
const downloadFolder = './cypress/downloads/';
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
cy.log('Download proposal file');
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
const filename =
|
||||
downloadFolder +
|
||||
'vega-network-param-proposal-' +
|
||||
getFormattedTime() +
|
||||
'.json';
|
||||
cy.readFile(filename, proposalTimeout)
|
||||
.its('terms.updateNetworkParameter')
|
||||
.should('exist');
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-network-param-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false });
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
validateDialogContentMsg('PROPOSAL_ERROR_CLOSE_TIME_TOO_SOON');
|
||||
});
|
||||
|
||||
// 3007-PNEC-001 3007-PNEC-003
|
||||
it('Able to download and submit network param proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
// 3007-PNEC-006
|
||||
cy.get(newProposalTitle)
|
||||
.siblings()
|
||||
.should('contain.text', '(100 characters or less)');
|
||||
// 3007-PNEC-004 3007-PNEC-005
|
||||
cy.get(newProposalTitle).type('Test update network parameter proposal');
|
||||
// 3007-PNEC-009
|
||||
cy.get(newProposalDescription)
|
||||
.siblings()
|
||||
.should('contain.text', '(20,000 characters or less)');
|
||||
// 3007-PNEC-007 3007-PNEC-008
|
||||
cy.get(newProposalDescription).type('E2E test for downloading proposals');
|
||||
// 3007-PNEC-010
|
||||
cy.get(proposalParameterSelect).select(
|
||||
'governance_proposal_asset_minClose'
|
||||
);
|
||||
// 3007-PNEC-011
|
||||
cy.get(newProposedParameterValue).type('10s');
|
||||
|
||||
// 3007-PNEC-012
|
||||
cy.get(proposalVoteDeadline).clear().type('2');
|
||||
// 3007-PNEC-013 3007-PNEC-014
|
||||
cy.getByTestId('voting-date').invoke('text').should('not.be.empty');
|
||||
// 3007-PNEC-015
|
||||
cy.get(maxEnactDeadline).click();
|
||||
// 3007-PNEC-016
|
||||
cy.getByTestId('enactment-date').invoke('text').should('not.be.empty');
|
||||
// 3007-PNEC-017
|
||||
cy.contains(
|
||||
'Time till enactment (must be equal to or after vote close)'
|
||||
).should('be.visible');
|
||||
// 3007-PNE-018
|
||||
cy.log('Download updated proposal file');
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
const filename =
|
||||
downloadFolder +
|
||||
'vega-network-param-proposal-' +
|
||||
getFormattedTime() +
|
||||
'.json';
|
||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
||||
cy.readFile(filename, proposalTimeout).then((jsonFile) => {
|
||||
cy.wrap(jsonFile)
|
||||
.its('rationale.description')
|
||||
.should('eq', 'E2E test for downloading proposals');
|
||||
cy.wrap(jsonFile)
|
||||
.its('terms.updateNetworkParameter.changes.key')
|
||||
.should('eq', 'governance.proposal.asset.minClose');
|
||||
cy.wrap(jsonFile)
|
||||
.its('terms.updateNetworkParameter.changes.value')
|
||||
.should('eq', '10s');
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-network-param-proposal-')
|
||||
).then((filePath) => {
|
||||
cy.readFile(String(filePath), { timeout: 14000 }).then(
|
||||
(jsonFile) => {
|
||||
cy.wrap(jsonFile)
|
||||
.its('rationale.description')
|
||||
.should('eq', 'E2E test for downloading proposals');
|
||||
cy.wrap(jsonFile)
|
||||
.its('terms.updateNetworkParameter.changes.key')
|
||||
.should('eq', 'governance.proposal.asset.minClose');
|
||||
cy.wrap(jsonFile)
|
||||
.its('terms.updateNetworkParameter.changes.value')
|
||||
.should('eq', '10s');
|
||||
}
|
||||
);
|
||||
// 3007-PNE-019
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -186,14 +187,21 @@ context.skip(
|
||||
'have.text',
|
||||
'Proposal will fail if enactment is earlier than the voting deadline'
|
||||
);
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-network-param-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false });
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
validateFeedBackMsg(
|
||||
'Invalid params: proposal_submission.terms.closing_timestamp (cannot be after enactment time)'
|
||||
);
|
||||
closeDialog();
|
||||
cy.get(minVoteDeadline).click();
|
||||
cy.get(enactmentDeadlineError).should('not.exist');
|
||||
});
|
||||
|
||||
// 3003-PMAN-001
|
||||
@@ -208,8 +216,17 @@ context.skip(
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
waitForProposalSubmitted();
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-new-market-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath }); // 3003-PMAN-003
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Unable to submit new market proposal with missing/invalid fields', function () {
|
||||
@@ -217,7 +234,7 @@ context.skip(
|
||||
'Invalid params: the transaction does not use a valid Vega command: unknown field "invalid" in vega.NewMarket';
|
||||
|
||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
||||
cy.get(inputError).should('have.length', 3);
|
||||
cy.get(newProposalTitle).type('Test new market proposal');
|
||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||
@@ -229,14 +246,28 @@ context.skip(
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-new-market-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false });
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should('have.text', errorMsg);
|
||||
validateFeedBackMsg(errorMsg);
|
||||
});
|
||||
|
||||
// Will fail if run after 'Able to submit update market proposal and vote for proposal'
|
||||
// 3002-PROP-022
|
||||
it('Unable to submit update market proposal without equity-like share in the market', function () {
|
||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||
cy.get('[data-testid="select-keypair-button"]').eq(0).click(); // switch to second wallet pub key
|
||||
stakingPageAssociateTokens('1');
|
||||
goToMakeNewProposal(governanceProposalType.UPDATE_MARKET);
|
||||
cy.get(newProposalTitle).type('Test update market proposal - rejected');
|
||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||
@@ -248,12 +279,25 @@ context.skip(
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-update-market-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false });
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||
cy.getByTestId('dialog-content')
|
||||
.find('p')
|
||||
.should('have.text', 'PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE');
|
||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||
validateDialogContentMsg('PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE');
|
||||
closeDialog();
|
||||
ethereumWalletConnect();
|
||||
stakingPageDisassociateAllTokens();
|
||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||
cy.get('[data-testid="select-keypair-button"]').eq(0).click();
|
||||
});
|
||||
|
||||
// 3002-PROP-020
|
||||
@@ -275,15 +319,25 @@ context.skip(
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-update-market-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false });
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||
cy.get(feedbackError).should(
|
||||
'have.text',
|
||||
validateFeedBackMsg(
|
||||
'Network error: the network blocked the transaction through the spam protection: party has insufficient associated governance tokens in their staking account to submit proposal request (ABCI code 89)'
|
||||
);
|
||||
});
|
||||
|
||||
// 3001-VOTE-092 3004-PMAC-001
|
||||
// 3001-VOTE-092 3004-PMAC-001 3004-PMAC-003
|
||||
it('Able to submit update market proposal and vote for proposal', function () {
|
||||
vegaWalletFaucetAssetsWithoutCheck(
|
||||
fUSDCId,
|
||||
@@ -313,11 +367,20 @@ context.skip(
|
||||
delay: 2,
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
waitForProposalSubmitted();
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-update-market-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath });
|
||||
});
|
||||
});
|
||||
navigateTo(navigation.proposals);
|
||||
cy.get('@EnactedMarketId').then((marketId) => {
|
||||
cy.contains(String(marketId))
|
||||
cy.contains(String(marketId).slice(0, 6))
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
@@ -341,12 +404,13 @@ context.skip(
|
||||
'contain.text',
|
||||
'Currently expected to pass'
|
||||
);
|
||||
cy.getByTestId('vote-breakdown-toggle').click();
|
||||
getProposalInformationFromTable('Expected to pass')
|
||||
.contains('👍 by token vote')
|
||||
.should('be.visible');
|
||||
});
|
||||
|
||||
// 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001
|
||||
// 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001
|
||||
it('Able to submit new asset proposal using min deadlines', function () {
|
||||
const proposalTitle = 'Test new asset proposal';
|
||||
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
||||
@@ -362,25 +426,23 @@ context.skip(
|
||||
cy.get(minVoteDeadline).click();
|
||||
cy.get(minValidationDeadline).click();
|
||||
cy.get(minEnactDeadline).click();
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-new-asset-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath, submit: false }); // 3005-PASN-003
|
||||
});
|
||||
});
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('Proposal waiting for node vote', proposalTimeout).should(
|
||||
'be.visible'
|
||||
);
|
||||
closeDialog();
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
// cannot submit a proposal with ERC20 address already in use
|
||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||
cy.getByTestId('dialog-content')
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get('p').should(
|
||||
'have.text',
|
||||
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
||||
);
|
||||
});
|
||||
validateDialogContentMsg('PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE');
|
||||
closeDialog();
|
||||
navigateTo(navigation.proposals);
|
||||
cy.contains(proposalTitle)
|
||||
@@ -389,6 +451,7 @@ context.skip(
|
||||
.within(() => {
|
||||
cy.getByTestId(viewProposalBtn).click();
|
||||
});
|
||||
cy.getByTestId('proposal-terms-toggle').click();
|
||||
cy.getByTestId(proposalTermsSection).within(() => {
|
||||
cy.contains('USDT Coin').should('be.visible');
|
||||
cy.contains('USDT').should('be.visible');
|
||||
@@ -397,15 +460,8 @@ context.skip(
|
||||
|
||||
it('Unable to submit new asset proposal with missing/invalid fields', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
||||
cy.get(inputError).should('have.length', 3);
|
||||
cy.get(newProposalTitle).type('Invalid new asset proposal');
|
||||
cy.get(newProposalDescription).type('Invalid E2E test for proposals');
|
||||
cy.get(proposalValidationDeadline).clear().type('2');
|
||||
cy.get(newProposalSubmitButton).click();
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
|
||||
it('Able to submit update asset proposal using min deadline', function () {
|
||||
@@ -416,8 +472,17 @@ context.skip(
|
||||
enterUpdateAssetProposalDetails();
|
||||
cy.get(minVoteDeadline).click();
|
||||
cy.get(minEnactDeadline).click();
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
waitForProposalSubmitted();
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-update-asset-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath });
|
||||
});
|
||||
});
|
||||
navigateTo(navigation.proposals);
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.get(proposalType)
|
||||
@@ -425,7 +490,7 @@ context.skip(
|
||||
.parentsUntil(proposalListItem)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
||||
cy.get(proposalDetails).should('contain.text', assetId.slice(0, 6)); // 3001-VOTE-029
|
||||
cy.getByTestId(viewProposalBtn).click();
|
||||
});
|
||||
});
|
||||
@@ -433,37 +498,97 @@ context.skip(
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
// 3001-VOTE-030 3001-VOTE-031
|
||||
cy.getByTestId(proposalTermsSection).within(() => {
|
||||
cy.contains('UpdateAsset').should('be.visible');
|
||||
cy.contains('UpdateERC20').should('be.visible');
|
||||
cy.contains('"lifetimeLimit": "10"').should('be.visible');
|
||||
cy.getByTestId('proposal-terms-toggle').click();
|
||||
cy.getByTestId('proposal-terms').within(() => {
|
||||
getProposalInformationFromTable('assetId').should('have.text', assetId);
|
||||
getProposalInformationFromTable('lifetimeLimit').should(
|
||||
'have.text',
|
||||
'10'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// 3006-PASC-001 3006-PASC-003
|
||||
it('Able to submit update asset proposal using max deadline', function () {
|
||||
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
||||
enterUpdateAssetProposalDetails();
|
||||
cy.get(maxVoteDeadline).click();
|
||||
cy.get(maxEnactDeadline).click();
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
waitForProposalSubmitted();
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-update-asset-proposal-')
|
||||
).then((filePath) => {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Unable to submit edit asset proposal with missing/invalid fields', function () {
|
||||
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
||||
cy.get(inputError).should('have.length', 3);
|
||||
});
|
||||
|
||||
function getFormattedTime() {
|
||||
const now = new Date();
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
const month = now.toLocaleString('en-US', { month: 'short' });
|
||||
const year = now.getFullYear().toString();
|
||||
const hours = now.getHours().toString().padStart(2, '0');
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
it('Able to download and submit freeform proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||
// 3008-PFRO-006
|
||||
cy.get(newProposalTitle)
|
||||
.siblings()
|
||||
.should('contain.text', '(100 characters or less)'); // 3008-PFRO-007
|
||||
// 3008-PFRO-005
|
||||
cy.get(newProposalTitle).type('Test freeform proposal form');
|
||||
// 3008-PFRO-009
|
||||
cy.get(newProposalDescription)
|
||||
.siblings()
|
||||
.should('contain.text', '(20,000 characters or less)'); // 3008-PFRO-010
|
||||
// 3008-PFRO-008 3002-PROP-012 3002-PROP-016
|
||||
cy.get(newProposalDescription).type(
|
||||
'E2E test for downloading freeform proposal'
|
||||
);
|
||||
// 3008-PFRO-012
|
||||
cy.get(minVoteDeadline).should('exist'); // 3002-PROP-008
|
||||
cy.get(maxVoteDeadline).should('exist');
|
||||
// 3008-PFRO-011
|
||||
cy.get(proposalVoteDeadline).clear().type('2');
|
||||
// 3008-PFRO-013 3008-PFRO-014
|
||||
cy.getByTestId('voting-date').invoke('text').should('not.be.empty');
|
||||
// 3008-PFRO-015
|
||||
cy.log('Download updated proposal file');
|
||||
cy.get(proposalDownloadBtn)
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.wrap(
|
||||
getDownloadedProposalJsonPath('vega-freeform-proposal-')
|
||||
).then((filePath) => {
|
||||
// 3008-PFRO-019
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
submitUniqueRawProposal({ proposalBody: filePath });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return `${day}-${month}-${year}-${hours}-${minutes}`;
|
||||
after('Disassociate from second wallet key if present', function () {
|
||||
cy.reload();
|
||||
waitForSpinner();
|
||||
ethereumWalletConnect();
|
||||
dissociateFromSecondWalletKey();
|
||||
});
|
||||
|
||||
function validateDialogContentMsg(expectedMsg: string) {
|
||||
cy.getByTestId('dialog-content')
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get('p').should('have.text', expectedMsg);
|
||||
});
|
||||
}
|
||||
|
||||
function validateFeedBackMsg(expectedMsg: string) {
|
||||
cy.get(feedbackError).should('have.text', expectedMsg);
|
||||
}
|
||||
|
||||
function enterUpdateAssetProposalDetails() {
|
||||
|
||||
@@ -86,11 +86,12 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||
});
|
||||
|
||||
it('Newly created proposals list - shows title and portion of summary', function () {
|
||||
const proposalPath = '/proposals/new-market-raw.json';
|
||||
const enactmentTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
||||
const proposalPath = 'src/fixtures/proposals/new-market-raw.json';
|
||||
const proposalTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
||||
submitUniqueRawProposal({
|
||||
proposalBody: proposalPath,
|
||||
enactmentTimestamp: enactmentTimestamp,
|
||||
enactmentTimestamp: proposalTimestamp,
|
||||
closingTimestamp: proposalTimestamp,
|
||||
}); // 3001-VOTE-052
|
||||
// 3001-VOTE-008
|
||||
// 3001-VOTE-034
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
import {
|
||||
clickOnValidatorFromList,
|
||||
closeStakingDialog,
|
||||
stakingPageAssociateTokens,
|
||||
stakingValidatorPageAddStake,
|
||||
waitForBeginningOfEpoch,
|
||||
} from '../../support/staking.functions';
|
||||
@@ -30,20 +29,22 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
||||
turnTelemetryOff();
|
||||
cy.visit('/');
|
||||
waitForSpinner();
|
||||
depositAsset(vegaAssetAddress, '1000', 18);
|
||||
cy.validatorsSelfDelegate();
|
||||
ethereumWalletConnect();
|
||||
cy.connectVegaWallet();
|
||||
cy.VegaWalletTopUpRewardsPool(30, 200);
|
||||
navigateTo(navigation.validators);
|
||||
depositAsset(vegaAssetAddress, '1000', 18);
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'contain.text',
|
||||
'Collateral'
|
||||
);
|
||||
vegaWalletTeardown();
|
||||
stakingPageAssociateTokens('6000');
|
||||
cy.associateTokensToVegaWallet('6000');
|
||||
navigateTo(navigation.validators);
|
||||
cy.VegaWalletTopUpRewardsPool();
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'6,000.0',
|
||||
txTimeout
|
||||
);
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
clickOnValidatorFromList(0);
|
||||
stakingValidatorPageAddStake('3000');
|
||||
closeStakingDialog();
|
||||
|
||||
@@ -109,6 +109,7 @@ context(
|
||||
cy.getByTestId(userStake, epochTimeout)
|
||||
.first()
|
||||
.should('have.text', '2.00');
|
||||
waitForBeginningOfEpoch();
|
||||
cy.getByTestId('total-stake').first().realHover();
|
||||
cy.getByTestId('staked-by-user-tooltip')
|
||||
.first()
|
||||
@@ -379,6 +380,7 @@ context(
|
||||
});
|
||||
|
||||
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
|
||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||
stakingPageAssociateTokens('3');
|
||||
verifyUnstakedBalance(3.0);
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
@@ -485,6 +487,7 @@ context(
|
||||
});
|
||||
|
||||
afterEach('Teardown Wallet', function () {
|
||||
navigateTo(navigation.home);
|
||||
vegaWalletTeardown();
|
||||
});
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ const associatedKey = '[data-testid="associated-key"]';
|
||||
const associatedAmount = '[data-testid="associated-amount"]';
|
||||
const associateCompleteText = '[data-testid="transaction-complete-body"]';
|
||||
const disassociationWarning = '[data-testid="disassociation-warning"]';
|
||||
const vegaWallet = '[data-testid="vega-wallet"]';
|
||||
const vegaWallet = 'aside [data-testid="vega-wallet"]';
|
||||
|
||||
context(
|
||||
'Token association flow - with eth and vega wallets connected',
|
||||
@@ -78,30 +78,15 @@ context(
|
||||
//0005-ETXN-003
|
||||
//0005-ETXN-005
|
||||
stakingPageAssociateTokens('2', { skipConfirmation: true });
|
||||
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '0.00');
|
||||
validateWalletCurrency('Pending association', '2.00');
|
||||
validateWalletCurrency('Total associated after pending', '2.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
|
||||
// 0005-ETXN-002
|
||||
verifyEthWalletAssociatedBalance('2.0');
|
||||
|
||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
|
||||
@@ -116,15 +101,11 @@ context(
|
||||
verifyEthWalletAssociatedBalance('2.0');
|
||||
verifyEthWalletTotalAssociatedBalance('6,002.00');
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
||||
stakingPageDisassociateTokens('2');
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '2.00');
|
||||
validateWalletCurrency('Pending association', '2.00');
|
||||
validateWalletCurrency('Total associated after pending', '0.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
cy.get(
|
||||
'[data-testid="eth-wallet-associated-balances"]:visible',
|
||||
txTimeout
|
||||
@@ -137,38 +118,26 @@ context(
|
||||
stakingPageAssociateTokens('1001', { approve: true });
|
||||
verifyEthWalletAssociatedBalance('1,001.00');
|
||||
verifyEthWalletTotalAssociatedBalance('7,001.00');
|
||||
cy.get(vegaWallet)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'1,001.00'
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
'1,001.00'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to disassociate a partial amount of tokens currently associated', function () {
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
||||
stakingPageDisassociateTokens('1');
|
||||
verifyEthWalletAssociatedBalance('1.0');
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
1.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 1.0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to disassociate all tokens - using max', function () {
|
||||
@@ -176,15 +145,11 @@ context(
|
||||
const warningText =
|
||||
'Warning: Any tokens that have been nominated to a node will sacrifice rewards they are due for the current epoch. If you do not wish to sacrifice these, you should remove stake from a node at the end of an epoch before disassociation.';
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
||||
cy.get(ethWalletDissociateButton).click();
|
||||
cy.get(disassociationWarning).should('contain', warningText);
|
||||
stakingPageDisassociateAllTokens();
|
||||
@@ -202,14 +167,9 @@ context(
|
||||
'not.exist'
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
0.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 0.0);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to associate and disassociate vesting contract tokens', function () {
|
||||
@@ -224,38 +184,22 @@ context(
|
||||
type: 'contract',
|
||||
skipConfirmation: true,
|
||||
});
|
||||
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '0.00');
|
||||
validateWalletCurrency('Pending association', '2.00');
|
||||
validateWalletCurrency('Total associated after pending', '2.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
verifyEthWalletAssociatedBalance('2.0');
|
||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||
stakingPageDisassociateTokens('1', {
|
||||
type: 'contract',
|
||||
skipConfirmation: true,
|
||||
});
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '2.00');
|
||||
validateWalletCurrency('Pending association', '1.00');
|
||||
validateWalletCurrency('Total associated after pending', '1.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
verifyEthWalletAssociatedBalance('1.0');
|
||||
verifyEthWalletTotalAssociatedBalance('1.0');
|
||||
});
|
||||
@@ -267,6 +211,7 @@ context(
|
||||
// 1004-ASSO-022
|
||||
stakingPageAssociateTokens('21', { type: 'wallet' });
|
||||
cy.get('button').contains('Select a validator to nominate').click();
|
||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
||||
stakingPageAssociateTokens('37', { type: 'contract' });
|
||||
cy.get(vestingContractSection)
|
||||
.first()
|
||||
@@ -286,28 +231,18 @@ context(
|
||||
);
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 21);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
58
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 58);
|
||||
});
|
||||
stakingPageDisassociateTokens('6', { type: 'contract' });
|
||||
cy.get(vestingContractSection)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 31);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
52
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 52);
|
||||
});
|
||||
navigateTo(navigation.validators);
|
||||
stakingPageDisassociateTokens('9', { type: 'wallet' });
|
||||
cy.get(vegaInWalletSection)
|
||||
@@ -315,14 +250,9 @@ context(
|
||||
.within(() => {
|
||||
cy.get(associatedAmount, txTimeout).should('contain', 12);
|
||||
});
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
43
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 43);
|
||||
});
|
||||
});
|
||||
|
||||
it('Not able to associate more tokens than owned', function () {
|
||||
@@ -339,14 +269,9 @@ context(
|
||||
// 1004-ASSO-004
|
||||
it('Pending association outside of app is shown', function () {
|
||||
vegaWalletAssociate('2');
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '0.00');
|
||||
validateWalletCurrency('Pending association', '2.00');
|
||||
validateWalletCurrency('Total associated after pending', '2.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
validateWalletCurrency('Associated', '2.00');
|
||||
});
|
||||
|
||||
@@ -355,14 +280,9 @@ context(
|
||||
cy.wrap(validateWalletCurrency('Associated', '2.00')).then(() => {
|
||||
vegaWalletDisassociate('2');
|
||||
});
|
||||
cy.getByTestId('currency-title', txTimeout).should(
|
||||
'have.length.above',
|
||||
6
|
||||
);
|
||||
validateWalletCurrency('Associated', '2.00');
|
||||
validateWalletCurrency('Pending association', '2.00');
|
||||
validateWalletCurrency('Total associated after pending', '0.00');
|
||||
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||
validateWalletCurrency('Associated', '0.00');
|
||||
});
|
||||
|
||||
@@ -381,14 +301,9 @@ context(
|
||||
Cypress.env('vegaWalletPublicKey2')
|
||||
);
|
||||
stakingPageAssociateTokens('2');
|
||||
cy.get(vegaWallet)
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||
'contain',
|
||||
2.0
|
||||
);
|
||||
});
|
||||
cy.get(vegaWallet).within(() => {
|
||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
||||
});
|
||||
cy.get(associateCompleteText).should(
|
||||
'have.text',
|
||||
`Vega key ${Cypress.env(
|
||||
|
||||
@@ -15,13 +15,7 @@ const balanceAvailable = 'BALANCE_AVAILABLE_value';
|
||||
const withdrawalThreshold = 'WITHDRAWAL_THRESHOLD_value';
|
||||
const delayTime = 'DELAY_TIME_value';
|
||||
const submitWithdrawalButton = 'submit-withdrawal';
|
||||
const dialogTitle = 'dialog-title';
|
||||
const dialogClose = 'dialog-close';
|
||||
const txExplorerLink = 'tx-block-explorer';
|
||||
const withdrawalAssetSymbol = 'withdrawal-asset-symbol';
|
||||
const withdrawalAmount = 'withdrawal-amount';
|
||||
const withdrawalRecipient = 'withdrawal-recipient';
|
||||
const withdrawFundsButton = 'withdraw-funds';
|
||||
const completeWithdrawalButton = 'complete-withdrawal';
|
||||
const tableTxHash = '[col-id="txHash"]';
|
||||
const tableAssetSymbol = '[col-id="asset.symbol"]';
|
||||
@@ -30,14 +24,16 @@ const tableReceiverAddress = '[col-id="details.receiverAddress"]';
|
||||
const tableWithdrawnTimeStamp = '[col-id="withdrawnTimestamp"]';
|
||||
const tableWithdrawnStatus = '[col-id="status"]';
|
||||
const tableCreatedTimeStamp = '[col-id="createdTimestamp"]';
|
||||
const toastContent = 'toast-content';
|
||||
const toast = 'toast';
|
||||
const toastPanel = 'toast-panel';
|
||||
const toastClose = 'toast-close';
|
||||
const withdrawalDialogContent = 'dialog-content';
|
||||
const toastCompleteWithdrawal = 'toast-complete-withdrawal';
|
||||
const usdtName = 'USDC (local)';
|
||||
const usdcEthAddress = '0x1b8a1B6CBE5c93609b46D1829Cc7f3Cb8eeE23a0';
|
||||
const usdcSymbol = 'tUSDC';
|
||||
const usdtSelectValue =
|
||||
'993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede';
|
||||
const truncatedWithdrawalEthAddress = '0xEe7D…22d94F';
|
||||
const formValidationError = 'input-error-text';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
@@ -107,29 +103,35 @@ context(
|
||||
cy.getByTestId(amountInput).click().type('120');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
|
||||
cy.contains('Awaiting network confirmation').should('be.visible');
|
||||
// assert withdrawal request
|
||||
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||
'have.text',
|
||||
'Transaction complete'
|
||||
);
|
||||
cy.getByTestId(txExplorerLink)
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/txs/');
|
||||
cy.getByTestId(withdrawalAssetSymbol).should('have.text', usdcSymbol);
|
||||
cy.getByTestId(withdrawalAmount).should('have.text', '120.00');
|
||||
cy.getByTestId(withdrawalRecipient)
|
||||
.should('have.text', truncatedWithdrawalEthAddress)
|
||||
.and('have.attr', 'href')
|
||||
.and('contain', `/address/${Cypress.env('ethWalletPublicKey')}`);
|
||||
cy.getByTestId(withdrawFundsButton).click();
|
||||
cy.getByTestId(toast)
|
||||
.first(txTimeout)
|
||||
.should('contain.text', 'Funds unlocked')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
cy.getByTestId(toastPanel).should(
|
||||
'contain.text',
|
||||
'Withdraw 120.00 tUSDC'
|
||||
);
|
||||
cy.getByTestId(toastCompleteWithdrawal).click();
|
||||
cy.getByTestId(toastClose).click();
|
||||
});
|
||||
// withdrawal complete
|
||||
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||
'have.text',
|
||||
'Withdraw asset complete'
|
||||
);
|
||||
cy.getByTestId(dialogClose).click();
|
||||
cy.getByTestId(toast)
|
||||
.first(txTimeout)
|
||||
.should('contain.text', 'The withdrawal has been approved.')
|
||||
.within(() => {
|
||||
cy.getByTestId(toastPanel).should(
|
||||
'contain.text',
|
||||
'Withdraw 120.00 tUSDC'
|
||||
);
|
||||
});
|
||||
cy.getByTestId(toast)
|
||||
.last(txTimeout)
|
||||
.should('contain.text', 'Transaction confirmed')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
});
|
||||
// withdrawal history for complete withdrawal displayed
|
||||
cy.get(tableWithdrawnStatus)
|
||||
.eq(1, txTimeout)
|
||||
@@ -168,13 +170,17 @@ context(
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
|
||||
cy.contains('Awaiting network confirmation').should('be.visible');
|
||||
// assert withdrawal request
|
||||
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||
'have.text',
|
||||
'Transaction complete'
|
||||
);
|
||||
cy.getByTestId(dialogClose).click();
|
||||
cy.getByTestId(toast)
|
||||
.first(txTimeout)
|
||||
.should('contain.text', 'Funds unlocked')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
cy.getByTestId(toastPanel).should(
|
||||
'contain.text',
|
||||
'Withdraw 110.00 tUSDC'
|
||||
);
|
||||
cy.getByTestId(toastClose).click();
|
||||
});
|
||||
cy.get(tableTxHash)
|
||||
.eq(1)
|
||||
.should('have.text', 'Complete withdrawal')
|
||||
@@ -189,28 +195,75 @@ context(
|
||||
cy.get(tableCreatedTimeStamp).should('not.be.empty');
|
||||
});
|
||||
ethereumWalletConnect();
|
||||
cy.getByTestId(completeWithdrawalButton).click();
|
||||
cy.getByTestId(toastContent)
|
||||
.last()
|
||||
cy.getByTestId(completeWithdrawalButton).first().click();
|
||||
cy.getByTestId(toast)
|
||||
.last(txTimeout)
|
||||
.should('contain.text', 'Awaiting confirmation')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
});
|
||||
cy.getByTestId(toastContent)
|
||||
.first()
|
||||
cy.getByTestId(toast)
|
||||
.first(txTimeout)
|
||||
.should('contain.text', 'The withdrawal has been approved.')
|
||||
.within(() => {
|
||||
cy.getByTestId(toastPanel).should('contain.text', '110.00', 'tUSDC');
|
||||
});
|
||||
cy.getByTestId(toastContent)
|
||||
.last()
|
||||
cy.getByTestId(toast)
|
||||
.last(txTimeout)
|
||||
.should('contain.text', 'Transaction confirmed')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('Unable to withdraw asset on pub key view', function () {
|
||||
it('Should be able to see withdrawal details from toast', function () {
|
||||
cy.getByTestId(withdraw).click();
|
||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(withdrawalThreshold).should(
|
||||
'have.text',
|
||||
'100,000.00000T'
|
||||
);
|
||||
cy.getByTestId(amountInput).click().type('50');
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
cy.getByTestId(toast)
|
||||
.first(txTimeout)
|
||||
.should('contain.text', 'Funds unlocked')
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link').should('exist');
|
||||
cy.getByTestId(toastPanel).should(
|
||||
'contain.text',
|
||||
'Withdraw 50.00 tUSDC'
|
||||
);
|
||||
cy.contains('save your withdrawal details').click();
|
||||
});
|
||||
cy.getByTestId(withdrawalDialogContent)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId('assetSource_value').should(
|
||||
'have.text',
|
||||
'0x1b8a1B6CBE5c93609b46D1829Cc7f3Cb8eeE23a0'
|
||||
);
|
||||
cy.getByTestId('amount_value').should('have.text', '5000000');
|
||||
cy.getByTestId('nonce_value').invoke('text').should('not.be.empty');
|
||||
cy.getByTestId('signatures_value')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('targetAddress_value').should(
|
||||
'have.text',
|
||||
Cypress.env('ethWalletPublicKey')
|
||||
);
|
||||
cy.getByTestId('creation_value')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
cy.getByTestId(dialogClose).click();
|
||||
});
|
||||
|
||||
// Skipping test due to bug #3882
|
||||
it.skip('Unable to withdraw asset on pub key view', function () {
|
||||
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey');
|
||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||
|
||||
@@ -224,10 +277,11 @@ context(
|
||||
cy.get('select').select(usdtSelectValue, { force: true });
|
||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||
cy.getByTestId(amountInput).click().type('100');
|
||||
cy.pause();
|
||||
cy.getByTestId(submitWithdrawalButton).click();
|
||||
});
|
||||
|
||||
cy.getByTestId('dialog-content')
|
||||
cy.getByTestId(withdrawalDialogContent)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.get('h1').should('have.text', 'Transaction failed');
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
import { mockNetworkUpgradeProposal } from '../../support/proposal.functions';
|
||||
|
||||
const proposalDocumentationLink = '[data-testid="proposal-documentation-link"]';
|
||||
const newProposalLink = '[data-testid="new-proposal-link"]';
|
||||
const governanceDocsUrl = 'https://vega.xyz/governance';
|
||||
const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||
|
||||
@@ -32,6 +31,14 @@ context(
|
||||
verifyPageHeader('Proposals');
|
||||
});
|
||||
|
||||
// 3002-PROP-023 3004-PMAC-002 3005-PASN-002 3006-PASC-002 3007-PNEC-002 3008-PFRO-003
|
||||
it('should have button for link to more information on proposals', function () {
|
||||
const proposalsUrl = 'https://docs.vega.xyz/mainnet/tutorials/proposals';
|
||||
cy.getByTestId('new-proposal-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href', proposalsUrl);
|
||||
});
|
||||
|
||||
it('should be able to see a working link for - find out more about Vega governance', function () {
|
||||
// 3001-VOTE-001
|
||||
cy.get(proposalDocumentationLink)
|
||||
@@ -54,17 +61,62 @@ context(
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('should be able to see button for - new proposal', function () {
|
||||
// 3001-VOTE-002
|
||||
cy.get(newProposalLink)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'New proposal')
|
||||
.and('have.attr', 'href')
|
||||
.and('equal', '/proposals/propose');
|
||||
// 3007-PNE-021
|
||||
it('should have documentation links for network parameter proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/network-parameter-proposal');
|
||||
});
|
||||
|
||||
it.skip('should be able to see a connect wallet button - if vega wallet disconnected and user is submitting new proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||
// 3003-PMAN-002 3003-PMAN-005
|
||||
it('should have documentation links for new market proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/new-market-proposal');
|
||||
});
|
||||
|
||||
// 3004-PMAC-005
|
||||
it('should have documentation links for update market proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.UPDATE_MARKET);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/update-market-proposal');
|
||||
});
|
||||
|
||||
// 3005-PASN-002 005-PASN-005
|
||||
it('should have documentation links for new asset proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/new-asset-proposal');
|
||||
});
|
||||
|
||||
// 3006-PASC-002 3006-PASC-005
|
||||
it('should have documentation links for update asset proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/update-asset-proposal');
|
||||
});
|
||||
|
||||
// 3008-PFRO-003 3008-PFRO-017
|
||||
it('should have documentation links for freeform proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||
cy.getByTestId('proposal-docs-link')
|
||||
.find('a')
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', '/tutorials/proposals/freeform-proposal');
|
||||
});
|
||||
|
||||
it('should be able to see a connect wallet button - if vega wallet disconnected and user is submitting new proposal', function () {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
cy.get(connectToVegaWalletButton)
|
||||
.should('be.visible')
|
||||
.and('have.text', 'Connect Vega wallet');
|
||||
@@ -128,6 +180,7 @@ context(
|
||||
.first()
|
||||
.find('[data-testid="view-proposal-btn"]')
|
||||
.click();
|
||||
cy.url().should('contain', '/protocol-upgrades/v1');
|
||||
cy.getByTestId('protocol-upgrade-proposal').within(() => {
|
||||
cy.get('h1').should('have.text', 'Vega Release v1');
|
||||
cy.getByTestId('protocol-upgrade-block-height').should(
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { stakingPageDisassociateAllTokens } from './staking.functions';
|
||||
|
||||
const tokenDropDown = 'state-trigger';
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
export enum navigation {
|
||||
section = 'nav',
|
||||
home = '[href="/"]',
|
||||
vesting = '[href="/token/redeem"]',
|
||||
validators = '[href="/validators"]',
|
||||
rewards = '[href="/rewards"]',
|
||||
@@ -18,6 +21,7 @@ export function convertTokenValueToNumber(subject: string) {
|
||||
}
|
||||
|
||||
const topLevelRoutes = [
|
||||
navigation.home,
|
||||
navigation.proposals,
|
||||
navigation.validators,
|
||||
navigation.rewards,
|
||||
@@ -97,3 +101,25 @@ export function turnTelemetryOff() {
|
||||
win.localStorage.setItem('vega_telemetry_on', 'false')
|
||||
);
|
||||
}
|
||||
|
||||
export function dissociateFromSecondWalletKey() {
|
||||
const secondWalletKey = Cypress.env('vegaWalletPublicKey2Short');
|
||||
cy.getByTestId('vega-in-wallet')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestId('eth-wallet-associated-balances')
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId('associated-key')
|
||||
.invoke('text')
|
||||
.as('associatedPubKey');
|
||||
});
|
||||
});
|
||||
cy.get('@associatedPubKey').then((associatedPubKey) => {
|
||||
if (associatedPubKey == secondWalletKey) {
|
||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||
cy.get('[data-testid="select-keypair-button"]').eq(0).click();
|
||||
stakingPageDisassociateAllTokens();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -59,11 +59,11 @@ export function submitUniqueRawProposal(proposalFields: {
|
||||
submit?: boolean;
|
||||
}) {
|
||||
goToMakeNewProposal(governanceProposalType.RAW);
|
||||
let proposalBodyPath = '/proposals/raw.json';
|
||||
let proposalBodyPath = 'src/fixtures/proposals/raw.json';
|
||||
if (proposalFields.proposalBody) {
|
||||
proposalBodyPath = proposalFields.proposalBody;
|
||||
}
|
||||
cy.fixture(proposalBodyPath).then((rawProposal) => {
|
||||
cy.readFile(proposalBodyPath).then((rawProposal) => {
|
||||
if (proposalFields.proposalTitle) {
|
||||
rawProposal.rationale.title = proposalFields.proposalTitle;
|
||||
cy.wrap(proposalFields.proposalTitle).as('proposalTitle');
|
||||
@@ -73,7 +73,10 @@ export function submitUniqueRawProposal(proposalFields: {
|
||||
}
|
||||
if (proposalFields.closingTimestamp) {
|
||||
rawProposal.terms.closingTimestamp = proposalFields.closingTimestamp;
|
||||
} else {
|
||||
} else if (
|
||||
!proposalFields.closingTimestamp &&
|
||||
!proposalFields.proposalBody
|
||||
) {
|
||||
const minTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
||||
rawProposal.terms.closingTimestamp = minTimeStamp;
|
||||
}
|
||||
@@ -106,7 +109,7 @@ export function enterUniqueFreeFormProposalBody(
|
||||
'this is a e2e freeform proposal description'
|
||||
);
|
||||
cy.get(proposalVoteDeadline).clear().click().type(timestamp);
|
||||
cy.getByTestId('proposal-submit').should('be.visible').click();
|
||||
cy.getByTestId('proposal-download-json').should('be.visible').click();
|
||||
}
|
||||
|
||||
export function getProposalFromTitle(proposalTitle: string) {
|
||||
@@ -188,6 +191,7 @@ export function goToMakeNewProposal(proposalType: governanceProposalType) {
|
||||
}
|
||||
}
|
||||
|
||||
// 3001-VOTE-013 3001-VOTE-014
|
||||
export function waitForProposalSubmitted() {
|
||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||
'be.visible'
|
||||
@@ -222,6 +226,23 @@ export function createFreeformProposal(proposalTitle: string) {
|
||||
navigateTo(navigation.proposals);
|
||||
}
|
||||
|
||||
export function getDownloadedProposalJsonPath(proposalType: string) {
|
||||
const downloadPath = './cypress/downloads/';
|
||||
const filepath = downloadPath + proposalType + getFormattedTime() + '.json';
|
||||
return filepath;
|
||||
}
|
||||
|
||||
function getFormattedTime() {
|
||||
const now = new Date();
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
const month = now.toLocaleString('en-US', { month: 'short' });
|
||||
const year = now.getFullYear().toString();
|
||||
const hours = now.getHours().toString().padStart(2, '0');
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
|
||||
return `${day}-${month}-${year}-${hours}-${minutes}`;
|
||||
}
|
||||
|
||||
export enum governanceProposalType {
|
||||
NETWORK_PARAMETER = 'Network parameter',
|
||||
NEW_MARKET = 'New market',
|
||||
|
||||
@@ -221,7 +221,7 @@ export function ensureSpecifiedUnstakedTokensAreAssociated(
|
||||
}
|
||||
|
||||
export function closeStakingDialog() {
|
||||
cy.getByTestId('dialog-title').should(
|
||||
cy.getByTestId('dialog-title', txTimeout).should(
|
||||
'contain.text',
|
||||
'At the beginning of the next epoch'
|
||||
);
|
||||
@@ -236,8 +236,8 @@ export function validateWalletCurrency(
|
||||
currencyTitle: string,
|
||||
expectedAmount: string
|
||||
) {
|
||||
cy.get("[data-testid='currency-title']")
|
||||
.contains(currencyTitle)
|
||||
cy.get("[data-testid='currency-title']", txTimeout)
|
||||
.contains(currencyTitle, txTimeout)
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => {
|
||||
|
||||
@@ -5,7 +5,7 @@ const capsuleWalletConnectButton = '[data-testid="web3-connector-Unknown"]';
|
||||
|
||||
export function ethereumWalletConnect() {
|
||||
cy.highlight('Connecting Eth Wallet');
|
||||
cy.get(connectToEthButton).within(() => {
|
||||
cy.get(connectToEthButton, { timeout: 60000 }).within(() => {
|
||||
cy.contains('Connect Ethereum wallet to associate $VEGA')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
@@ -19,7 +19,7 @@ const ethStakingBridgeContractAddress = Cypress.env(
|
||||
);
|
||||
const ethProviderUrl = Cypress.env('ethProviderUrl');
|
||||
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
||||
const transactionTimeout = 100000;
|
||||
const transactionTimeout = { timeout: 100000, log: false };
|
||||
const Erc20BridgeAddress = '0x9708FF7510D4A7B9541e1699d15b53Ecb1AFDc54';
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider({ url: ethProviderUrl });
|
||||
@@ -43,10 +43,7 @@ export async function depositAsset(
|
||||
const faucet = new Token(assetEthAddress, signer);
|
||||
cy.wrap(
|
||||
faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(decimalPlaces + 1)),
|
||||
{
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}
|
||||
transactionTimeout
|
||||
).then(() => {
|
||||
const collateralBridge = new CollateralBridge(Erc20BridgeAddress, signer);
|
||||
cy.wrap(
|
||||
@@ -55,7 +52,7 @@ export async function depositAsset(
|
||||
amount + '0'.repeat(decimalPlaces),
|
||||
'0x' + vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout, log: false }
|
||||
transactionTimeout
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -79,13 +76,13 @@ export async function vegaWalletTeardown() {
|
||||
}
|
||||
});
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
cy.get(associatedAmountInWallet, {
|
||||
timeout: transactionTimeout,
|
||||
})
|
||||
.should('have.length', 1, { timeout: transactionTimeout })
|
||||
.contains('0.00', {
|
||||
timeout: transactionTimeout,
|
||||
});
|
||||
cy.get(associatedAmountInWallet, transactionTimeout).should(
|
||||
'have.length',
|
||||
1
|
||||
);
|
||||
cy.get(associatedAmountInWallet)
|
||||
.first(transactionTimeout)
|
||||
.should('have.text', '0.00');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -109,7 +106,7 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
||||
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
||||
cy.wrap(
|
||||
stakingBridgeContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
{ timeout: transactionTimeout }
|
||||
transactionTimeout
|
||||
).then((stakeBalance) => {
|
||||
if (Number(stakeBalance) != 0) {
|
||||
cy.get(vegaWalletContainer).within(() => {
|
||||
@@ -122,31 +119,25 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
||||
String(stakeBalance),
|
||||
vegaWalletPubKey
|
||||
),
|
||||
{ timeout: transactionTimeout }
|
||||
transactionTimeout
|
||||
);
|
||||
cy.wrap(
|
||||
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
{
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}
|
||||
transactionTimeout
|
||||
).then((vestingAmount) => {
|
||||
if (Number(vestingAmount) != 0) {
|
||||
cy.contains('Associated', {
|
||||
timeout: transactionTimeout,
|
||||
})
|
||||
cy.contains('Associated', transactionTimeout)
|
||||
.parent()
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.getByTestId('currency-value', {
|
||||
timeout: transactionTimeout,
|
||||
})
|
||||
.should('have.length', 1)
|
||||
cy.getByTestId('currency-value', transactionTimeout)
|
||||
.first()
|
||||
.invoke('text')
|
||||
.as('displayedAmount');
|
||||
cy.get('@displayedAmount', {
|
||||
timeout: transactionTimeout,
|
||||
}).should('not.eq', $associatedAmount);
|
||||
cy.get('@displayedAmount', transactionTimeout).should(
|
||||
'not.eq',
|
||||
$associatedAmount
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -158,14 +149,14 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
||||
|
||||
async function vegaWalletTeardownVesting(vestingContract: TokenVesting) {
|
||||
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
||||
cy.wrap(vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey), {
|
||||
timeout: transactionTimeout,
|
||||
log: false,
|
||||
}).then((vestingAmount) => {
|
||||
cy.wrap(
|
||||
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||
transactionTimeout
|
||||
).then((vestingAmount) => {
|
||||
if (Number(vestingAmount) != 0) {
|
||||
cy.wrap(
|
||||
vestingContract.remove_stake(String(vestingAmount), vegaWalletPubKey),
|
||||
{ timeout: transactionTimeout }
|
||||
transactionTimeout
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,10 +5,11 @@ NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_FAIRGROUND=false
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://stagnet1.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
|
||||
@@ -6,7 +6,7 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https:/
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=#
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
|
||||
|
||||
@@ -3,7 +3,7 @@ NX_VEGA_ENV=MAINNET
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_ETHEREUM_PROVIDER_URL=https://eth-mainnet.gateway.pokt.network/v1/lb/6684b914570bbfa533ba9324
|
||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/3ba145ccc2884bcd91213d8dc989ca76
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://stagnet1.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||
|
||||
@@ -13,4 +13,4 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-testnet-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
@@ -7,7 +7,7 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https:/
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './multisig-incorrect-notice';
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { MultisigIncorrectNotice } from './multisig-incorrect-notice';
|
||||
|
||||
jest.mock('@vegaprotocol/web3', () => ({
|
||||
useEthereumConfig: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@vegaprotocol/environment', () => ({
|
||||
useEnvironment: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('MultisigIncorrectNotice', () => {
|
||||
it('renders correctly when config is provided', () => {
|
||||
(useEthereumConfig as jest.Mock).mockReturnValue({
|
||||
config: {
|
||||
multisig_control_contract: {
|
||||
address: '0x1234',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
(useEnvironment as unknown as jest.Mock).mockReturnValue({
|
||||
ETHERSCAN_URL: 'https://etherscan.io',
|
||||
});
|
||||
|
||||
render(<MultisigIncorrectNotice />);
|
||||
|
||||
expect(screen.getByTestId('multisig-contract-link')).toHaveAttribute(
|
||||
'href',
|
||||
'https://etherscan.io/address/0x1234'
|
||||
);
|
||||
expect(screen.getByTestId('multisig-contract-link')).toHaveAttribute(
|
||||
'title',
|
||||
'0x1234'
|
||||
);
|
||||
expect(
|
||||
screen.getByTestId('multisig-validators-learn-more')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render when config is not provided', () => {
|
||||
(useEthereumConfig as jest.Mock).mockReturnValue({
|
||||
config: null,
|
||||
});
|
||||
|
||||
const { container } = render(<MultisigIncorrectNotice />);
|
||||
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
});
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Callout, Intent, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useEthereumConfig } from '@vegaprotocol/web3';
|
||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
||||
import type { EthereumConfig } from '@vegaprotocol/web3';
|
||||
|
||||
export const MultisigIncorrectNotice = () => {
|
||||
const { t } = useTranslation();
|
||||
const { config } = useEthereumConfig();
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
|
||||
if (!config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const contract = config[
|
||||
'multisig_control_contract' as keyof EthereumConfig
|
||||
] as {
|
||||
address: string;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-10">
|
||||
<Callout intent={Intent.Warning}>
|
||||
<div>
|
||||
<Link
|
||||
title={contract.address}
|
||||
href={`${ETHERSCAN_URL}/address/${contract.address}`}
|
||||
target="_blank"
|
||||
data-testid="multisig-contract-link"
|
||||
>
|
||||
{t('multisigContractLink')}
|
||||
</Link>{' '}
|
||||
{t('multisigContractIncorrect')}
|
||||
</div>
|
||||
|
||||
<div className="mt-2">
|
||||
<Link
|
||||
href={DocsLinks?.VALIDATOR_SCORES_REWARDS}
|
||||
target="_blank"
|
||||
data-testid="multisig-validators-learn-more"
|
||||
>
|
||||
{t('learnMore')}
|
||||
</Link>
|
||||
</div>
|
||||
</Callout>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -3,32 +3,32 @@ import { usePendingBalancesStore } from './use-pending-balances-manager';
|
||||
import type { Contract } from 'ethers';
|
||||
import { useListenForPendingEthEvents } from './use-listen-for-pending-eth-events';
|
||||
import { prepend0x } from '@vegaprotocol/smart-contracts';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
|
||||
export const useListenForStakingEvents = (
|
||||
contract: Contract | undefined,
|
||||
vegaPublicKey: string | null,
|
||||
numberOfConfirmations: number
|
||||
) => {
|
||||
const { account } = useWeb3React();
|
||||
const { addPendingTxs, removePendingTx, resetPendingTxs } =
|
||||
usePendingBalancesStore((state) => ({
|
||||
addPendingTxs: state.addPendingTxs,
|
||||
removePendingTx: state.removePendingTx,
|
||||
resetPendingTxs: state.resetPendingTxs,
|
||||
}));
|
||||
const addFilter = useMemo(
|
||||
() =>
|
||||
vegaPublicKey && contract
|
||||
? contract.filters.Stake_Deposited(null, null, prepend0x(vegaPublicKey))
|
||||
: null,
|
||||
[contract, vegaPublicKey]
|
||||
);
|
||||
const removeFilter = useMemo(
|
||||
() =>
|
||||
vegaPublicKey && contract
|
||||
? contract.filters.Stake_Removed(null, null, prepend0x(vegaPublicKey))
|
||||
: null,
|
||||
[contract, vegaPublicKey]
|
||||
);
|
||||
const addFilter = useMemo(() => {
|
||||
if (!account || !vegaPublicKey || !contract) return null;
|
||||
return contract.filters.Stake_Deposited(
|
||||
null,
|
||||
null,
|
||||
prepend0x(vegaPublicKey)
|
||||
);
|
||||
}, [contract, vegaPublicKey, account]);
|
||||
const removeFilter = useMemo(() => {
|
||||
if (!account || !vegaPublicKey || !contract) return null;
|
||||
return contract.filters.Stake_Removed(null, null, prepend0x(vegaPublicKey));
|
||||
}, [contract, vegaPublicKey, account]);
|
||||
|
||||
/**
|
||||
* Listen for all add stake events
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
"Showing tranches with <{{trancheMinimum}} VEGA, click to hide these tranches": "Showing tranches with ≤{{trancheMinimum}} $VEGA, click to hide these tranches",
|
||||
"Not showing tranches with <{{trancheMinimum}} VEGA, click to show all tranches": "Not showing tranches with ≤{{trancheMinimum}} $VEGA, click to show all tranches",
|
||||
"the holder": "the holder",
|
||||
"We couldn't seem to load your data.": "We couldn't seem to load your data.",
|
||||
"Your data couldn't be loaded": "Your data couldn't be loaded",
|
||||
"Vesting VEGA": "Vesting VEGA",
|
||||
"All the tokens in this tranche are locked and can not be redeemed yet.": "All the tokens in this tranche are locked and can not be redeemed yet.",
|
||||
"Redeem unlocked VEGA from tranche {{id}}": "Redeem unlocked $VEGA from tranche {{id}}",
|
||||
@@ -728,7 +728,7 @@
|
||||
"ThisWillSetEnactmentDeadlineTo": "This will set the enactment date to",
|
||||
"ThisWillSetValidationDeadlineTo": "This will set the validation deadline to",
|
||||
"Hours": "hours",
|
||||
"ThisWillAdd2MinutesToAllowTimeToConfirmInWallet": "Note: we add 2 minutes of extra time when you choose the minimum value. This gives you time to confirm the proposal in your wallet.",
|
||||
"ThisWillAdd2MinutesToAllowTimeToConfirmInWallet": "Note: 2 minutes of extra time are added when you choose the minimum value. This gives you time to confirm the proposal in your wallet.",
|
||||
"ProposalWillFailIfEnactmentIsEarlierThanVotingDeadline": "Proposal will fail if enactment is earlier than the voting deadline",
|
||||
"SelectAMarketToChange": "Select a market to change",
|
||||
"MarketName": "Market name",
|
||||
@@ -821,5 +821,8 @@
|
||||
"disclaimer2": "The Vega Governance App is free, public and open source software. Software upgrades may contain bugs or security vulnerabilities that might result in loss of functionality.",
|
||||
"disclaimer3": "The Vega Governance App uses data obtained from nodes on the Vega Blockchain. The developers of the Vega Governance App do not operate or run the Vega Blockchain or any other blockchain.",
|
||||
"disclaimer4": "The Vega Governance App is provided “as is”. The developers of the Vega Governance App make no representations or warranties of any kind, whether express or implied, statutory or otherwise regarding the Vega Governance App. They disclaim all warranties of merchantability, quality, fitness for purpose. They disclaim all warranties that the Vega Governance App is free of harmful components or errors.",
|
||||
"disclaimer5": "No developer of the Vega Governance App accepts any responsibility for, or liability to users in connection with their use of the Vega Governance App."
|
||||
"disclaimer5": "No developer of the Vega Governance App accepts any responsibility for, or liability to users in connection with their use of the Vega Governance App.",
|
||||
"multisigContractLink": "Ethereum Multisig Contract",
|
||||
"multisigContractIncorrect": "is incorrectly configured. Validator and delegator rewards will be penalised until this is resolved.",
|
||||
"learnMore": "Learn more"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import {
|
||||
getMultisigStatusInfo,
|
||||
MultisigStatus,
|
||||
} from './get-multisig-status-info';
|
||||
import type { PreviousEpochQuery } from '../routes/staking/__generated__/PreviousEpoch';
|
||||
|
||||
const createNode = (id: string, multisigScore: string) => ({
|
||||
node: {
|
||||
id,
|
||||
stakedTotal: '1000',
|
||||
rewardScore: { multisigScore },
|
||||
},
|
||||
});
|
||||
|
||||
describe('getMultisigStatus', () => {
|
||||
it('should return MultisigStatus.noNodes when no nodes are present', () => {
|
||||
const result = getMultisigStatusInfo({
|
||||
epoch: { id: '1', validatorsConnection: { edges: [] } },
|
||||
} as PreviousEpochQuery);
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.noNodes,
|
||||
showMultisigStatusError: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return MultisigStatus.correct when all nodes have multisigScore of 1', () => {
|
||||
const result = getMultisigStatusInfo({
|
||||
epoch: {
|
||||
id: '1',
|
||||
validatorsConnection: {
|
||||
edges: [createNode('1', '1'), createNode('2', '1')],
|
||||
},
|
||||
},
|
||||
} as PreviousEpochQuery);
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.correct,
|
||||
showMultisigStatusError: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return MultisigStatus.nodeNeedsRemoving when all nodes have multisigScore of 0', () => {
|
||||
const result = getMultisigStatusInfo({
|
||||
epoch: {
|
||||
id: '1',
|
||||
validatorsConnection: {
|
||||
edges: [createNode('1', '0'), createNode('2', '0')],
|
||||
},
|
||||
},
|
||||
} as PreviousEpochQuery);
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.nodeNeedsRemoving,
|
||||
showMultisigStatusError: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return MultisigStatus.nodeNeedsAdding when some nodes have multisigScore of 0 and others have 1', () => {
|
||||
const result = getMultisigStatusInfo({
|
||||
epoch: {
|
||||
id: '1',
|
||||
validatorsConnection: {
|
||||
edges: [createNode('1', '0'), createNode('2', '1')],
|
||||
},
|
||||
},
|
||||
} as PreviousEpochQuery);
|
||||
expect(result).toEqual({
|
||||
multisigStatus: MultisigStatus.nodeNeedsAdding,
|
||||
showMultisigStatusError: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { removePaginationWrapper } from '@vegaprotocol/utils';
|
||||
import type { PreviousEpochQuery } from '../routes/staking/__generated__/PreviousEpoch';
|
||||
|
||||
export enum MultisigStatus {
|
||||
'correct' = 'correct',
|
||||
'nodeNeedsAdding' = 'nodeNeedsAdding',
|
||||
'nodeNeedsRemoving' = 'nodeNeedsRemoving ',
|
||||
'noNodes' = 'noNodes',
|
||||
}
|
||||
|
||||
export const getMultisigStatusInfo = (
|
||||
previousEpochData: PreviousEpochQuery
|
||||
) => {
|
||||
let status = MultisigStatus.noNodes;
|
||||
|
||||
const allNodesInPreviousEpoch = removePaginationWrapper(
|
||||
previousEpochData?.epoch.validatorsConnection?.edges
|
||||
);
|
||||
|
||||
const hasZero = allNodesInPreviousEpoch.some(
|
||||
(node) => Number(node?.rewardScore?.multisigScore) === 0
|
||||
);
|
||||
const hasOne = allNodesInPreviousEpoch.some(
|
||||
(node) => Number(node?.rewardScore?.multisigScore) === 1
|
||||
);
|
||||
|
||||
if (hasZero && hasOne) {
|
||||
// If any individual node has 0 it means that node is missing from the multisig and needs to be added
|
||||
status = MultisigStatus.nodeNeedsAdding;
|
||||
} else if (hasZero) {
|
||||
// If all nodes have 0 it means there is an incorrect address in the multisig that needs to be removed
|
||||
status = MultisigStatus.nodeNeedsRemoving;
|
||||
} else if (allNodesInPreviousEpoch.length > 0) {
|
||||
// If all nodes have 1 it means the multisig is correct
|
||||
status = MultisigStatus.correct;
|
||||
}
|
||||
|
||||
return {
|
||||
showMultisigStatusError: status !== MultisigStatus.correct,
|
||||
multisigStatus: status,
|
||||
};
|
||||
};
|
||||
-23
@@ -115,29 +115,6 @@ describe('Proposals list', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Orders proposals correctly by closingDateTime', () => {
|
||||
render(
|
||||
renderComponent([
|
||||
failedProposalClosedLastMonth,
|
||||
openProposalClosesNextMonth,
|
||||
openProposalClosesNextWeek,
|
||||
enactedProposalClosedLastWeek,
|
||||
])
|
||||
);
|
||||
const openProposals = within(screen.getByTestId('open-proposals'));
|
||||
const closedProposals = within(screen.getByTestId('closed-proposals'));
|
||||
const openProposalsItems = openProposals.getAllByTestId(
|
||||
'proposals-list-item'
|
||||
);
|
||||
const closedProposalsItems = closedProposals.getAllByTestId(
|
||||
'proposals-list-item'
|
||||
);
|
||||
expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal2');
|
||||
expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal1');
|
||||
expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal3');
|
||||
expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal4');
|
||||
});
|
||||
|
||||
it('Displays info on no proposals', () => {
|
||||
render(renderComponent([]));
|
||||
expect(screen.queryByTestId('open-proposals')).not.toBeInTheDocument();
|
||||
|
||||
@@ -35,7 +35,11 @@ export const orderByDate = (arr: ProposalFieldsFragment[]) =>
|
||||
orderBy(
|
||||
arr,
|
||||
[
|
||||
(p) => new Date(p?.terms?.closingDatetime).getTime(),
|
||||
(p) =>
|
||||
p?.terms?.enactmentDatetime
|
||||
? new Date(p?.terms?.enactmentDatetime).getTime()
|
||||
: // has to be defaulted to 0 because new Date(null).getTime() -> NaN which is first when ordered
|
||||
new Date(p?.terms?.closingDatetime || 0).getTime(),
|
||||
(p) => new Date(p?.datetime).getTime(),
|
||||
],
|
||||
['asc', 'asc']
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ describe('Proposal form vote, validation and enactment deadline', () => {
|
||||
it('should show the correct datetimes', () => {
|
||||
renderComponent();
|
||||
// Should be adding 2 mins to the vote deadline as the minimum is set by
|
||||
// default, and we add 2 mins for wallet confirmation
|
||||
// default, and 2 mins are added for wallet confirmation
|
||||
expect(screen.getByTestId('voting-date')).toHaveTextContent(
|
||||
'2022-01-01T01:02:00.000Z'
|
||||
);
|
||||
|
||||
@@ -5,6 +5,9 @@ import { ProtocolUpgradeProposalDetailInfo } from '../components/protocol-upgrad
|
||||
import { getNormalisedVotingPower } from '../../staking/shared';
|
||||
import type { NodesFragmentFragment } from '../../staking/home/__generated__/Nodes';
|
||||
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { useVegaRelease } from '@vegaprotocol/environment';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface ProtocolUpgradeProposalProps {
|
||||
proposal: ProtocolUpgradeProposalFieldsFragment;
|
||||
@@ -42,6 +45,9 @@ export const ProtocolUpgradeProposal = ({
|
||||
lastBlockHeight,
|
||||
consensusValidators,
|
||||
}: ProtocolUpgradeProposalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const releaseInfo = useVegaRelease(proposal.vegaReleaseTag);
|
||||
|
||||
const consensusApprovals = useMemo(
|
||||
() => getConsensusApprovals(consensusValidators || [], proposal),
|
||||
[consensusValidators, proposal]
|
||||
@@ -78,6 +84,14 @@ export const ProtocolUpgradeProposal = ({
|
||||
totalConsensusValidators={consensusValidators.length}
|
||||
/>
|
||||
)}
|
||||
|
||||
{releaseInfo && releaseInfo.htmlUrl && (
|
||||
<div className="mb-10">
|
||||
<ExternalLink href={releaseInfo.htmlUrl}>
|
||||
{t('Explore release on GitHub')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ const mockData = {
|
||||
{
|
||||
asset: 'tDAI',
|
||||
totalAmount: '5',
|
||||
decimals: 6,
|
||||
rewardTypes: {
|
||||
ACCOUNT_TYPE_GLOBAL_REWARD: {
|
||||
amount: '0',
|
||||
|
||||
+20
-10
@@ -1,6 +1,5 @@
|
||||
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { useAppState } from '../../../contexts/app-state/app-state-context';
|
||||
import {
|
||||
rowGridItemStyles,
|
||||
RewardsTable,
|
||||
@@ -13,7 +12,8 @@ interface EpochIndividualRewardsGridProps {
|
||||
}
|
||||
|
||||
interface RewardItemProps {
|
||||
value: string;
|
||||
amount: string;
|
||||
decimals: number;
|
||||
percentageOfTotal?: string;
|
||||
dataTestId: string;
|
||||
last?: boolean;
|
||||
@@ -21,15 +21,14 @@ interface RewardItemProps {
|
||||
|
||||
const DisplayReward = ({
|
||||
reward,
|
||||
decimals,
|
||||
percentageOfTotal,
|
||||
}: {
|
||||
reward: string;
|
||||
decimals: number;
|
||||
percentageOfTotal?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
appState: { decimals },
|
||||
} = useAppState();
|
||||
|
||||
if (Number(reward) === 0) {
|
||||
return <span className="text-vega-dark-300">-</span>;
|
||||
@@ -64,7 +63,8 @@ const DisplayReward = ({
|
||||
};
|
||||
|
||||
const RewardItem = ({
|
||||
value,
|
||||
amount,
|
||||
decimals,
|
||||
percentageOfTotal,
|
||||
dataTestId,
|
||||
last,
|
||||
@@ -72,7 +72,11 @@ const RewardItem = ({
|
||||
<div data-testid={dataTestId} className={rowGridItemStyles(last)}>
|
||||
<div className="h-full w-5 absolute right-0 top-0 bg-gradient-to-r from-transparent to-black pointer-events-none" />
|
||||
<div className="overflow-auto p-5">
|
||||
<DisplayReward reward={value} percentageOfTotal={percentageOfTotal} />
|
||||
<DisplayReward
|
||||
reward={amount}
|
||||
decimals={decimals}
|
||||
percentageOfTotal={percentageOfTotal}
|
||||
/>
|
||||
</div>
|
||||
<div className="h-full w-5 absolute left-0 top-0 bg-gradient-to-l from-transparent to-black pointer-events-none" />
|
||||
</div>
|
||||
@@ -86,7 +90,7 @@ export const EpochIndividualRewardsTable = ({
|
||||
dataTestId="epoch-individual-rewards-table"
|
||||
epoch={Number(data.epoch)}
|
||||
>
|
||||
{data.rewards.map(({ asset, rewardTypes, totalAmount }, i) => (
|
||||
{data.rewards.map(({ asset, rewardTypes, totalAmount, decimals }, i) => (
|
||||
<div className="contents" key={i}>
|
||||
<div
|
||||
data-testid="individual-rewards-asset"
|
||||
@@ -98,13 +102,19 @@ export const EpochIndividualRewardsTable = ({
|
||||
([key, { amount, percentageOfTotal }]) => (
|
||||
<RewardItem
|
||||
key={key}
|
||||
value={amount}
|
||||
amount={amount}
|
||||
decimals={decimals}
|
||||
percentageOfTotal={percentageOfTotal}
|
||||
dataTestId={key}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<RewardItem dataTestId="total" value={totalAmount} last={true} />
|
||||
<RewardItem
|
||||
dataTestId="total"
|
||||
amount={totalAmount}
|
||||
decimals={decimals}
|
||||
last={true}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</RewardsTable>
|
||||
|
||||
+14
-6
@@ -8,7 +8,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '100',
|
||||
percentageOfTotal: '0.1',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD' },
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD', decimals: 6 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '1' },
|
||||
};
|
||||
@@ -18,7 +18,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '50',
|
||||
percentageOfTotal: '0.05',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'eur', symbol: 'EUR', name: 'EUR' },
|
||||
asset: { id: 'eur', symbol: 'EUR', name: 'EUR', decimals: 5 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '2' },
|
||||
};
|
||||
@@ -28,7 +28,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '200',
|
||||
percentageOfTotal: '0.2',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'gbp', symbol: 'GBP', name: 'GBP' },
|
||||
asset: { id: 'gbp', symbol: 'GBP', name: 'GBP', decimals: 7 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '2' },
|
||||
};
|
||||
@@ -38,7 +38,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '100',
|
||||
percentageOfTotal: '0.1',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD' },
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD', decimals: 6 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '1' },
|
||||
};
|
||||
@@ -48,7 +48,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '150',
|
||||
percentageOfTotal: '0.15',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD' },
|
||||
asset: { id: 'usd', symbol: 'USD', name: 'USD', decimals: 6 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '3' },
|
||||
};
|
||||
@@ -58,7 +58,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
amount: '50',
|
||||
percentageOfTotal: '0.05',
|
||||
receivedAt: new Date(),
|
||||
asset: { id: 'eur', symbol: 'EUR', name: 'EUR' },
|
||||
asset: { id: 'eur', symbol: 'EUR', name: 'EUR', decimals: 5 },
|
||||
party: { id: 'blah' },
|
||||
epoch: { id: '2' },
|
||||
};
|
||||
@@ -99,6 +99,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
rewards: [
|
||||
{
|
||||
asset: 'USD',
|
||||
decimals: 6,
|
||||
totalAmount: '100',
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
@@ -167,6 +168,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'GBP',
|
||||
totalAmount: '200',
|
||||
decimals: 7,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
@@ -197,6 +199,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'EUR',
|
||||
totalAmount: '50',
|
||||
decimals: 5,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
@@ -232,6 +235,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'USD',
|
||||
totalAmount: '200',
|
||||
decimals: 6,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
@@ -279,6 +283,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
rewards: [
|
||||
{
|
||||
asset: 'USD',
|
||||
decimals: 6,
|
||||
totalAmount: '150',
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
@@ -315,6 +320,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'GBP',
|
||||
totalAmount: '200',
|
||||
decimals: 7,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
@@ -345,6 +351,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'EUR',
|
||||
totalAmount: '50',
|
||||
decimals: 5,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
@@ -390,6 +397,7 @@ describe('generateEpochIndividualRewardsList', () => {
|
||||
{
|
||||
asset: 'USD',
|
||||
totalAmount: '200',
|
||||
decimals: 6,
|
||||
rewardTypes: {
|
||||
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
|
||||
amount: '0',
|
||||
|
||||
+3
@@ -9,6 +9,7 @@ export interface EpochIndividualReward {
|
||||
rewards: {
|
||||
asset: string;
|
||||
totalAmount: string;
|
||||
decimals: number;
|
||||
rewardTypes: {
|
||||
[key in AccountType]?: {
|
||||
amount: string;
|
||||
@@ -53,6 +54,7 @@ export const generateEpochIndividualRewardsList = ({
|
||||
const epochIndividualRewards = rewards.reduce((acc, reward) => {
|
||||
const epochId = reward.epoch.id;
|
||||
const assetName = reward.asset.name;
|
||||
const assetDecimals = reward.asset.decimals;
|
||||
const rewardType = reward.rewardType;
|
||||
const amount = reward.amount;
|
||||
const percentageOfTotal = reward.percentageOfTotal;
|
||||
@@ -73,6 +75,7 @@ export const generateEpochIndividualRewardsList = ({
|
||||
if (!asset) {
|
||||
asset = {
|
||||
asset: assetName,
|
||||
decimals: assetDecimals,
|
||||
totalAmount: '0',
|
||||
rewardTypes: Object.fromEntries(emptyRowAccountTypes),
|
||||
};
|
||||
|
||||
+1
@@ -52,6 +52,7 @@ const assetRewards: Map<
|
||||
assetRewards.set(assetId, {
|
||||
assetId,
|
||||
name: 'tDAI TEST',
|
||||
decimals: 6,
|
||||
rewards,
|
||||
totalAmount: '295',
|
||||
});
|
||||
|
||||
+29
-12
@@ -1,6 +1,5 @@
|
||||
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { useAppState } from '../../../contexts/app-state/app-state-context';
|
||||
import {
|
||||
rowGridItemStyles,
|
||||
RewardsTable,
|
||||
@@ -12,16 +11,19 @@ interface EpochTotalRewardsGridProps {
|
||||
}
|
||||
|
||||
interface RewardItemProps {
|
||||
value: string;
|
||||
amount: string;
|
||||
decimals: number;
|
||||
dataTestId: string;
|
||||
last?: boolean;
|
||||
}
|
||||
|
||||
const DisplayReward = ({ reward }: { reward: string }) => {
|
||||
const {
|
||||
appState: { decimals },
|
||||
} = useAppState();
|
||||
|
||||
const DisplayReward = ({
|
||||
reward,
|
||||
decimals,
|
||||
}: {
|
||||
reward: string;
|
||||
decimals: number;
|
||||
}) => {
|
||||
if (Number(reward) === 0) {
|
||||
return <span className="text-vega-dark-300">-</span>;
|
||||
}
|
||||
@@ -33,11 +35,16 @@ const DisplayReward = ({ reward }: { reward: string }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const RewardItem = ({ value, dataTestId, last }: RewardItemProps) => (
|
||||
const RewardItem = ({
|
||||
amount,
|
||||
decimals,
|
||||
dataTestId,
|
||||
last,
|
||||
}: RewardItemProps) => (
|
||||
<div data-testid={dataTestId} className={rowGridItemStyles(last)}>
|
||||
<div className="h-full w-5 absolute right-0 top-0 bg-gradient-to-r from-transparent to-black pointer-events-none" />
|
||||
<div className="overflow-auto p-5">
|
||||
<DisplayReward reward={value} />
|
||||
<DisplayReward reward={amount} decimals={decimals} />
|
||||
</div>
|
||||
<div className="h-full w-5 absolute left-0 top-0 bg-gradient-to-l from-transparent to-black pointer-events-none" />
|
||||
</div>
|
||||
@@ -49,15 +56,25 @@ export const EpochTotalRewardsTable = ({
|
||||
return (
|
||||
<RewardsTable dataTestId="epoch-total-rewards-table" epoch={data.epoch}>
|
||||
{Array.from(data.assetRewards.values()).map(
|
||||
({ name, rewards, totalAmount }, i) => (
|
||||
({ name, rewards, totalAmount, decimals }, i) => (
|
||||
<div className="contents" key={i}>
|
||||
<div data-testid="asset" className={`${rowGridItemStyles()} p-5`}>
|
||||
{name}
|
||||
</div>
|
||||
{Array.from(rewards.values()).map(({ rewardType, amount }, i) => (
|
||||
<RewardItem key={i} dataTestId={rewardType} value={amount} />
|
||||
<RewardItem
|
||||
key={i}
|
||||
dataTestId={rewardType}
|
||||
amount={amount}
|
||||
decimals={decimals}
|
||||
/>
|
||||
))}
|
||||
<RewardItem dataTestId="total" value={totalAmount} last={true} />
|
||||
<RewardItem
|
||||
dataTestId="total"
|
||||
amount={totalAmount}
|
||||
decimals={decimals}
|
||||
last={true}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
|
||||
+21
@@ -56,12 +56,14 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
id: '1',
|
||||
name: 'Asset 1',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '2',
|
||||
name: 'Asset 2',
|
||||
decimals: 6,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -101,6 +103,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
{
|
||||
node: {
|
||||
epoch: 1,
|
||||
decimals: 18,
|
||||
assetId: '1',
|
||||
rewardType: AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
|
||||
amount: '123',
|
||||
@@ -128,6 +131,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
'1',
|
||||
{
|
||||
assetId: '1',
|
||||
decimals: 0,
|
||||
name: '',
|
||||
rewards: new Map([
|
||||
[
|
||||
@@ -196,12 +200,14 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
id: '1',
|
||||
name: 'Asset 1',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '2',
|
||||
name: 'Asset 2',
|
||||
decimals: 6,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -212,6 +218,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 1,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
|
||||
amount: '123',
|
||||
},
|
||||
@@ -220,6 +227,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 1,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
amount: '100',
|
||||
},
|
||||
@@ -228,6 +236,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 2,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
|
||||
amount: '5',
|
||||
},
|
||||
@@ -254,6 +263,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
'1',
|
||||
{
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
name: 'Asset 1',
|
||||
rewards: new Map([
|
||||
[
|
||||
@@ -319,6 +329,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
'1',
|
||||
{
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
name: 'Asset 1',
|
||||
rewards: new Map([
|
||||
[
|
||||
@@ -387,12 +398,14 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
id: '1',
|
||||
name: 'Asset 1',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: '2',
|
||||
name: 'Asset 2',
|
||||
decimals: 6,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -403,6 +416,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 1,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
|
||||
amount: '123',
|
||||
},
|
||||
@@ -411,6 +425,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 1,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
amount: '100',
|
||||
},
|
||||
@@ -419,6 +434,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 2,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
|
||||
amount: '6',
|
||||
},
|
||||
@@ -427,6 +443,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 2,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
|
||||
amount: '27',
|
||||
},
|
||||
@@ -435,6 +452,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
node: {
|
||||
epoch: 3,
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
rewardType: AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
|
||||
amount: '15',
|
||||
},
|
||||
@@ -467,6 +485,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
{
|
||||
assetId: '1',
|
||||
name: 'Asset 1',
|
||||
decimals: 18,
|
||||
rewards: new Map([
|
||||
[
|
||||
AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
|
||||
@@ -531,6 +550,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
'1',
|
||||
{
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
name: 'Asset 1',
|
||||
rewards: new Map([
|
||||
[
|
||||
@@ -608,6 +628,7 @@ describe('generateEpochAssetRewardsList', () => {
|
||||
'1',
|
||||
{
|
||||
assetId: '1',
|
||||
decimals: 18,
|
||||
name: 'Asset 1',
|
||||
rewards: new Map([
|
||||
[
|
||||
|
||||
+2
@@ -22,6 +22,7 @@ export type AggregatedEpochRewardSummary = {
|
||||
name: EpochSummaryWithNamedReward['name'];
|
||||
rewards: Map<RewardType, RewardItem>;
|
||||
totalAmount: string;
|
||||
decimals: number;
|
||||
};
|
||||
|
||||
export type EpochTotalSummary = {
|
||||
@@ -91,6 +92,7 @@ export const generateEpochTotalRewardsList = ({
|
||||
assetId: reward.assetId,
|
||||
name: matchingAsset?.name || '',
|
||||
rewards: rewards || new Map(emptyRowAccountTypes),
|
||||
decimals: matchingAsset?.decimals || 0,
|
||||
totalAmount: (
|
||||
Number(reward.amount) + Number(assetWithRewards?.totalAmount || 0)
|
||||
).toString(),
|
||||
|
||||
@@ -4,6 +4,7 @@ fragment RewardFields on Reward {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
@@ -67,6 +68,7 @@ query EpochAssetsRewards(
|
||||
node {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type RewardFieldsFragment = { __typename?: 'Reward', rewardType: Types.AccountType, amount: string, percentageOfTotal: string, receivedAt: any, asset: { __typename?: 'Asset', id: string, symbol: string, name: string }, party: { __typename?: 'Party', id: string }, epoch: { __typename?: 'Epoch', id: string } };
|
||||
export type RewardFieldsFragment = { __typename?: 'Reward', rewardType: Types.AccountType, amount: string, percentageOfTotal: string, receivedAt: any, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string }, epoch: { __typename?: 'Epoch', id: string } };
|
||||
|
||||
export type DelegationFieldsFragment = { __typename?: 'Delegation', amount: string, epoch: number };
|
||||
|
||||
@@ -16,7 +16,7 @@ export type RewardsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type RewardsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, rewardsConnection?: { __typename?: 'RewardsConnection', edges?: Array<{ __typename?: 'RewardEdge', node: { __typename?: 'Reward', rewardType: Types.AccountType, amount: string, percentageOfTotal: string, receivedAt: any, asset: { __typename?: 'Asset', id: string, symbol: string, name: string }, party: { __typename?: 'Party', id: string }, epoch: { __typename?: 'Epoch', id: string } } } | null> | null } | null, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number } } | null> | null } | null } | null };
|
||||
export type RewardsQuery = { __typename?: 'Query', party?: { __typename?: 'Party', id: string, rewardsConnection?: { __typename?: 'RewardsConnection', edges?: Array<{ __typename?: 'RewardEdge', node: { __typename?: 'Reward', rewardType: Types.AccountType, amount: string, percentageOfTotal: string, receivedAt: any, asset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, party: { __typename?: 'Party', id: string }, epoch: { __typename?: 'Epoch', id: string } } } | null> | null } | null, delegationsConnection?: { __typename?: 'DelegationsConnection', edges?: Array<{ __typename?: 'DelegationEdge', node: { __typename?: 'Delegation', amount: string, epoch: number } } | null> | null } | null } | null };
|
||||
|
||||
export type EpochRewardSummaryFieldsFragment = { __typename?: 'EpochRewardSummary', epoch: number, assetId: string, amount: string, rewardType: Types.AccountType };
|
||||
|
||||
@@ -26,7 +26,7 @@ export type EpochAssetsRewardsQueryVariables = Types.Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type EpochAssetsRewardsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string } } | null> | null } | null, epochRewardSummaries?: { __typename?: 'EpochRewardSummaryConnection', edges?: Array<{ __typename?: 'EpochRewardSummaryEdge', node: { __typename?: 'EpochRewardSummary', epoch: number, assetId: string, amount: string, rewardType: Types.AccountType } } | null> | null } | null };
|
||||
export type EpochAssetsRewardsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, decimals: number } } | null> | null } | null, epochRewardSummaries?: { __typename?: 'EpochRewardSummaryConnection', edges?: Array<{ __typename?: 'EpochRewardSummaryEdge', node: { __typename?: 'EpochRewardSummary', epoch: number, assetId: string, amount: string, rewardType: Types.AccountType } } | null> | null } | null };
|
||||
|
||||
export type EpochFieldsFragment = { __typename?: 'Epoch', id: string, timestamps: { __typename?: 'EpochTimestamps', start?: any | null, end?: any | null, expiry?: any | null } };
|
||||
|
||||
@@ -42,6 +42,7 @@ export const RewardFieldsFragmentDoc = gql`
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
party {
|
||||
id
|
||||
@@ -143,6 +144,7 @@ export const EpochAssetsRewardsDocument = gql`
|
||||
node {
|
||||
id
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
|
||||
import { DocsLinks } from '@vegaprotocol/environment';
|
||||
import { ConnectToSeeRewards } from '../connect-to-see-rewards';
|
||||
import { EpochTotalRewards } from '../epoch-total-rewards/epoch-total-rewards';
|
||||
import { usePreviousEpochQuery } from '../../staking/__generated__/PreviousEpoch';
|
||||
import { getMultisigStatusInfo } from '../../../lib/get-multisig-status-info';
|
||||
import { MultisigIncorrectNotice } from '../../../components/multisig-incorrect-notice';
|
||||
|
||||
type RewardsView = 'total' | 'individual';
|
||||
|
||||
@@ -41,12 +44,25 @@ export const RewardsPage = () => {
|
||||
|
||||
useRefreshAfterEpoch(epochData?.epoch.timestamps.expiry, refetch);
|
||||
|
||||
const { data: previousEpochData } = usePreviousEpochQuery({
|
||||
variables: {
|
||||
epochId: (Number(epochData?.epoch.id) - 1).toString(),
|
||||
},
|
||||
skip: !epochData?.epoch.id,
|
||||
});
|
||||
|
||||
const multisigStatus = previousEpochData
|
||||
? getMultisigStatusInfo(previousEpochData)
|
||||
: undefined;
|
||||
|
||||
const {
|
||||
params,
|
||||
loading: paramsLoading,
|
||||
error: paramsError,
|
||||
} = useNetworkParams([NetworkParams.reward_staking_delegation_payoutDelay]);
|
||||
|
||||
console.log('params', params);
|
||||
|
||||
const payoutDuration = useMemo(() => {
|
||||
if (!params) {
|
||||
return 0;
|
||||
@@ -78,14 +94,18 @@ export const RewardsPage = () => {
|
||||
)}
|
||||
</p>
|
||||
|
||||
{payoutDuration ? (
|
||||
{multisigStatus?.showMultisigStatusError ? (
|
||||
<MultisigIncorrectNotice />
|
||||
) : null}
|
||||
|
||||
{!multisigStatus?.showMultisigStatusError && payoutDuration ? (
|
||||
<div className="my-8">
|
||||
<Callout
|
||||
title={t('rewardsCallout', {
|
||||
duration: formatDistance(new Date(0), payoutDuration),
|
||||
})}
|
||||
headingLevel={3}
|
||||
intent={Intent.Warning}
|
||||
intent={Intent.Primary}
|
||||
>
|
||||
<p className="mb-0">{t('rewardsCalloutDetail')}</p>
|
||||
</Callout>
|
||||
|
||||
@@ -7,6 +7,8 @@ import { ValidatorTables } from './validator-tables';
|
||||
import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { ENV } from '../../../config';
|
||||
import { getMultisigStatusInfo } from '../../../lib/get-multisig-status-info';
|
||||
import { MultisigIncorrectNotice } from '../../../components/multisig-incorrect-notice';
|
||||
|
||||
export const EpochData = () => {
|
||||
// errorPolicy due to vegaprotocol/vega issue 5898
|
||||
@@ -46,12 +48,20 @@ export const EpochData = () => {
|
||||
userStakingRefetch();
|
||||
});
|
||||
|
||||
const multisigStatus = previousEpochData
|
||||
? getMultisigStatusInfo(previousEpochData)
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<AsyncRenderer
|
||||
loading={nodesLoading || userStakingLoading}
|
||||
error={nodesError || userStakingError}
|
||||
data={nodesData}
|
||||
>
|
||||
{multisigStatus?.showMultisigStatusError ? (
|
||||
<MultisigIncorrectNotice />
|
||||
) : null}
|
||||
|
||||
{nodesData?.epoch &&
|
||||
nodesData.epoch.timestamps.start &&
|
||||
nodesData?.epoch.timestamps.expiry && (
|
||||
|
||||
@@ -71,14 +71,6 @@ export const calculateOverstakedPenalty = (nodeId: string, nodes: Node[]) => {
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0).dividedBy(tts)
|
||||
)
|
||||
.times(100);
|
||||
console.log(
|
||||
nodeId,
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0).toString(),
|
||||
tts.toString(),
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0)
|
||||
.dividedBy(tts)
|
||||
.toString()
|
||||
);
|
||||
return penalty.isLessThan(0) ? new BigNumber(0) : penalty;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,5 +23,6 @@ NX_VEGA_URL="https://api.n07.testnet.vega.xyz/graphql"
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||
NX_VEGA_ENV=DEVNET
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_VEGA_EXPLORER_URL=#
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_ENV=MAINNET
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||
NX_VEGA_CONSOLE_URL=https://console.vega.xyz
|
||||
|
||||
@@ -4,5 +4,6 @@ NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
|
||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -3,3 +3,6 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/maste
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=MAINNET
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.tom
|
||||
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS={'{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=VALIDATOR_TESTNET
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,27 +26,27 @@
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:first-child {
|
||||
animation-delay: -50ms;
|
||||
animation-delay: -0.1s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
animation-delay: 0.3s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(3) {
|
||||
animation-delay: -0.6s;
|
||||
animation-delay: -0.45s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(4) {
|
||||
animation-delay: 0.4s;
|
||||
animation-delay: 1s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(5) {
|
||||
animation-delay: -0.5s;
|
||||
animation-delay: -0.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(6) {
|
||||
animation-delay: 0.3s;
|
||||
animation-delay: 0.9s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(7) {
|
||||
@@ -54,11 +54,11 @@
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(8) {
|
||||
animation-delay: 2s;
|
||||
animation-delay: 1.6s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(9) {
|
||||
animation-delay: -0.9s;
|
||||
animation-delay: -0.45s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(10) {
|
||||
@@ -66,7 +66,7 @@
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(11) {
|
||||
animation-delay: -0.55s;
|
||||
animation-delay: -2.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(12) {
|
||||
@@ -74,21 +74,57 @@
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(13) {
|
||||
animation-delay: -0.65s;
|
||||
animation-delay: -1.95s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(14) {
|
||||
animation-delay: 0.7s;
|
||||
animation-delay: 2.8s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(15) {
|
||||
animation-delay: -3.75s;
|
||||
animation-delay: -0.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(16) {
|
||||
animation-delay: 1.6s;
|
||||
animation-delay: 4s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(17) {
|
||||
animation-delay: -0.85s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(18) {
|
||||
animation-delay: 1.8s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(19) {
|
||||
animation-delay: -1.9s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(20) {
|
||||
animation-delay: 5s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(21) {
|
||||
animation-delay: -5.25s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(22) {
|
||||
animation-delay: 4.4s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(23) {
|
||||
animation-delay: -5.75s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(24) {
|
||||
animation-delay: 4.8s;
|
||||
animation-direction: reverse;
|
||||
}
|
||||
.pre-loader .loader-item:nth-child(25) {
|
||||
animation-delay: -5s;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
.pre-loader .loader-item {
|
||||
animation: flickering 0.4s linear infinite alternate;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
.pre-loader {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.loader-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: black;
|
||||
}
|
||||
.pre-loader-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.pre-loader-wrapper {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@for $i from 0 through 25 {
|
||||
.loader-item:nth-child(#{$i}) {
|
||||
@if $i % 2 == 0 {
|
||||
animation-delay: #{$i * 50 * random(5)}ms;
|
||||
animation-direction: reverse;
|
||||
} @else {
|
||||
animation-delay: #{$i * -50 * random(5)}ms;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
.loader-item {
|
||||
animation: flickering 0.4s linear alternate infinite;
|
||||
}
|
||||
@keyframes flickering {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
25% {
|
||||
opacity: 1;
|
||||
}
|
||||
26% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
html.dark {
|
||||
.pre-loader {
|
||||
.loader-item {
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,8 @@ NX_VEGA_CONFIG_URL=''
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
@@ -19,6 +20,7 @@ CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit
|
||||
CYPRESS_ETHEREUM_WALLET_ADDRESS=0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F
|
||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
CYPRESS_CONSOLE_URL=https://console.fairground.wtf
|
||||
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||
CYPRESS_ORACLE_PUBKEY=6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||
|
||||
@@ -5,7 +5,8 @@ NX_VEGA_CONFIG_URL=''
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
@@ -17,6 +18,7 @@ CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit
|
||||
CYPRESS_ETHEREUM_WALLET_ADDRESS=0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F
|
||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
CYPRESS_CONSOLE_URL=https://console.fairground.wtf
|
||||
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports = defineConfig({
|
||||
viewportHeight: 900,
|
||||
responseTimeout: 50000,
|
||||
requestTimeout: 20000,
|
||||
retries: 2,
|
||||
retries: 1,
|
||||
testIsolation: false,
|
||||
},
|
||||
env: {
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// #region consts
|
||||
const asset = 'asset';
|
||||
const assetDetailsDialog = 'dialog-content';
|
||||
const assetRow = 'key-value-table-row';
|
||||
const contractAddress = '7_value';
|
||||
const dialogCloseBtn = 'close-asset-details-dialog';
|
||||
const dialogCloseX = 'dialog-close';
|
||||
const dialogTitle = 'dialog-title';
|
||||
|
||||
const indicesWithLabelTooltips = [4, 5, 6, 7, 8, 9, 11, 12, 13, 14];
|
||||
const indicesWithValueTooltips = [1, 6];
|
||||
|
||||
const labelValueToolTipPairs = [
|
||||
{
|
||||
label: 'ID',
|
||||
value: 'asset-id',
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
value: 'ERC20',
|
||||
valueToolTip: 'An asset originated from an Ethereum ERC20 Token',
|
||||
},
|
||||
{
|
||||
label: 'Name',
|
||||
value: 'Euro',
|
||||
},
|
||||
{
|
||||
label: 'Symbol',
|
||||
value: 'tEURO',
|
||||
},
|
||||
{
|
||||
label: 'Decimals',
|
||||
value: '5',
|
||||
labelTooltip: 'Number of decimal / precision handled by this asset',
|
||||
},
|
||||
{
|
||||
label: 'Quantum',
|
||||
value: '0.00001',
|
||||
labelTooltip: 'The minimum economically meaningful amount of the asset',
|
||||
},
|
||||
{
|
||||
label: 'Status',
|
||||
value: 'Enabled',
|
||||
labelTooltip: 'The status of the asset in the Vega network',
|
||||
valueToolTip: 'Asset can be used on the Vega network',
|
||||
},
|
||||
{
|
||||
label: 'Contract address',
|
||||
value: '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4 ',
|
||||
labelTooltip:
|
||||
'The address of the contract for the token, on the ethereum network',
|
||||
},
|
||||
{
|
||||
label: 'Withdrawal threshold',
|
||||
value: '0.0005',
|
||||
labelTooltip:
|
||||
"The maximum you can withdraw instantly. There's no limit on the size of a withdrawal, but all withdrawals over the threshold will have a delay time added to them",
|
||||
},
|
||||
{
|
||||
label: 'Lifetime limit',
|
||||
value: '1,230.00',
|
||||
labelTooltip:
|
||||
'The lifetime deposit limit per address. Note: this is a temporary measure that can be changed or removed through governance',
|
||||
},
|
||||
{ label: '', value: '' },
|
||||
{
|
||||
label: 'Infrastructure fee account balance',
|
||||
value: '0.00001',
|
||||
labelTooltip: 'The infrastructure fee account in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Global reward pool account balance',
|
||||
value: '0.00002',
|
||||
labelTooltip: 'The global rewards acquired in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Maker paid fees account balance',
|
||||
value: '0.00003',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the fees paid to makers in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Maker received fees account balance',
|
||||
value: '0.00004',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on fees received for being a maker on trades',
|
||||
},
|
||||
{
|
||||
label: 'Liquidity provision fee reward account balance',
|
||||
value: '0.00005',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the liquidity provision fees in this asset',
|
||||
},
|
||||
{
|
||||
label: 'Market proposer reward account balance',
|
||||
value: '0.00006',
|
||||
labelTooltip:
|
||||
'The rewards acquired based on the market proposer reward in this asset',
|
||||
},
|
||||
];
|
||||
//endregion
|
||||
|
||||
beforeEach(() => {
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.setVegaWallet();
|
||||
});
|
||||
|
||||
const visitPortfolioAndClickAsset = (assetName: string) => {
|
||||
cy.visit('/#/portfolio');
|
||||
cy.getByTestId(asset).contains(assetName).click();
|
||||
};
|
||||
|
||||
const testTooltip = (index: number, testId: string, tooltip: string) => {
|
||||
cy.getByTestId(`${index}_${testId}`).realHover();
|
||||
cy.get('[role="tooltip"]').find('div').should('have.text', tooltip);
|
||||
cy.getByTestId(dialogTitle).click();
|
||||
};
|
||||
|
||||
describe('assets', { tags: '@smoke', testIsolation: true }, () => {
|
||||
it('asset details', () => {
|
||||
visitPortfolioAndClickAsset('tBTC');
|
||||
|
||||
cy.getByTestId(assetRow).each((element, index) => {
|
||||
if (index === 10) {
|
||||
return;
|
||||
}
|
||||
const { label, value, labelTooltip, valueToolTip } =
|
||||
labelValueToolTipPairs[index];
|
||||
// 6501-ASSE-001
|
||||
// 6501-ASSE-002
|
||||
// 6501-ASSE-003
|
||||
// 6501-ASSE-004
|
||||
// 6501-ASSE-005
|
||||
// 6501-ASSE-006
|
||||
// 6501-ASSE-007
|
||||
// 6501-ASSE-008
|
||||
// 6501-ASSE-009
|
||||
// 6501-ASSE-010
|
||||
// 6501-ASSE-011
|
||||
cy.getByTestId(`${index}_label`).should('have.text', label);
|
||||
cy.getByTestId(`${index}_value`).should('have.text', value);
|
||||
|
||||
// 6501-ASSE-012
|
||||
if (indicesWithLabelTooltips.includes(index)) {
|
||||
if (labelTooltip) {
|
||||
testTooltip(index, 'label', labelTooltip);
|
||||
}
|
||||
}
|
||||
if (indicesWithValueTooltips.includes(index)) {
|
||||
if (valueToolTip) {
|
||||
testTooltip(index, 'value', valueToolTip);
|
||||
}
|
||||
}
|
||||
});
|
||||
// 6501-ASSE-013
|
||||
cy.getByTestId(dialogCloseX).click();
|
||||
cy.document().then((doc) => {
|
||||
expect(doc.querySelector(assetDetailsDialog)).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
it('ERC20 Contract address', () => {
|
||||
visitPortfolioAndClickAsset('tBTC');
|
||||
cy.getByTestId(contractAddress).within(() => {
|
||||
// 6501-ASSE-014
|
||||
cy.getByTestId('external-link')
|
||||
.should('have.attr', 'target', '_blank')
|
||||
.should('have.text', '0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4');
|
||||
});
|
||||
// 6501-ASSE-013
|
||||
cy.getByTestId(dialogCloseBtn).click();
|
||||
cy.document().then((doc) => {
|
||||
expect(doc.querySelector(assetDetailsDialog)).to.not.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -41,6 +41,7 @@ const submitTransferBtn = '[type="submit"]';
|
||||
const transferForm = 'transfer-form';
|
||||
const depositSubmit = 'deposit-submit';
|
||||
const approveSubmit = 'approve-submit';
|
||||
const dialogContent = 'dialog-content';
|
||||
|
||||
// Because the tests are run on a live network to optimize time, the tests are interdependent and must be run in the given order.
|
||||
describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
@@ -50,10 +51,7 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
cy.wrap(markets[0]).as('market');
|
||||
});
|
||||
cy.visit('/#/portfolio');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.setVegaWallet();
|
||||
cy.connectVegaWallet();
|
||||
});
|
||||
|
||||
it('can deposit', function () {
|
||||
@@ -116,6 +114,8 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
});
|
||||
|
||||
it('can key to key transfers', function () {
|
||||
// 1003-TRAN-023
|
||||
// 1003-TRAN-006
|
||||
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||
|
||||
cy.getByTestId(collateralTab).click();
|
||||
@@ -172,7 +172,6 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
'contain.text',
|
||||
'Error occurredcannot estimate gas'
|
||||
);
|
||||
cy.getByTestId(toastCloseBtn).click({ multiple: true });
|
||||
cy.getByTestId(completeWithdrawalBtn).should(
|
||||
'contain.text',
|
||||
'Complete withdrawal'
|
||||
@@ -202,7 +201,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
.first()
|
||||
.should('contain.text', 'Operational')
|
||||
.next()
|
||||
.should('contain.text', new URL(Cypress.env('VEGA_URL')).origin)
|
||||
.should('contain.text', new URL(Cypress.env('VEGA_URL')).hostname)
|
||||
.next()
|
||||
.then(($el) => {
|
||||
const blockHeight = parseInt($el.text());
|
||||
@@ -346,6 +345,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
// 1002-WITH-019
|
||||
// 1002-WITH-020
|
||||
// 1002-WITH-021
|
||||
const ethWalletAddress = Cypress.env('ETHEREUM_WALLET_ADDRESS');
|
||||
|
||||
cy.visit('/#/portfolio');
|
||||
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||
@@ -376,10 +376,39 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
'contain.text',
|
||||
'Transaction confirmed'
|
||||
);
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
'contain.text',
|
||||
'Funds unlockedYour funds have been unlocked for withdrawalView in block explorerWithdraw 1.00 tBTCComplete withdrawal'
|
||||
);
|
||||
cy.getByTestId(toastContent, txTimeout)
|
||||
.should('contain.text', 'Funds unlocked')
|
||||
.and('contain.text', 'Your funds have been unlocked for withdrawal.')
|
||||
.and(
|
||||
'contain.text',
|
||||
'View in block explorerYou can save your withdrawal details for extra security.'
|
||||
)
|
||||
.and('contain.text', 'Withdraw 1.00 tBTCComplete withdrawal');
|
||||
cy.getByTestId('toast-withdrawal-details').click();
|
||||
cy.getByTestId(dialogContent)
|
||||
.last()
|
||||
.within(() => {
|
||||
cy.getByTestId('dialog-title').should(
|
||||
'contain.text',
|
||||
'Save withdrawal details'
|
||||
);
|
||||
cy.getByTestId('copy-button').should('be.visible');
|
||||
cy.getByTestId('assetSource_value').should(
|
||||
'have.text',
|
||||
'0xb63D135B0a6854EEb765d69ca36210cC70BECAE0'
|
||||
);
|
||||
cy.getByTestId('amount_value').should('have.text', '100000');
|
||||
cy.getByTestId('nonce_value').invoke('text').should('not.be.empty');
|
||||
cy.getByTestId('signatures_value')
|
||||
.invoke('text')
|
||||
.should('not.be.empty');
|
||||
cy.getByTestId('targetAddress_value').should(
|
||||
'have.text',
|
||||
ethWalletAddress
|
||||
);
|
||||
cy.getByTestId('creation_value').invoke('text').should('not.be.empty');
|
||||
});
|
||||
cy.getByTestId('close-withdrawal-approval-dialog').click();
|
||||
|
||||
cy.get('.ag-center-cols-container')
|
||||
.find('[col-id="status"]')
|
||||
@@ -407,7 +436,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
});
|
||||
|
||||
cy.getByTestId('withdraw-dialog-button').click({ force: true });
|
||||
cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '7.999');
|
||||
// cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '6.999');
|
||||
});
|
||||
|
||||
it('approved amount is less than deposit', function () {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { closeWelcomeDialog } from '../support/helpers';
|
||||
|
||||
const dialogContent = 'dialog-content';
|
||||
const nodeHealth = 'node-health';
|
||||
const statusIncidentsLink = 'footer [data-testid=external-link]';
|
||||
|
||||
describe('home', { tags: '@regression' }, () => {
|
||||
before(() => {
|
||||
@@ -9,41 +8,22 @@ describe('home', { tags: '@regression' }, () => {
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.visit('/');
|
||||
closeWelcomeDialog();
|
||||
});
|
||||
|
||||
describe('footer', () => {
|
||||
it.skip('shows current block height', () => {
|
||||
closeWelcomeDialog();
|
||||
it('shows current block height', () => {
|
||||
// 0006-NETW-004
|
||||
// 0006-NETW-005
|
||||
// 0006-NETW-008
|
||||
// 0006-NETW-009
|
||||
// 0006-NETW-011
|
||||
|
||||
cy.intercept('POST', 'http://localhost:3008/graphql', (req) => {
|
||||
req.on('response', (res) => {
|
||||
res.setDelay(3001);
|
||||
});
|
||||
});
|
||||
|
||||
cy.getByTestId(nodeHealth)
|
||||
.children()
|
||||
.first()
|
||||
.should('contain.text', 'Warning delay ( >3 sec)');
|
||||
|
||||
cy.intercept('POST', 'http://localhost:3008/graphql', (req) => {
|
||||
req.on('response', (res) => {
|
||||
res.setDelay(1);
|
||||
});
|
||||
});
|
||||
|
||||
cy.getByTestId(nodeHealth)
|
||||
.children()
|
||||
.first()
|
||||
.should('contain.text', 'Operational', { timeout: 10000 })
|
||||
.should('contain.text', 'Operational', {
|
||||
timeout: 10000,
|
||||
})
|
||||
.next()
|
||||
.should('contain.text', new URL(Cypress.env('VEGA_URL')).origin)
|
||||
.should('contain.text', new URL(Cypress.env('VEGA_URL')).hostname)
|
||||
.next()
|
||||
.should('contain.text', '100'); // all mocked queries have x-block-height header set to 100
|
||||
});
|
||||
@@ -86,12 +66,9 @@ describe('home', { tags: '@regression' }, () => {
|
||||
.focus()
|
||||
.type(new URL(Cypress.env('VEGA_URL')).origin + '/graphql');
|
||||
cy.getByTestId('connect').click();
|
||||
cy.getByTestId(nodeHealth)
|
||||
.children()
|
||||
.first()
|
||||
.should('contain.text', 'Operational');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Network switcher', () => {
|
||||
before(() => {
|
||||
cy.mockTradingPage();
|
||||
@@ -101,10 +78,21 @@ describe('home', { tags: '@regression' }, () => {
|
||||
|
||||
// 0006-NETW-002
|
||||
// 0006-NETW-003
|
||||
it('switch to fairground network', () => {
|
||||
cy.getByTestId('network-switcher').click();
|
||||
// 0006-NETW-011
|
||||
it('switch to fairground network and check status & incidents link', () => {
|
||||
cy.getByTestId('navigation')
|
||||
.find('[data-testid="network-switcher"]')
|
||||
.click();
|
||||
cy.getByTestId('network-item').contains('Fairground testnet').click();
|
||||
cy.get('[aria-haspopup="menu"]').should('contain.text', 'Fairground');
|
||||
cy.url().should('include', 'fairground.wtf');
|
||||
cy.contains('Continue').click();
|
||||
cy.get(statusIncidentsLink)
|
||||
.children('span')
|
||||
.should('have.text', 'Mainnet status & incidents');
|
||||
cy.get(statusIncidentsLink)
|
||||
.should('have.attr', 'href')
|
||||
.and('contain', 'https://blog.vega.xyz/tagged/vega-incident-reports');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { marketsDataQuery } from '@vegaprotocol/mock';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const selectMarketOverlay = 'select-market-list';
|
||||
const dialogContent = 'dialog-content';
|
||||
|
||||
const generateProposal = (code: string): ProposalListFieldsFragment => ({
|
||||
@@ -110,77 +108,12 @@ describe('home', { tags: '@regression' }, () => {
|
||||
|
||||
cy.get('main[data-testid^="/markets/"]');
|
||||
|
||||
// Overlay should be shown
|
||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||
cy.contains('Select a market to get started').should('be.visible');
|
||||
|
||||
// I expect the market overlay table to contain at least 3 rows (one header row)
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.then((row) => {
|
||||
expect(row.length >= 3).to.be.true;
|
||||
});
|
||||
|
||||
// each market shown in overlay table contains content under the last price and change fields
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.each(($element, index) => {
|
||||
if (index > 0) {
|
||||
// skip header row
|
||||
cy.root().within(() => {
|
||||
cy.getByTestId('price').should('not.be.empty');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cy.getByTestId('welcome-notice-proposed-markets')
|
||||
.children('div.pt-1.flex.justify-between')
|
||||
.should('have.length', 3)
|
||||
.each((item) => {
|
||||
cy.wrap(item).getByTestId('external-link').should('exist');
|
||||
});
|
||||
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId(selectMarketOverlay).should('not.exist');
|
||||
|
||||
// the choose market overlay is no longer showing
|
||||
cy.contains('Select a market to get started').should('not.exist');
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('market table should be properly rendered', () => {
|
||||
it('redirects to a default market with the landing dialog open', () => {
|
||||
const override = {
|
||||
marketsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
data: {
|
||||
markPrice: '46126900581221212121212121212121212121212121212',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
// @ts-ignore partial deep check failing
|
||||
const data = marketsDataQuery(override);
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'MarketsData', data);
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table')
|
||||
.invoke('outerWidth')
|
||||
.then((value) => {
|
||||
expect(value).to.be.closeTo(554, 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('no markets found', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
@@ -206,40 +139,13 @@ describe('home', { tags: '@regression' }, () => {
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
});
|
||||
it('redirects to a the empty market page and displays welcome notice', () => {
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets`);
|
||||
|
||||
it('redirects to market/all and displays welcome notice', () => {
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
cy.getByTestId('welcome-notice-title').should(
|
||||
'contain.text',
|
||||
'Welcome to Console'
|
||||
);
|
||||
cy.getByTestId('welcome-notice-proposed-markets').should(
|
||||
'contain.text',
|
||||
'AAAZZZ'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('no proposal found', () => {
|
||||
it('there is a link to propose market', () => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ProposalsList', {
|
||||
proposalsConnection: {
|
||||
__typename: 'ProposalsConnection',
|
||||
edges: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.then((row) => {
|
||||
expect(row.length >= 3).to.be.true;
|
||||
});
|
||||
cy.getByTestId('external-link')
|
||||
.contains('Propose a market')
|
||||
.should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const selectMarketOverlay = 'select-market-list';
|
||||
const marketInfoBtn = 'Info';
|
||||
const marketInfoSubtitle = 'accordion-title';
|
||||
const marketSummaryBlock = 'header-summary';
|
||||
@@ -14,45 +13,6 @@ const itemHeader = 'item-header';
|
||||
const itemValue = 'item-value';
|
||||
const marketListContent = 'popover-content';
|
||||
|
||||
describe(
|
||||
'Console - market list - live env',
|
||||
{ tags: '@live', testIsolation: true },
|
||||
() => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('shows the market list page', () => {
|
||||
cy.get('main', { timeout: 20000 });
|
||||
|
||||
// Overlay should be shown
|
||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||
cy.contains('Select a market to get started').should('be.visible');
|
||||
|
||||
// I expect the market overlay table to contain at least one row
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.should('have.length.greaterThan', 1);
|
||||
|
||||
// each market shown in overlay table contains content under the last price and change fields
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.getByTestId('price')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
|
||||
it('redirects to a default market', () => {
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId(selectMarketOverlay).should('not.exist');
|
||||
|
||||
// the choose market overlay is no longer showing
|
||||
cy.contains('Select a market to get started').should('not.exist');
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
cy.getByTestId('popover-trigger').should('not.be.empty');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe(
|
||||
'Console - market info - live env',
|
||||
{ tags: '@live', testIsolation: true },
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const rowSelector =
|
||||
'[data-testid="tab-all-markets"] .ag-center-cols-container .ag-row';
|
||||
|
||||
describe('markets all table', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage().then(() => {
|
||||
cy.mockTradingPage(
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
|
||||
);
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/all');
|
||||
});
|
||||
});
|
||||
|
||||
it('can see table headers', () => {
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
const headers = [
|
||||
'Market',
|
||||
'Description',
|
||||
'Trading mode',
|
||||
'Status',
|
||||
'Best bid',
|
||||
'Best offer',
|
||||
'Mark price',
|
||||
'Settlement asset',
|
||||
'',
|
||||
];
|
||||
cy.getByTestId('tab-all-markets').within(($headers) => {
|
||||
cy.wrap($headers)
|
||||
.get('.ag-header-cell-text')
|
||||
.each(($header, i) => {
|
||||
cy.wrap($header).should('have.text', headers[i]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('markets tab should be rendered properly', () => {
|
||||
cy.get('[data-testid="All markets"]').should(
|
||||
'have.attr',
|
||||
'data-state',
|
||||
'active'
|
||||
);
|
||||
cy.get('[data-testid="Proposed markets"]').should(
|
||||
'have.attr',
|
||||
'data-state',
|
||||
'inactive'
|
||||
);
|
||||
cy.get('[data-testid="Closed markets"]').should(
|
||||
'have.attr',
|
||||
'data-state',
|
||||
'inactive'
|
||||
);
|
||||
});
|
||||
it('renders markets correctly', () => {
|
||||
// 6001-MARK-035
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="tradableInstrument.instrument.code"]')
|
||||
.should('have.text', 'SOLUSD');
|
||||
|
||||
// 6001-MARK-036
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="tradableInstrument.instrument.name"]')
|
||||
.should('have.text', 'SUSPENDED MARKET');
|
||||
|
||||
// 6001-MARK-037
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="tradingMode"]')
|
||||
.should('have.text', 'Continuous');
|
||||
|
||||
// 6001-MARK-038
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="state"]')
|
||||
.should('have.text', 'Active');
|
||||
|
||||
// 6001-MARK-039
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="data.bestBidPrice"]')
|
||||
.should('have.text', '0.00');
|
||||
|
||||
// 6001-MARK-040
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="data.bestOfferPrice"]')
|
||||
.should('have.text', '0.00');
|
||||
|
||||
// 6001-MARK-041
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find('[col-id="data.markPrice"]')
|
||||
.should('have.text', '84.41');
|
||||
|
||||
// 6001-MARK-042
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find(
|
||||
'[col-id="tradableInstrument.instrument.product.settlementAsset.symbol"]'
|
||||
)
|
||||
.should('have.text', 'XYZalpha');
|
||||
|
||||
// 6001-MARK-043
|
||||
cy.get(rowSelector)
|
||||
.first()
|
||||
.find(
|
||||
'[col-id="tradableInstrument.instrument.product.settlementAsset.symbol"] button'
|
||||
)
|
||||
.click();
|
||||
cy.getByTestId('dialog-title').should('have.text', 'Asset details - tEURO');
|
||||
cy.getByTestId('close-asset-details-dialog').click();
|
||||
});
|
||||
|
||||
it('can open row actions', () => {
|
||||
// 6001-MARK-044
|
||||
cy.get('.ag-pinned-right-cols-container')
|
||||
.find('[col-id="market-actions"]')
|
||||
.first()
|
||||
.find('button')
|
||||
.click();
|
||||
|
||||
// 6001-MARK-045
|
||||
const dropdownContent = '[data-testid="market-actions-content"]';
|
||||
const dropdownContentItem = '[role="menuitem"]';
|
||||
cy.get(dropdownContent)
|
||||
.find(dropdownContentItem)
|
||||
.eq(0)
|
||||
// Cannot click the copy button as it falls back to window.prompt, blocking the test.
|
||||
.should('have.text', 'Copy Market ID');
|
||||
|
||||
// 6001-MARK-046
|
||||
cy.get(dropdownContent)
|
||||
.find(dropdownContentItem)
|
||||
.eq(1)
|
||||
.find('a')
|
||||
.then(($el) => {
|
||||
const href = $el.attr('href');
|
||||
expect(/\/markets\/market-1/.test(href || '')).to.equal(true);
|
||||
})
|
||||
.should('have.text', 'View on Explorer');
|
||||
|
||||
// 6001-MARK-047
|
||||
cy.get(dropdownContent)
|
||||
.find(dropdownContentItem)
|
||||
.eq(2)
|
||||
.should('have.text', 'View asset');
|
||||
cy.getByTestId('market-actions-content').click();
|
||||
});
|
||||
|
||||
it('able to open and sort full market list - market page', () => {
|
||||
const ExpectedSortedMarkets = [
|
||||
'AAPL.MF21',
|
||||
'BTCUSD.MF21',
|
||||
'ETHBTC.QM21',
|
||||
'SOLUSD',
|
||||
];
|
||||
cy.get('[data-testid="All markets"]').click({ force: true });
|
||||
cy.url().should('eq', Cypress.config('baseUrl') + '/#/markets/all');
|
||||
cy.contains('AAPL.MF21').should('be.visible');
|
||||
cy.get('.ag-header-cell-label').contains('Market').click(); // sort by market name
|
||||
for (let i = 0; i < ExpectedSortedMarkets.length; i++) {
|
||||
cy.get(`[row-index=${i}]`)
|
||||
.find('[col-id="tradableInstrument.instrument.code"]')
|
||||
.should('have.text', ExpectedSortedMarkets[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,18 @@
|
||||
import { MarketTradingModeMapping } from '@vegaprotocol/types';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
|
||||
const marketInfoBtn = 'Info';
|
||||
const row = 'key-value-table-row';
|
||||
const marketTitle = 'accordion-title';
|
||||
const externalLink = 'external-link';
|
||||
const accordionContent = 'accordion-content';
|
||||
const blockExplorerLink = 'block-explorer-link';
|
||||
const dialogClose = 'dialog-close';
|
||||
const dialogContent = 'dialog-content';
|
||||
const externalLink = 'external-link';
|
||||
const githubLink = 'github-link';
|
||||
const liquidityLink = 'view-liquidity-link';
|
||||
const marketInfoBtn = 'Info';
|
||||
const marketTitle = 'accordion-title';
|
||||
const providerName = 'provider-name';
|
||||
const oracleBannerStatus = 'oracle-banner-status';
|
||||
const oracleBannerDialogTrigger = 'oracle-banner-dialog-trigger';
|
||||
const oracleFullProfile = 'oracle-full-profile';
|
||||
const row = 'key-value-table-row';
|
||||
const verifiedProofs = 'verified-proofs';
|
||||
|
||||
describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
@@ -17,12 +20,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
before(() => {
|
||||
cy.mockTradingPage(
|
||||
MarketState.STATE_ACTIVE,
|
||||
undefined,
|
||||
undefined,
|
||||
'COMPROMISED'
|
||||
);
|
||||
cy.mockTradingPage(MarketState.STATE_ACTIVE);
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
cy.wait('@Markets');
|
||||
@@ -30,16 +28,8 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
cy.wait('@MarketInfo');
|
||||
});
|
||||
|
||||
it('show oracle banner', () => {
|
||||
cy.getByTestId(marketTitle).contains('Oracle').click();
|
||||
cy.getByTestId(oracleBannerStatus).should('contain.text', 'COMPROMISED');
|
||||
cy.getByTestId(oracleBannerDialogTrigger)
|
||||
.should('contain.text', 'Show more')
|
||||
.click();
|
||||
cy.getByTestId(oracleFullProfile).should('exist');
|
||||
});
|
||||
|
||||
it('current fees displayed', () => {
|
||||
// 6002-MDET-101
|
||||
cy.getByTestId(marketTitle).contains('Current fees').click();
|
||||
validateMarketDataRow(0, 'Maker Fee', '0.02%');
|
||||
validateMarketDataRow(1, 'Infrastructure Fee', '0.05%');
|
||||
@@ -48,6 +38,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('market price', () => {
|
||||
// 6002-MDET-102
|
||||
cy.getByTestId(marketTitle).contains('Market price').click();
|
||||
validateMarketDataRow(0, 'Mark Price', '46,126.90058');
|
||||
validateMarketDataRow(1, 'Best Bid Price', '44,126.90058 ');
|
||||
@@ -56,8 +47,8 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('market volume displayed', () => {
|
||||
// 6002-MDET-103
|
||||
cy.getByTestId(marketTitle).contains('Market volume').click();
|
||||
validateMarketDataRow(0, '24 Hour Volume', '1');
|
||||
validateMarketDataRow(1, 'Open Interest', '-');
|
||||
validateMarketDataRow(2, 'Best Bid Volume', '1');
|
||||
validateMarketDataRow(3, 'Best Offer Volume', '3');
|
||||
@@ -66,11 +57,13 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('insurance pool displayed', () => {
|
||||
// 6002-MDET-104
|
||||
cy.getByTestId(marketTitle).contains('Insurance pool').click();
|
||||
validateMarketDataRow(0, 'Balance', '0');
|
||||
});
|
||||
|
||||
it('key details displayed', () => {
|
||||
// 6002-MDET-201
|
||||
cy.getByTestId(marketTitle).contains('Key details').click();
|
||||
|
||||
validateMarketDataRow(0, 'Name', 'BTCUSD Monthly (30 Jun 2022)');
|
||||
@@ -86,6 +79,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('instrument displayed', () => {
|
||||
// 6002-MDET-202
|
||||
cy.getByTestId(marketTitle).contains('Instrument').click();
|
||||
|
||||
validateMarketDataRow(0, 'Market Name', 'BTCUSD Monthly (30 Jun 2022)');
|
||||
@@ -94,7 +88,30 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
validateMarketDataRow(3, 'Quote Name', 'BTC');
|
||||
});
|
||||
|
||||
it('oracle displayed', () => {
|
||||
// 6002-MDET-203
|
||||
cy.getByTestId(marketTitle).contains('Oracle').click();
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId(providerName)
|
||||
.and('contain', 'Another oracle');
|
||||
|
||||
cy.getByTestId(providerName).should('be.visible').click();
|
||||
cy.getByTestId(dialogContent)
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.getByTestId(blockExplorerLink).contains('Block explorer');
|
||||
cy.getByTestId(githubLink).contains('Oracle repository');
|
||||
});
|
||||
cy.getByTestId(dialogClose).click();
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId(verifiedProofs)
|
||||
.and('contain', '1');
|
||||
});
|
||||
|
||||
it('settlement asset displayed', () => {
|
||||
// 6002-MDET-206
|
||||
cy.getByTestId(marketTitle).contains('Settlement asset').click();
|
||||
cy.window().then((win) => {
|
||||
cy.stub(win, 'prompt').returns('DISABLED WINDOW PROMPT');
|
||||
@@ -113,9 +130,12 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
);
|
||||
validateMarketDataRow(8, 'Withdrawal threshold', '0.0005');
|
||||
validateMarketDataRow(9, 'Lifetime limit', '1,230');
|
||||
validateMarketDataRow(10, 'Infrastructure fee account balance', '0.00001');
|
||||
validateMarketDataRow(11, 'Global reward pool account balance', '0.00002');
|
||||
});
|
||||
|
||||
it('metadata displayed', () => {
|
||||
// 6002-MDET-207
|
||||
cy.getByTestId(marketTitle).contains('Metadata').click();
|
||||
|
||||
validateMarketDataRow(0, 'Formerly', '076BB86A5AA41E3E');
|
||||
@@ -126,18 +146,21 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('risk model displayed', () => {
|
||||
// 6002-MDET-208
|
||||
cy.getByTestId(marketTitle).contains('Risk model').click();
|
||||
validateMarketDataRow(0, 'Tau', '0.0001140771161');
|
||||
validateMarketDataRow(1, 'Risk Aversion Parameter', '0.01');
|
||||
});
|
||||
|
||||
it('risk parameters displayed', () => {
|
||||
// 6002-MDET-209
|
||||
cy.getByTestId(marketTitle).contains('Risk parameters').click();
|
||||
validateMarketDataRow(0, 'R', '0.016');
|
||||
validateMarketDataRow(1, 'Sigma', '0.3');
|
||||
});
|
||||
|
||||
it('risk factors displayed', () => {
|
||||
// 6002-MDET-210
|
||||
cy.getByTestId(marketTitle).contains('Risk factors').click();
|
||||
|
||||
validateMarketDataRow(0, 'Short', '0.008571790367285281');
|
||||
@@ -145,6 +168,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('price monitoring bounds displayed', () => {
|
||||
// 6002-MDET-211
|
||||
cy.getByTestId(marketTitle).contains('Price monitoring bounds 1').click();
|
||||
cy.get('p.col-span-1').contains('99.99999% probability price bounds');
|
||||
cy.get('p.col-span-1').contains('Within 43,200 seconds');
|
||||
@@ -153,6 +177,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('liquidity monitoring parameters displayed', () => {
|
||||
// 6002-MDET-212
|
||||
cy.getByTestId(marketTitle)
|
||||
.contains('Liquidity monitoring parameters')
|
||||
.click();
|
||||
@@ -163,6 +188,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('liquidity displayed', () => {
|
||||
// 6002-MDET-213
|
||||
cy.getByTestId(marketTitle)
|
||||
.contains(/Liquidity(?! m)/)
|
||||
.click();
|
||||
@@ -170,14 +196,14 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
validateMarketDataRow(0, 'Target Stake', '10.00 tBTC');
|
||||
validateMarketDataRow(1, 'Supplied Stake', '0.01 tBTC');
|
||||
validateMarketDataRow(2, 'Market Value Proxy', '20.00 tBTC');
|
||||
|
||||
cy.getByTestId('view-liquidity-link').should(
|
||||
cy.getByTestId(liquidityLink).should(
|
||||
'have.text',
|
||||
'View liquidity provision table'
|
||||
);
|
||||
});
|
||||
|
||||
it('liquidity price range displayed', () => {
|
||||
// 6002-MDET-214
|
||||
cy.getByTestId(marketTitle).contains('Liquidity price range').click();
|
||||
|
||||
validateMarketDataRow(0, 'Liquidity Price Range', '2.00% of mid price');
|
||||
@@ -185,29 +211,8 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
||||
validateMarketDataRow(2, 'Highest Price', '47,049.438 BTC');
|
||||
});
|
||||
|
||||
it('oracle displayed', () => {
|
||||
cy.getByTestId(marketTitle).contains('Oracle').click();
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId(providerName)
|
||||
.and('contain', 'Another oracle');
|
||||
|
||||
cy.getByTestId(providerName).should('be.visible').click();
|
||||
|
||||
cy.getByTestId('dialog-content')
|
||||
.eq(1)
|
||||
.within(() => {
|
||||
cy.getByTestId('block-explorer-link').contains('Block explorer');
|
||||
cy.getByTestId('github-link').contains('Oracle repository');
|
||||
});
|
||||
cy.getByTestId('dialog-close').click();
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
.getByTestId('verified-proofs')
|
||||
.and('contain', '1');
|
||||
});
|
||||
|
||||
it('proposal displayed', () => {
|
||||
// 6002-MDET-301
|
||||
cy.getByTestId(marketTitle).contains('Proposal').click();
|
||||
|
||||
cy.getByTestId(accordionContent)
|
||||
|
||||
@@ -38,28 +38,28 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
// TODO: load data from mocks in. Using alias and wrap intermittently fails
|
||||
const data = [
|
||||
{
|
||||
code: 'AAPL.MF21',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
},
|
||||
{
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'ACTIVE MARKET',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
code: 'SOLUSD',
|
||||
markPrice: '84.41XYZalpha',
|
||||
change: '',
|
||||
vol: '0.0024h vol',
|
||||
},
|
||||
{
|
||||
code: 'ETHBTC.QM21',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
markPrice: '46,126.90058tBTC',
|
||||
change: '',
|
||||
vol: '0.0024h vol',
|
||||
},
|
||||
{
|
||||
code: 'SOLUSD',
|
||||
name: 'SUSPENDED MARKET',
|
||||
markPrice: '84.41',
|
||||
change: '+200.00%',
|
||||
code: 'BTCUSD.MF21',
|
||||
markPrice: '46,126.90058tDAI',
|
||||
change: '',
|
||||
vol: '0.0024h vol',
|
||||
},
|
||||
{
|
||||
code: 'AAPL.MF21',
|
||||
markPrice: '46,126.90058tUSDC',
|
||||
change: '',
|
||||
vol: '0.0024h vol',
|
||||
},
|
||||
];
|
||||
cy.getByTestId(list)
|
||||
@@ -68,18 +68,19 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
const market = data[i];
|
||||
// 6001-MARK-021
|
||||
expect(item.find('h3').text()).equals(market.code);
|
||||
// 6001-MARK-022
|
||||
expect(item.find('h4').text()).equals(market.name);
|
||||
expect(
|
||||
item.find('[data-testid="market-selector-data-row"]').eq(0).text()
|
||||
).contains(market.vol);
|
||||
// 6001-MARK-024
|
||||
expect(item.find('[data-testid="market-item-price"]').text()).equals(
|
||||
market.markPrice
|
||||
);
|
||||
expect(
|
||||
item.find('[data-testid="market-selector-data-row"]').eq(1).text()
|
||||
).contains(market.markPrice);
|
||||
// 6001-MARK-023
|
||||
expect(item.find('[data-testid="market-item-change"]').text()).equals(
|
||||
market.change
|
||||
);
|
||||
// 6001-MARK-025
|
||||
expect(item.find('[data-testid="sparkline-svg"]')).to.exist;
|
||||
expect(item.find('[data-testid="sparkline-svg"]')).to.not.exist;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -96,8 +97,8 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
// 6001-MARK-29
|
||||
cy.getByTestId(searchInput).clear().type('btc');
|
||||
cy.getByTestId(list).find('a').should('have.length', 2);
|
||||
cy.getByTestId(list).find('a').eq(0).contains('BTCUSD.MF21');
|
||||
cy.getByTestId(list).find('a').eq(1).contains('ETHBTC.QM21');
|
||||
cy.getByTestId(list).find('a').eq(1).contains('BTCUSD.MF21');
|
||||
cy.getByTestId(list).find('a').eq(0).contains('ETHBTC.QM21');
|
||||
|
||||
cy.getByTestId(searchInput).clear();
|
||||
cy.getByTestId(list).find('a').should('have.length', 4);
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const marketSummaryBlock = 'header-summary';
|
||||
const marketExpiry = 'market-expiry';
|
||||
const marketPrice = 'market-price';
|
||||
const marketChange = 'market-change';
|
||||
const marketVolume = 'market-volume';
|
||||
const marketMode = 'market-trading-mode';
|
||||
const marketState = 'market-state';
|
||||
const marketSettlement = 'market-settlement-asset';
|
||||
const percentageValue = 'price-change-percentage';
|
||||
const priceChangeValue = 'price-change';
|
||||
const expirtyTooltip = 'expiry-tooltip';
|
||||
const externalLink = 'external-link';
|
||||
const itemHeader = 'item-header';
|
||||
const itemValue = 'item-value';
|
||||
const link = 'link';
|
||||
const liquidityLink = 'view-liquidity-link';
|
||||
const liquiditySupplied = 'liquidity-supplied';
|
||||
const liquiditySuppliedTooltip = 'liquidity-supplied-tooltip';
|
||||
const marketChange = 'market-change';
|
||||
const marketExpiry = 'market-expiry';
|
||||
const marketMode = 'market-trading-mode';
|
||||
const marketName = 'header-title';
|
||||
const marketPrice = 'market-price';
|
||||
const marketSettlement = 'market-settlement-asset';
|
||||
const marketState = 'market-state';
|
||||
const marketSummaryBlock = 'header-summary';
|
||||
const marketVolume = 'market-volume';
|
||||
const percentageValue = 'price-change-percentage';
|
||||
const priceChangeValue = 'price-change';
|
||||
const tradingModeTooltip = 'trading-mode-tooltip';
|
||||
|
||||
describe('Market trading page', () => {
|
||||
before(() => {
|
||||
@@ -31,10 +39,12 @@ describe('Market trading page', () => {
|
||||
// 7002-SORD-001
|
||||
// 7002-SORD-002
|
||||
it('must display market name', () => {
|
||||
cy.getByTestId('header-title').should('not.be.empty');
|
||||
// 6002-MDET-001
|
||||
cy.getByTestId(marketName).should('not.be.empty');
|
||||
});
|
||||
|
||||
it('must see market expiry', () => {
|
||||
// 6002-MDET-002
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketExpiry).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Expiry');
|
||||
@@ -44,6 +54,7 @@ describe('Market trading page', () => {
|
||||
});
|
||||
|
||||
it('must see market price', () => {
|
||||
// 6002-MDET-003
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketPrice).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Price');
|
||||
@@ -53,6 +64,7 @@ describe('Market trading page', () => {
|
||||
});
|
||||
|
||||
it('must see market change', () => {
|
||||
// 6002-MDET-004
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketChange).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Change (24h)');
|
||||
@@ -63,6 +75,7 @@ describe('Market trading page', () => {
|
||||
});
|
||||
|
||||
it('must see market volume', () => {
|
||||
// 6002-MDET-005
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketVolume).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Volume (24h)');
|
||||
@@ -72,16 +85,21 @@ describe('Market trading page', () => {
|
||||
});
|
||||
|
||||
it('must see market mode', () => {
|
||||
// 6002-MDET-006
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketMode).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Trading mode');
|
||||
cy.getByTestId(itemValue).should('not.be.empty');
|
||||
cy.getByTestId(itemValue).should(
|
||||
'have.text',
|
||||
'Monitoring auction - liquidity (target not met)'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('must see market state', () => {
|
||||
//7002-SORD-061
|
||||
it('must see market status', () => {
|
||||
// 6002-MDET-007
|
||||
// 7002-SORD-061
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketState).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Status');
|
||||
@@ -91,6 +109,7 @@ describe('Market trading page', () => {
|
||||
});
|
||||
|
||||
it('must see market settlement', () => {
|
||||
// 6002-MDET-008
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketSettlement).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Settlement asset');
|
||||
@@ -98,15 +117,12 @@ describe('Market trading page', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('must see market mode', () => {
|
||||
it('must see market liquidity supplied', () => {
|
||||
// 6002-MDET-009
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(marketMode).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Trading mode');
|
||||
cy.getByTestId(itemValue).should(
|
||||
'have.text',
|
||||
'Monitoring auction - liquidity (target not met)'
|
||||
);
|
||||
cy.getByTestId(liquiditySupplied).within(() => {
|
||||
cy.getByTestId(itemHeader).should('have.text', 'Liquidity supplied');
|
||||
cy.getByTestId(itemValue).should('not.be.empty');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -121,14 +137,14 @@ describe('Market trading page', () => {
|
||||
.realHover();
|
||||
});
|
||||
});
|
||||
cy.getByTestId('expiry-tooltip')
|
||||
cy.getByTestId(expirtyTooltip)
|
||||
.eq(0)
|
||||
.should(
|
||||
'contain.text',
|
||||
'This market expires when triggered by its oracle, not on a set date.'
|
||||
)
|
||||
.within(() => {
|
||||
cy.getByTestId('link')
|
||||
cy.getByTestId(link)
|
||||
.should('have.attr', 'href')
|
||||
.and('include', Cypress.env('EXPLORER_URL'));
|
||||
});
|
||||
@@ -154,15 +170,14 @@ describe('Market trading page', () => {
|
||||
.realHover();
|
||||
});
|
||||
});
|
||||
|
||||
cy.getByTestId('trading-mode-tooltip')
|
||||
cy.getByTestId(tradingModeTooltip)
|
||||
.should(
|
||||
'contain.text',
|
||||
'This market is in auction until it reaches sufficient liquidity.'
|
||||
)
|
||||
.eq(0)
|
||||
.within(() => {
|
||||
cy.getByTestId('external-link')
|
||||
cy.getByTestId(externalLink)
|
||||
.should('have.attr', 'href')
|
||||
.and('include', Cypress.env('TRADING_MODE_LINK'));
|
||||
|
||||
@@ -174,5 +189,27 @@ describe('Market trading page', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should see liquidity supplied tooltip', () => {
|
||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||
cy.getByTestId(liquiditySupplied).within(() => {
|
||||
cy.getByTestId(itemValue).realHover();
|
||||
});
|
||||
});
|
||||
cy.getByTestId(liquiditySuppliedTooltip)
|
||||
.should('contain.text', 'Supplied stake')
|
||||
.and('contain.text', 'Target stake')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.getByTestId(liquidityLink).should(
|
||||
'have.text',
|
||||
'View liquidity provision table'
|
||||
);
|
||||
cy.getByTestId(externalLink).should(
|
||||
'have.text',
|
||||
'Learn about providing liquidity'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user