Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f784bd552c |
@@ -14,7 +14,8 @@ What we need to achieve and who for
|
|||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
- [ ]
|
- [ ] What do we need to do first
|
||||||
- [ ]
|
- [ ] and then what?
|
||||||
|
- [ ] Etc.
|
||||||
|
|
||||||
## Additional details / background info
|
## Additional details / background info
|
||||||
|
|||||||
@@ -22,14 +22,11 @@ So that
|
|||||||
|
|
||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
- [ ] UX (if needed)
|
- [ ] Explore and sketch
|
||||||
- [ ] Design (if needed)
|
|
||||||
- [ ] Team and stakeholder review
|
- [ ] Team and stakeholder review
|
||||||
- [ ] Specs reviewed and created or adjusted
|
- [ ] Visual Design
|
||||||
- [ ] Implementation
|
- [ ] Team review
|
||||||
- [ ] Testing (unit and/or e2e)
|
- [ ] Etc.
|
||||||
- [ ] Code review
|
|
||||||
- [ ] QA review
|
|
||||||
|
|
||||||
## Sketch
|
## Sketch
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
name: After Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
after-release:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log in to the Container registry (ghcr)
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Log in to the Container registry (docker hub)
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: resolve ipfs hashes for release
|
|
||||||
run: |
|
|
||||||
echo "Name: ${{ github.event.release.name }}"
|
|
||||||
echo "Description: ${{ github.event.release.body }}"
|
|
||||||
echo "Tag: ${{ github.event.release.tag_name }}"
|
|
||||||
commit="$(git rev-list -n 1 ${{ github.event.release.tag_name }})"
|
|
||||||
echo "Commit: $commit"
|
|
||||||
until docker pull vegaprotocol/trading:$commit; do
|
|
||||||
echo "Image not pushed yet, waiting 60 seconds"
|
|
||||||
sleep 60
|
|
||||||
done
|
|
||||||
docker run --rm vegaprotocol/trading:$commit cat /ipfs-hash > ipfs-hash
|
|
||||||
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
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
which ipfs
|
|
||||||
echo IPFS_V0=$(cat ipfs-hash) >> $GITHUB_ENV
|
|
||||||
echo IPFS_V1=$(ipfs cid format -v 1 -b base32 $(cat ipfs-hash)) >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Edit Release
|
|
||||||
uses: irongut/EditRelease@v1.2.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
id: ${{ github.event.release.id }}
|
|
||||||
body: |
|
|
||||||
|
|
||||||
___
|
|
||||||
|
|
||||||
# Deployments
|
|
||||||
* https://explorer.vega.xyz
|
|
||||||
* https://governance.vega.xyz
|
|
||||||
|
|
||||||
# IPFS releases
|
|
||||||
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 [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/).
|
|
||||||
|
|
||||||
Your settings are not remembered across different URLs.
|
|
||||||
|
|
||||||
IPFS gateways:
|
|
||||||
|
|
||||||
https://${{ env.IPFS_V1 }}.ipfs.dweb.link/
|
|
||||||
https://${{ env.IPFS_V1 }}.ipfs.cf-ipfs.com/
|
|
||||||
ipfs://${{ env.IPFS_V0 }}/
|
|
||||||
@@ -5,7 +5,8 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- release/*
|
- release/*
|
||||||
- develop
|
- develop
|
||||||
- main
|
tags:
|
||||||
|
- v*
|
||||||
pull_request:
|
pull_request:
|
||||||
types:
|
types:
|
||||||
- opened
|
- opened
|
||||||
@@ -97,79 +98,44 @@ jobs:
|
|||||||
# See affected apps
|
# See affected apps
|
||||||
- name: See affected apps
|
- name: See affected apps
|
||||||
run: |
|
run: |
|
||||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
|
||||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
|
||||||
|
|
||||||
echo ">>>> debug"
|
echo ">>>> debug"
|
||||||
echo "NX_BASE: ${{ env.NX_BASE }}"
|
echo "NX_BASE: ${{ env.NX_BASE }}"
|
||||||
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
||||||
echo "Affected: ${affected}"
|
|
||||||
echo "Branch slug: ${branch_slug}"
|
|
||||||
echo ">>>> eof debug"
|
echo ">>>> eof debug"
|
||||||
|
|
||||||
|
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
||||||
|
|
||||||
|
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||||
projects_e2e=""
|
projects_e2e=""
|
||||||
preview_governance="not deployed"
|
preview_governance="not deployed"
|
||||||
preview_trading="not deployed"
|
preview_trading="not deployed"
|
||||||
preview_explorer="not deployed"
|
preview_explorer="not deployed"
|
||||||
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 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 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
|
|
||||||
if [[ -z "$projects_e2e" ]]; then
|
if [[ -z "$projects_e2e" ]]; then
|
||||||
projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '
|
projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '
|
||||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||||
fi
|
else
|
||||||
projects="$(echo $projects_e2e | sed 's|-e2e||g')"
|
if [[ $affected == *"governance"* ]]; then
|
||||||
if [[ "${{ github.event_name }}" = "pull_request" ]]; then
|
projects_e2e+='"governance-e2e" '
|
||||||
if echo "$affected" | grep -q multisig-signer; then
|
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||||
echo "Tools are affected"
|
|
||||||
# tools are only applicable to check previews or deploy from develop to mainnet
|
|
||||||
echo "Deploying tools on preview"
|
|
||||||
preview_tools=$(printf "https://%s.%s.vega.rocks" "tools" "$branch_slug")
|
|
||||||
projects+=' "multisig-signer" '
|
|
||||||
fi
|
fi
|
||||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
if [[ $affected == *"trading"* ]]; then
|
||||||
if echo "$affected" | grep -q multisig-signer; then
|
projects_e2e+='"trading-e2e" '
|
||||||
echo "Tools are affected"
|
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||||
# tools are only applicable to check previews or deploy from develop to mainnet
|
|
||||||
echo "Deploying tools on s3"
|
|
||||||
projects+=' "multisig-signer" '
|
|
||||||
fi
|
fi
|
||||||
if echo "$affected" | grep -q static; then
|
if [[ $affected == *"explorer"* ]]; then
|
||||||
echo "static is affected"
|
projects_e2e+='"explorer-e2e" '
|
||||||
echo "Deploying static on s3"
|
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||||
projects+=' "static" '
|
|
||||||
fi
|
|
||||||
if echo "$affected" | grep -q ui-toolkit; then
|
|
||||||
echo "ui-toolkit is affected"
|
|
||||||
echo "Deploying ui-toolkit on s3"
|
|
||||||
projects+=' "ui-toolkit" '
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
projects_e2e=${projects_e2e%?}
|
projects_e2e=${projects_e2e%?}
|
||||||
projects_e2e=[${projects_e2e// /,}]
|
projects_e2e=[${projects_e2e// /,}]
|
||||||
projects=[${projects// /,}]
|
|
||||||
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
|
echo PROJECTS_E2E=$projects_e2e >> $GITHUB_ENV
|
||||||
echo PROJECTS=$projects >> $GITHUB_ENV
|
echo PROJECTS=$(echo $projects_e2e | sed 's|-e2e||g') >> $GITHUB_ENV
|
||||||
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
|
echo PREVIEW_GOVERNANCE=$preview_governance >> $GITHUB_ENV
|
||||||
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
|
echo PREVIEW_TRADING=$preview_trading >> $GITHUB_ENV
|
||||||
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
|
echo PREVIEW_EXPLORER=$preview_explorer >> $GITHUB_ENV
|
||||||
echo PREVIEW_TOOLS=$preview_tools >> $GITHUB_ENV
|
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
projects: ${{ env.PROJECTS }}
|
projects: ${{ env.PROJECTS }}
|
||||||
@@ -177,12 +143,11 @@ jobs:
|
|||||||
preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
|
preview_governance: ${{ env.PREVIEW_GOVERNANCE }}
|
||||||
preview_trading: ${{ env.PREVIEW_TRADING }}
|
preview_trading: ${{ env.PREVIEW_TRADING }}
|
||||||
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
preview_explorer: ${{ env.PREVIEW_EXPLORER }}
|
||||||
preview_tools: ${{ env.PREVIEW_TOOLS }}
|
|
||||||
|
|
||||||
cypress:
|
cypress:
|
||||||
needs: lint-test-build
|
needs: lint-test-build
|
||||||
name: '(CI) cypress'
|
name: '(CI) cypress'
|
||||||
if: ${{ needs.lint-test-build.outputs.projects-e2e != '[]' }}
|
if: ${{ needs.lint-test-build.outputs.projects != '[]' }}
|
||||||
uses: ./.github/workflows/cypress-run.yml
|
uses: ./.github/workflows/cypress-run.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
@@ -204,7 +169,6 @@ jobs:
|
|||||||
- publish-dist
|
- publish-dist
|
||||||
- lint-test-build
|
- lint-test-build
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
timeout-minutes: 60
|
|
||||||
name: '(CD) comment preview links'
|
name: '(CD) comment preview links'
|
||||||
steps:
|
steps:
|
||||||
- name: Find Comment
|
- name: Find Comment
|
||||||
@@ -214,35 +178,6 @@ jobs:
|
|||||||
issue-number: ${{ github.event.pull_request.number }}
|
issue-number: ${{ github.event.pull_request.number }}
|
||||||
body-includes: Previews
|
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
|
- name: Create comment
|
||||||
uses: peter-evans/create-or-update-comment@v3
|
uses: peter-evans/create-or-update-comment@v3
|
||||||
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
if: ${{ steps.fc.outputs.comment-id == 0 }}
|
||||||
@@ -253,11 +188,16 @@ jobs:
|
|||||||
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
|
* governance: ${{ needs.lint-test-build.outputs.preview_governance }}
|
||||||
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
* explorer: ${{ needs.lint-test-build.outputs.preview_explorer }}
|
||||||
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
* trading: ${{ needs.lint-test-build.outputs.preview_trading }}
|
||||||
* tools: ${{ needs.lint-test-build.outputs.preview_tools }}
|
|
||||||
|
|
||||||
# Report single result at the end, to avoid mess with required checks in PR
|
|
||||||
cypress-check:
|
cypress-check:
|
||||||
name: '(CI) cypress - check'
|
name: '(CI) cypress - check'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: cypress
|
||||||
|
steps:
|
||||||
|
- run: echo Done!
|
||||||
|
|
||||||
|
# Report single result at the end, to avoid mess with required checks in PR
|
||||||
|
cypress-result:
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
needs: cypress
|
needs: cypress
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|||||||
@@ -33,4 +33,5 @@ jobs:
|
|||||||
config: baseUrl=${{ github.event.inputs.url }}
|
config: baseUrl=${{ github.event.inputs.url }}
|
||||||
env: grepTags=@live
|
env: grepTags=@live
|
||||||
env:
|
env:
|
||||||
|
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
project: ${{ fromJSON(inputs.projects) }}
|
project: ${{ fromJSON(inputs.projects) }}
|
||||||
name: ${{ matrix.project }}
|
name: ${{ matrix.project }}
|
||||||
runs-on: self-hosted-runner
|
runs-on: self-hosted-runner
|
||||||
timeout-minutes: 100
|
timeout-minutes: 40
|
||||||
steps:
|
steps:
|
||||||
# Checks if skip cache was requested
|
# Checks if skip cache was requested
|
||||||
- name: Set skip-nx-cache flag
|
- name: Set skip-nx-cache flag
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
######
|
######
|
||||||
|
|
||||||
- name: Run Cypress tests
|
- name: Run Cypress tests
|
||||||
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --browser chrome --env.grepTags="${{ inputs.tags }}"
|
run: yarn nx run ${{ matrix.project }}:e2e ${{ env.SKIP_CACHE }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome --env.grepTags="${{ inputs.tags }}"
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
@@ -98,4 +98,4 @@ jobs:
|
|||||||
if: ${{ failure() }}
|
if: ${{ failure() }}
|
||||||
with:
|
with:
|
||||||
name: test-report-${{ matrix.project }}
|
name: test-report-${{ matrix.project }}
|
||||||
path: frontend-monorepo/apps/${{ matrix.project }}/cypress/reports
|
path: frontend-monorepo/apps/trading-e2e/cypress/reports
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
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
|
||||||
@@ -31,7 +31,6 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v2
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Log in to the Container registry (ghcr)
|
- name: Log in to the Container registry (ghcr)
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
@@ -40,7 +39,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Log in to the Container registry (docker hub)
|
- name: Log in to the Container registry (docker hub)
|
||||||
uses: docker/login-action@v2
|
uses: docker/login-action@v2
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||||
with:
|
with:
|
||||||
# registry: registry.hub.docker.com
|
# registry: registry.hub.docker.com
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
@@ -60,68 +59,38 @@ jobs:
|
|||||||
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||||
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||||
- name: Define dist variables
|
- name: Define variables
|
||||||
if: ${{ github.event_name == 'push' }}
|
|
||||||
run: |
|
run: |
|
||||||
envName=''
|
envName=''
|
||||||
domain="vega.rocks"
|
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||||
bucketName=''
|
domain="vega.rocks"
|
||||||
|
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
if [[ "${{ github.ref }}" =~ .*mainnet.* ]]; then
|
||||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
domain="vega.community"
|
||||||
envName="stagnet1"
|
fi
|
||||||
if [[ "${{ matrix.app }}" = "multisig-signer" ]]; then
|
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||||
|
envName="stagnet1"
|
||||||
|
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
||||||
envName="mainnet"
|
envName="mainnet"
|
||||||
bucketName="tools.vega.xyz"
|
|
||||||
fi
|
fi
|
||||||
if [[ "${{ matrix.app }}" = "static" ]]; then
|
|
||||||
envName="mainnet"
|
|
||||||
bucketName="static.vega.xyz"
|
|
||||||
fi
|
|
||||||
if [[ "${{ matrix.app }}" = "ui-toolkit" ]]; then
|
|
||||||
envName="mainnet"
|
|
||||||
bucketName="ui.vega.rocks"
|
|
||||||
fi
|
|
||||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; 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}"
|
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||||
|
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "bucket name: ${bucketName}"
|
|
||||||
echo "env name: ${envName}"
|
|
||||||
|
|
||||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
|
||||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build local dist
|
- name: Build local dist
|
||||||
run: |
|
run: |
|
||||||
flags=""
|
flags=""
|
||||||
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
|
if [[ ! -z "${{ env.ENV_NAME }}" ]]; then
|
||||||
flags="--env=${{ env.ENV_NAME }}"
|
if [[ "${{ env.ENV_NAME }}" != "ops-vega" ]]; then
|
||||||
|
flags="--env=${{ env.ENV_NAME }}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${{ matrix.app }}" = "trading" ]; then
|
if [ "${{ matrix.app }}" = "trading" ]; then
|
||||||
yarn nx export trading $flags || (yarn install && yarn nx export trading $flags)
|
yarn nx export trading $flags || (yarn install && yarn nx export trading $flags)
|
||||||
DIST_LOCATION=dist/apps/trading/exported
|
DIST_LOCATION=dist/apps/trading/exported
|
||||||
elif [ "${{ matrix.app }}" = "ui-toolkit" ]; then
|
|
||||||
NODE_ENV=production yarn nx run ui-toolkit:build-storybook
|
|
||||||
DIST_LOCATION=dist/storybook/ui-toolkit
|
|
||||||
else
|
else
|
||||||
yarn nx build ${{ matrix.app }} $flags || (yarn install && yarn nx build ${{ matrix.app }} $flags)
|
yarn nx build ${{ matrix.app }} $flags || (yarn install && yarn nx build ${{ matrix.app }} $flags)
|
||||||
DIST_LOCATION=dist/apps/${{ matrix.app }}
|
DIST_LOCATION=dist/apps/${{ matrix.app }}
|
||||||
@@ -150,15 +119,13 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "Check ipfs-hash"
|
echo "Check ipfs-hash"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matrix.app }}-ipfs-hash
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local cat /ipfs-hash > ${{ matirx.app }}-ipfs-hash
|
||||||
echo "List html directory"
|
echo "List html directory"
|
||||||
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
docker run --rm ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:local sh -c 'apk add --update tree; tree /usr/share/nginx/html'
|
||||||
|
|
||||||
- name: Publish dist as docker image (ghcr)
|
- name: Publish dist as docker image (ghcr)
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
continue-on-error: true
|
if: ${{ github.event_name == 'pull_request' || (matrix.app == 'trading' && github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') ) }}
|
||||||
id: ghcr-push
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/node-outside-docker.Dockerfile
|
file: docker/node-outside-docker.Dockerfile
|
||||||
@@ -171,9 +138,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish dist as docker image (docker hub)
|
- name: Publish dist as docker image (docker hub)
|
||||||
uses: docker/build-push-action@v3
|
uses: docker/build-push-action@v3
|
||||||
continue-on-error: true
|
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||||
id: dockerhub-push
|
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: docker/node-outside-docker.Dockerfile
|
file: docker/node-outside-docker.Dockerfile
|
||||||
@@ -182,41 +147,12 @@ jobs:
|
|||||||
APP=${{ matrix.app }}
|
APP=${{ matrix.app }}
|
||||||
ENV_NAME=${{ env.ENV_NAME }}
|
ENV_NAME=${{ env.ENV_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
vegaprotocol/${{ matrix.app }}:${{ github.ref_name }}
|
||||||
vegaprotocol/${{ matrix.app }}:${{ endsWith(github.ref, 'main') && 'mainnet' || endsWith(github.ref, 'release/testnet') && 'testnet' || '' }}
|
|
||||||
|
|
||||||
- name: Publish dist as docker image (ghcr - retry)
|
|
||||||
uses: docker/build-push-action@v3
|
|
||||||
if: ${{ steps.ghcr-push.outcome == 'failure' }}
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: docker/node-outside-docker.Dockerfile
|
|
||||||
push: true
|
|
||||||
build-args: |
|
|
||||||
APP=${{ matrix.app }}
|
|
||||||
ENV_NAME=${{ env.ENV_NAME }}
|
|
||||||
tags: |
|
|
||||||
ghcr.io/vegaprotocol/frontend/${{ matrix.app }}:${{ github.event.pull_request.head.sha || github.sha }}
|
|
||||||
|
|
||||||
- name: Publish dist as docker image (docker hub - retry)
|
|
||||||
uses: docker/build-push-action@v3
|
|
||||||
if: ${{ steps.dockerhub-push.outcome == 'failure' }}
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: docker/node-outside-docker.Dockerfile
|
|
||||||
push: true
|
|
||||||
build-args: |
|
|
||||||
APP=${{ matrix.app }}
|
|
||||||
ENV_NAME=${{ env.ENV_NAME }}
|
|
||||||
tags: |
|
|
||||||
vegaprotocol/${{ matrix.app }}:${{ github.sha }}
|
|
||||||
vegaprotocol/${{ matrix.app }}:${{ endsWith(github.ref, 'main') && 'mainnet' || endsWith(github.ref, 'release/testnet') && 'testnet' || '' }}
|
|
||||||
|
|
||||||
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||||
- name: Publish dist to s3
|
- name: Publish dist to s3
|
||||||
uses: jakejarvis/s3-sync-action@master
|
uses: jakejarvis/s3-sync-action@master
|
||||||
# s3 releases are not happening for trading on mainnet - it's IPFS
|
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') }}
|
||||||
if: ${{ github.event_name == 'push' && ( matrix.app != 'trading' || (matrix.app == 'trading' && !( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) ) ) }}
|
|
||||||
with:
|
with:
|
||||||
args: --acl private --follow-symlinks --delete
|
args: --acl private --follow-symlinks --delete
|
||||||
env:
|
env:
|
||||||
@@ -233,81 +169,8 @@ jobs:
|
|||||||
labels: ${{ matrix.app }}-preview
|
labels: ${{ matrix.app }}-preview
|
||||||
number: ${{ github.event.number }}
|
number: ${{ github.event.number }}
|
||||||
|
|
||||||
- name: Trigger fleek deployment
|
- name: Add ipfs hash to release
|
||||||
# release to ipfs happens only on mainnet (represented by main branch) for trading
|
uses: softprops/action-gh-release@v1
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'release/testnet') ) }}
|
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }}
|
||||||
run: |
|
|
||||||
if echo ${{ github.ref }} | grep -q main; then
|
|
||||||
# display info about app
|
|
||||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "query{getSiteById(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id latestDeploy{id status}}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
# trigger new deployment as base image is always set to vegaprotocol/trading:mainnet
|
|
||||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
elif echo ${{ github.ref }} | grep -q release/testnet; then
|
|
||||||
# display info about app
|
|
||||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "query{getSiteById(siteId:\"79baaeca-1952-4ae7-a256-f668cfc1d68e\"){id latestDeploy{id status}}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
# trigger new deployment as base image is always set to vegaprotocol/trading:mainnet
|
|
||||||
curl --fail -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "mutation{triggerDeploy(siteId:\"79baaeca-1952-4ae7-a256-f668cfc1d68e\"){id status}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Check out ipfs-redirect
|
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'testnet') ) }}
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
with:
|
||||||
repository: 'vegaprotocol/ipfs-redirect'
|
files: ${{ matrix.app }}-ipfs-hash
|
||||||
path: 'ipfs-redirect'
|
|
||||||
fetch-depth: '0'
|
|
||||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Update interstitial page to point to the new console
|
|
||||||
if: ${{ matrix.app == 'trading' && github.event_name == 'push' && ( endsWith(github.ref, 'main') || endsWith(github.ref, 'testnet') ) }}
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
|
||||||
run: |
|
|
||||||
# set CID
|
|
||||||
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
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
which ipfs
|
|
||||||
new_hash=$(cat ${{ matrix.app }}-ipfs-hash)
|
|
||||||
new_cid=$(ipfs cid format -v 1 -b base32 $new_hash)
|
|
||||||
|
|
||||||
(
|
|
||||||
cd ipfs-redirect
|
|
||||||
|
|
||||||
# configure git
|
|
||||||
git status
|
|
||||||
cat .git/config
|
|
||||||
git config --global user.email "vega-ci-bot@vega.xyz"
|
|
||||||
git config --global user.name "vega-ci-bot"
|
|
||||||
|
|
||||||
# update CID files
|
|
||||||
if echo ${{ github.ref }} | grep -q main; then
|
|
||||||
echo $new_hash > cidv0-mainnet.txt
|
|
||||||
echo $new_cid > cidv1-mainnet.txt
|
|
||||||
git add cidv0-mainnet.txt cidv1-mainnet.txt
|
|
||||||
elif echo ${{ github.ref }} | grep -q release/testnet; then
|
|
||||||
echo $new_hash > cidv0-fairground.txt
|
|
||||||
echo $new_cid > cidv1-fairground.txt
|
|
||||||
git add cidv0-fairground.txt cidv1-fairground.txt
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create commit
|
|
||||||
commit_msg="Automated hash update from ${{ github.ref }}"
|
|
||||||
git commit -m "$commit_msg"
|
|
||||||
git push -u origin "main"
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
name: 'Rollback console'
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: 'Version that should be set on rollback'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
rollback:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Log in to the Container registry (docker hub)
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Retag mainnet
|
|
||||||
run: |
|
|
||||||
docker pull vegaprotocol/trading:${{ inputs.version }}
|
|
||||||
docker tag vegaprotocol/trading:${{ inputs.version }} vegaprotocol/trading:mainnet
|
|
||||||
docker push vegaprotocol/trading:mainnet
|
|
||||||
docker run --rm vegaprotocol/trading:mainnet cat /ipfs-hash > ipfs-hash
|
|
||||||
|
|
||||||
- name: Trigger fleek deployment
|
|
||||||
run: |
|
|
||||||
# display info about app
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "query{getSiteById(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id latestDeploy{id status}}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
# trigger new deployment as base image is always set to vegaprotocol/trading:mainnet
|
|
||||||
curl -H "Authorization: ${{ secrets.FLEEK_API_KEY }}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"query": "mutation{triggerDeploy(siteId:\"f8f2e051-f18e-49e6-b876-0a39369dc0d8\"){id status}}"}' \
|
|
||||||
https://api.fleek.co/graphql
|
|
||||||
|
|
||||||
- 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
|
|
||||||
export PATH="$PATH:$PWD/kubo"
|
|
||||||
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
|
|
||||||
|
|
||||||
(
|
|
||||||
cd ipfs-redirect
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
+1
-3
@@ -49,6 +49,4 @@ cypress.env.json
|
|||||||
.next
|
.next
|
||||||
|
|
||||||
#cypress
|
#cypress
|
||||||
/apps/**/cypress/reports/
|
/apps/trading-e2e/cypress/reports/
|
||||||
/apps/**/cypress/downloads/
|
|
||||||
/apps/**/fixtures/wallet/node**
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
.PHONY: latest-release
|
.PHONY: latest-release
|
||||||
latest-release:
|
latest-release:
|
||||||
gh release list | head -n 1 | awk '{print $1}'
|
gh release list | head -n 1 | awk '{print $1}'
|
||||||
|
|
||||||
.PHONY: show-latest-release
|
.PHONY: show-latest-release
|
||||||
show-latest-release:
|
show-latest-release:
|
||||||
gh release view `gh release list | head -n 1 | awk '{print $1}'`
|
gh release view `gh release list | head -n 1 | awk '{print $1}'`
|
||||||
|
|
||||||
.PHONY: recalculate-ipfs
|
.PHONY: recalculate-ipfs
|
||||||
recalculate-ipfs:
|
recalculate-ipfs:
|
||||||
echo "ipfs hash inside the image"
|
echo "ipfs hash inside the image"
|
||||||
docker run --rm ${TAG} cat /ipfs-hash
|
docker run --rm ${TAG} cat /ipfs-hash
|
||||||
echo "recalculating ipfs hash"
|
echo "recalculating ipfs hash"
|
||||||
docker run --rm ${TAG} ipfs add -r /usr/share/nginx/html
|
docker run --rm ${TAG} ipfs add -rw /usr/share/nginx/html
|
||||||
|
|
||||||
.PHONY: eject-ipfs-hash
|
.PHONY: eject-ipfs-hash
|
||||||
unpack:
|
unpack:
|
||||||
docker create --name=dist ${TAG}
|
docker create --name=dist ${TAG}
|
||||||
docker cp dist:/usr/share/nginx/html dist
|
docker cp dist:/usr/share/nginx/html dist
|
||||||
docker rm dist
|
docker rm dist
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
|
||||||
NX_TENDERMINT_URL=http://localhost:26617
|
NX_TENDERMINT_URL=http://localhost:26617
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26617/websocket
|
||||||
NX_VEGA_URL=http://localhost:3008/graphql
|
NX_VEGA_URL=http://localhost:3008/graphql
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# 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_URL=https://n04.d.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
|
||||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# 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_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
|
||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
NX_VEGA_URL=https://api.vega.community/graphql
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# App configuration variables
|
# 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_URL=https://tm.n07.testnet.vega.xyz/tm
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
|
||||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
reporter: '../../node_modules/cypress-mochawesome-reporter',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
require('cypress-mochawesome-reporter/plugin')(on);
|
|
||||||
require('@cypress/grep/src/plugin')(config);
|
require('@cypress/grep/src/plugin')(config);
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,6 +15,5 @@
|
|||||||
|
|
||||||
import '@vegaprotocol/cypress';
|
import '@vegaprotocol/cypress';
|
||||||
import './common.functions.js';
|
import './common.functions.js';
|
||||||
import 'cypress-mochawesome-reporter/register';
|
|
||||||
import registerCypressGrep from '@cypress/grep';
|
import registerCypressGrep from '@cypress/grep';
|
||||||
registerCypressGrep();
|
registerCypressGrep();
|
||||||
|
|||||||
+4
-6
@@ -3,19 +3,17 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|||||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
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_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||||
NX_VEGA_ENV=STAGNET1
|
NX_VEGA_ENV=STAGNET1
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||||
NX_VEGA_TOKEN_URL=https://governance.stagnet1.vega.rocks
|
NX_VEGA_TOKEN_URL=https://stagnet1.governance.vega.xyz
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||||
NX_VEGA_GOVERNANCE_URL=https://governance.stagnet1.vega.rocks
|
NX_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
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
|
# App flags
|
||||||
NX_EXPLORER_ASSETS=1
|
NX_EXPLORER_ASSETS=1
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_TENDERMINT_URL=https://be.vega.community
|
NX_TENDERMINT_URL=https://be.vega.community
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||||
NX_SENTRY_DSN=https://b3a56b03eda842faad731f3ea9dfd1bc@o286262.ingest.sentry.io/6242427
|
|
||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
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_ENV=MAINNET
|
||||||
NX_BLOCK_EXPLORER=https://be.vega.community/rest
|
NX_BLOCK_EXPLORER=https://be.vega.community/rest/
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
|
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
|
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
|
# .env is stagnet1, so there are no overrides required
|
||||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET1":"https://stagnet1.explorer.vega.xyz"}'
|
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz","STAGNET3":"https://stagnet3.explorer.vega.xyz"}'
|
||||||
|
|||||||
@@ -10,4 +10,3 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
|||||||
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
|
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
|
||||||
|
|||||||
@@ -7,9 +7,8 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
|||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
|
|
||||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
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_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
||||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
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://validator-testnet.explorer.vega.xyz/
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
|
||||||
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
|
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
"executor": "@nrwl/workspace:run-commands",
|
"executor": "@nrwl/workspace:run-commands",
|
||||||
"options": {
|
"options": {
|
||||||
"commands": [
|
"commands": [
|
||||||
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.71.4/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
|
"npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.67.3/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
|||||||
import { RouterProvider } from 'react-router-dom';
|
import { RouterProvider } from 'react-router-dom';
|
||||||
import { router } from './routes/router-config';
|
import { router } from './routes/router-config';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Suspense } from 'react';
|
|
||||||
|
|
||||||
const splashLoading = (
|
const splashLoading = (
|
||||||
<Splash>
|
<Splash>
|
||||||
@@ -33,9 +32,7 @@ function App() {
|
|||||||
skeleton={<div>{t('Loading')}</div>}
|
skeleton={<div>{t('Loading')}</div>}
|
||||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||||
>
|
>
|
||||||
<Suspense fallback={splashLoading}>
|
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
|
||||||
</Suspense>
|
|
||||||
</NodeGuard>
|
</NodeGuard>
|
||||||
<NodeSwitcherDialog
|
<NodeSwitcherDialog
|
||||||
open={nodeSwitcherOpen}
|
open={nodeSwitcherOpen}
|
||||||
|
|||||||
@@ -1,13 +1,29 @@
|
|||||||
import WS from 'jest-websocket-mock';
|
import WS from 'jest-websocket-mock';
|
||||||
import { render, screen } from '@testing-library/react';
|
import useWebSocket from 'react-use-websocket';
|
||||||
|
import {
|
||||||
|
render,
|
||||||
|
screen,
|
||||||
|
fireEvent,
|
||||||
|
act,
|
||||||
|
waitFor,
|
||||||
|
} from '@testing-library/react';
|
||||||
|
import { TendermintWebsocketContext } from '../../contexts/websocket/tendermint-websocket-context';
|
||||||
import { BlocksRefetch } from './blocks-refetch';
|
import { BlocksRefetch } from './blocks-refetch';
|
||||||
|
|
||||||
const BlocksRefetchInWebsocketProvider = ({
|
const BlocksRefetchInWebsocketProvider = ({
|
||||||
callback,
|
callback,
|
||||||
|
mocketLocation,
|
||||||
}: {
|
}: {
|
||||||
callback: () => null;
|
callback: () => null;
|
||||||
|
mocketLocation: string;
|
||||||
}) => {
|
}) => {
|
||||||
return <BlocksRefetch refetch={callback} />;
|
const contextShape = useWebSocket(mocketLocation);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TendermintWebsocketContext.Provider value={{ ...contextShape }}>
|
||||||
|
<BlocksRefetch refetch={callback} />
|
||||||
|
</TendermintWebsocketContext.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Blocks refetch', () => {
|
describe('Blocks refetch', () => {
|
||||||
@@ -16,8 +32,111 @@ describe('Blocks refetch', () => {
|
|||||||
const mocket = new WS(mocketLocation, { jsonProtocol: true });
|
const mocket = new WS(mocketLocation, { jsonProtocol: true });
|
||||||
new WebSocket(mocketLocation);
|
new WebSocket(mocketLocation);
|
||||||
|
|
||||||
render(<BlocksRefetchInWebsocketProvider callback={() => null} />);
|
render(
|
||||||
|
<BlocksRefetchInWebsocketProvider
|
||||||
|
callback={() => null}
|
||||||
|
mocketLocation={mocketLocation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await mocket.connected;
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('new blocks');
|
||||||
expect(screen.getByTestId('refresh')).toBeInTheDocument();
|
expect(screen.getByTestId('refresh')).toBeInTheDocument();
|
||||||
mocket.close();
|
mocket.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should initiate callback when the button is clicked', async () => {
|
||||||
|
const mocketLocation = 'wss:localhost:3003';
|
||||||
|
const mocket = new WS(mocketLocation, { jsonProtocol: true });
|
||||||
|
new WebSocket(mocketLocation);
|
||||||
|
|
||||||
|
const callback = jest.fn();
|
||||||
|
render(
|
||||||
|
<BlocksRefetchInWebsocketProvider
|
||||||
|
callback={callback}
|
||||||
|
mocketLocation={mocketLocation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await mocket.connected;
|
||||||
|
const button = screen.getByTestId('refresh');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
fireEvent.click(button);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(callback.mock.calls.length).toEqual(1);
|
||||||
|
mocket.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show new blocks as websocket is correctly updated', async () => {
|
||||||
|
const mocketLocation = 'wss:localhost:3004';
|
||||||
|
const mocket = new WS(mocketLocation, { jsonProtocol: true });
|
||||||
|
new WebSocket(mocketLocation);
|
||||||
|
render(
|
||||||
|
<BlocksRefetchInWebsocketProvider
|
||||||
|
callback={() => null}
|
||||||
|
mocketLocation={mocketLocation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await mocket.connected;
|
||||||
|
|
||||||
|
// Ensuring we send an ID equal to the one the client subscribed with.
|
||||||
|
await waitFor(() => expect(mocket.messages.length).toEqual(1));
|
||||||
|
// @ts-ignore id on messages
|
||||||
|
const id = mocket.messages[0].id;
|
||||||
|
|
||||||
|
const newBlockMessage = {
|
||||||
|
id,
|
||||||
|
result: {
|
||||||
|
query: "tm.event = 'NewBlock'",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('0 new blocks');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
mocket.send(newBlockMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('1 new blocks');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
mocket.send(newBlockMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('2 new blocks');
|
||||||
|
mocket.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will not show new blocks if websocket has wrong ID', async () => {
|
||||||
|
const mocketLocation = 'wss:localhost:3005';
|
||||||
|
const mocket = new WS(mocketLocation, { jsonProtocol: true });
|
||||||
|
new WebSocket(mocketLocation);
|
||||||
|
|
||||||
|
render(
|
||||||
|
<BlocksRefetchInWebsocketProvider
|
||||||
|
callback={() => null}
|
||||||
|
mocketLocation={mocketLocation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await mocket.connected;
|
||||||
|
|
||||||
|
// Ensuring we send an ID equal to the one the client subscribed with.
|
||||||
|
await waitFor(() => expect(mocket.messages.length).toEqual(1));
|
||||||
|
|
||||||
|
const newBlockMessageBadId = {
|
||||||
|
id: 'blahblahblah',
|
||||||
|
result: {
|
||||||
|
query: "tm.event = 'NewBlock'",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('0 new blocks');
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
mocket.send(newBlockMessageBadId);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByTestId('new-blocks')).toHaveTextContent('0 new blocks');
|
||||||
|
mocket.close();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,36 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useTendermintWebsocket } from '../../hooks/use-tendermint-websocket';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
interface BlocksRefetchProps {
|
interface BlocksRefetchProps {
|
||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BlocksRefetch = ({ refetch }: BlocksRefetchProps) => {
|
export const BlocksRefetch = ({ refetch }: BlocksRefetchProps) => {
|
||||||
|
const [blocksToLoad, setBlocksToLoad] = useState<number>(0);
|
||||||
|
|
||||||
|
const { messages } = useTendermintWebsocket({
|
||||||
|
query: "tm.event = 'NewBlock'",
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (messages.length > 0) {
|
||||||
|
setBlocksToLoad((prev) => prev + 1);
|
||||||
|
}
|
||||||
|
}, [messages]);
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
refetch();
|
refetch();
|
||||||
|
setBlocksToLoad(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onClick={refresh} data-testid="refresh" size="xs">
|
<div className="mb-4">
|
||||||
<Icon name="refresh" className="!align-baseline mr-2" size={3} />
|
<span data-testid="new-blocks">{blocksToLoad} new blocks - </span>
|
||||||
{t('Load new')}
|
<ButtonLink onClick={refresh} data-testid="refresh">
|
||||||
</Button>
|
{t('refresh to see latest')}
|
||||||
|
</ButtonLink>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ import {
|
|||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||||
import { Link, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { ENV } from '../../config/env';
|
import { ENV } from '../../config/env';
|
||||||
import { Routes } from '../../routes/route-names';
|
|
||||||
import { Link as RouteLink } from 'react-router-dom';
|
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
||||||
@@ -23,7 +21,7 @@ export const Footer = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<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">
|
<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">
|
||||||
<div className="flex justify-between gap-2 align-middle">
|
<div className="flex justify-between gap-2 align-middle">
|
||||||
{GIT_COMMIT_HASH && (
|
{GIT_COMMIT_HASH && (
|
||||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||||
@@ -50,26 +48,23 @@ export const Footer = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{ENV.addresses.feedback ? (
|
<div className="flex pl-2 content-center">
|
||||||
<div className="flex pl-2 content-center">
|
<ExternalLink href={ENV.addresses.feedback}>
|
||||||
<ExternalLink href={ENV.addresses.feedback}>
|
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
||||||
{showFullFeedbackLabel ? t('Share your feedback') : t('Feedback')}
|
</ExternalLink>
|
||||||
</ExternalLink>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const NodeUrl = ({ url }: { url: string }) => {
|
const NodeUrl = ({ url }: { url: string }) => {
|
||||||
// get base url from api url, api sub domain
|
// get base url from api url, api sub domain
|
||||||
const urlObj = new URL(url);
|
const urlObj = new URL(url);
|
||||||
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
||||||
return <span className="cursor-default">{nodeUrl}</span>;
|
return (
|
||||||
|
<Link href={'https://' + nodeUrl} target="_blank">
|
||||||
|
{nodeUrl}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Header } from './header';
|
|||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/environment', () => ({
|
jest.mock('@vegaprotocol/environment', () => ({
|
||||||
...jest.requireActual('@vegaprotocol/environment'),
|
|
||||||
NetworkSwitcher: () => (
|
NetworkSwitcher: () => (
|
||||||
<div data-testid="network-switcher">NetworkSwitcher</div>
|
<div data-testid="network-switcher">NetworkSwitcher</div>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { MarketInfoWithData } from '@vegaprotocol/markets';
|
import type { MarketInfoWithData } from '@vegaprotocol/market-info';
|
||||||
import { PriceMonitoringBoundsInfoPanel } from '@vegaprotocol/markets';
|
import { LiquidityInfoPanel } from '@vegaprotocol/market-info';
|
||||||
|
import { LiquidityMonitoringParametersInfoPanel } from '@vegaprotocol/market-info';
|
||||||
import {
|
import {
|
||||||
LiquidityInfoPanel,
|
|
||||||
LiquidityMonitoringParametersInfoPanel,
|
|
||||||
InstrumentInfoPanel,
|
InstrumentInfoPanel,
|
||||||
KeyDetailsInfoPanel,
|
KeyDetailsInfoPanel,
|
||||||
LiquidityPriceRangeInfoPanel,
|
LiquidityPriceRangeInfoPanel,
|
||||||
@@ -13,18 +12,20 @@ import {
|
|||||||
RiskModelInfoPanel,
|
RiskModelInfoPanel,
|
||||||
RiskParametersInfoPanel,
|
RiskParametersInfoPanel,
|
||||||
SettlementAssetInfoPanel,
|
SettlementAssetInfoPanel,
|
||||||
} from '@vegaprotocol/markets';
|
} from '@vegaprotocol/market-info';
|
||||||
import { MarketInfoTable } from '@vegaprotocol/markets';
|
import { MarketInfoTable } from '@vegaprotocol/market-info';
|
||||||
import type { DataSourceDefinition } from '@vegaprotocol/types';
|
import type { DataSourceDefinition } from '@vegaprotocol/types';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
|
||||||
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
||||||
if (!market) return null;
|
if (!market) return null;
|
||||||
|
|
||||||
const settlementData = market.tradableInstrument.instrument.product
|
const settlementData =
|
||||||
.dataSourceSpecForSettlementData.data as DataSourceDefinition;
|
market.tradableInstrument.instrument.product.dataSourceSpecForSettlementData
|
||||||
const terminationData = market.tradableInstrument.instrument.product
|
.data;
|
||||||
.dataSourceSpecForTradingTermination.data as DataSourceDefinition;
|
const terminationData =
|
||||||
|
market.tradableInstrument.instrument.product
|
||||||
|
.dataSourceSpecForTradingTermination.data;
|
||||||
|
|
||||||
const getSigners = (data: DataSourceDefinition) => {
|
const getSigners = (data: DataSourceDefinition) => {
|
||||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
||||||
@@ -40,69 +41,133 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
|
|||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const showTwoOracles = isEqual(
|
const oraclePanels = isEqual(
|
||||||
getSigners(settlementData),
|
getSigners(settlementData),
|
||||||
getSigners(terminationData)
|
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 headerClassName = 'font-alpha calt text-xl mt-4 border-b-2 pb-2';
|
const panels = [
|
||||||
|
{
|
||||||
return (
|
title: t('Key details'),
|
||||||
<div>
|
content: <KeyDetailsInfoPanel noBorder={false} market={market} />,
|
||||||
<h2 className={headerClassName}>{t('Key details')}</h2>
|
},
|
||||||
<KeyDetailsInfoPanel market={market} />
|
{
|
||||||
<h2 className={headerClassName}>{t('Instrument')}</h2>
|
title: t('Instrument'),
|
||||||
<InstrumentInfoPanel market={market} />
|
content: <InstrumentInfoPanel noBorder={false} market={market} />,
|
||||||
<h2 className={headerClassName}>{t('Settlement asset')}</h2>
|
},
|
||||||
<SettlementAssetInfoPanel market={market} />
|
{
|
||||||
<h2 className={headerClassName}>{t('Metadata')}</h2>
|
title: t('Settlement asset'),
|
||||||
<MetadataInfoPanel market={market} />
|
content: <SettlementAssetInfoPanel market={market} noBorder={false} />,
|
||||||
<h2 className={headerClassName}>{t('Risk model')}</h2>
|
},
|
||||||
<RiskModelInfoPanel market={market} />
|
{
|
||||||
<h2 className={headerClassName}>{t('Risk parameters')}</h2>
|
title: t('Metadata'),
|
||||||
<RiskParametersInfoPanel market={market} />
|
content: <MetadataInfoPanel noBorder={false} market={market} />,
|
||||||
<h2 className={headerClassName}>{t('Risk factors')}</h2>
|
},
|
||||||
<RiskFactorsInfoPanel market={market} />
|
{
|
||||||
{(market.data?.priceMonitoringBounds || []).map((trigger, i) => (
|
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: (
|
||||||
<>
|
<>
|
||||||
<h2 className={headerClassName}>
|
<MarketInfoTable
|
||||||
{t('Price monitoring bounds %s', [(i + 1).toString()])}
|
noBorder={false}
|
||||||
</h2>
|
data={{
|
||||||
<PriceMonitoringBoundsInfoPanel
|
maxValidPrice: trigger.maxValidPrice,
|
||||||
market={market}
|
minValidPrice: trigger.minValidPrice,
|
||||||
triggerIndex={i + 1}
|
}}
|
||||||
|
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,
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{panels.map((p) => (
|
||||||
|
<div key={p.title} className="mb-3">
|
||||||
|
<h2 className="font-alpha calt text-xl">{p.title}</h2>
|
||||||
|
{p.content}
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
{(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>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { MarketFieldsFragment } from '@vegaprotocol/markets';
|
import type { MarketFieldsFragment } from '@vegaprotocol/market-list';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
@@ -77,24 +77,22 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
|||||||
hide={window.innerWidth <= BREAKPOINT_MD}
|
hide={window.innerWidth <= BREAKPOINT_MD}
|
||||||
valueGetter={({
|
valueGetter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueGetterParams<MarketFieldsFragment>) => {
|
}: VegaValueGetterParams<MarketFieldsFragment, 'state'>) => {
|
||||||
return data?.state ? MarketStateMapping[data?.state] : '-';
|
return data?.state ? MarketStateMapping[data?.state] : '-';
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
colId="asset"
|
colId="asset"
|
||||||
headerName={t('Settlement asset')}
|
headerName={t('Settlement asset')}
|
||||||
field="tradableInstrument.instrument.product.settlementAsset.symbol"
|
field="tradableInstrument.instrument.product.settlementAsset"
|
||||||
hide={window.innerWidth <= BREAKPOINT_MD}
|
hide={window.innerWidth <= BREAKPOINT_MD}
|
||||||
cellRenderer={({
|
cellRenderer={({
|
||||||
data,
|
value,
|
||||||
}: VegaICellRendererParams<
|
}: VegaICellRendererParams<
|
||||||
MarketFieldsFragment,
|
MarketFieldsFragment,
|
||||||
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
'tradableInstrument.instrument.product.settlementAsset'
|
||||||
>) => {
|
>) =>
|
||||||
const value =
|
value ? (
|
||||||
data?.tradableInstrument.instrument.product.settlementAsset;
|
|
||||||
return value ? (
|
|
||||||
<ButtonLink
|
<ButtonLink
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
||||||
@@ -104,8 +102,8 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
|||||||
</ButtonLink>
|
</ButtonLink>
|
||||||
) : (
|
) : (
|
||||||
''
|
''
|
||||||
);
|
)
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
flex={2}
|
flex={2}
|
||||||
|
|||||||
+4
-12
@@ -1,17 +1,14 @@
|
|||||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
// https://github.com/vegaprotocol/vega/blob/develop/core/blockchain/response.go
|
// https://github.com/vegaprotocol/vega/blob/develop/core/blockchain/response.go
|
||||||
export const ErrorCodes = new Map([
|
export const ErrorCodes = new Map([
|
||||||
[51, 'Transaction failed validation'],
|
[51, 'Transaction failed validation'],
|
||||||
[60, 'Transaction could not be decoded'],
|
[60, 'Transaction could not be decoded'],
|
||||||
[70, 'Error'],
|
[70, 'Error'],
|
||||||
[71, 'Partial success/error'],
|
|
||||||
[80, 'Unknown command'],
|
[80, 'Unknown command'],
|
||||||
[89, 'Rejected as spam'],
|
[89, 'Rejected as spam'],
|
||||||
[0, 'Success'],
|
[0, 'Success'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const successCodes = new Set([0, 71]);
|
export const successCodes = new Set([0]);
|
||||||
|
|
||||||
interface ChainResponseCodeProps {
|
interface ChainResponseCodeProps {
|
||||||
code: number;
|
code: number;
|
||||||
@@ -30,13 +27,8 @@ export const ChainResponseCode = ({
|
|||||||
error,
|
error,
|
||||||
}: ChainResponseCodeProps) => {
|
}: ChainResponseCodeProps) => {
|
||||||
const isSuccess = successCodes.has(code);
|
const isSuccess = successCodes.has(code);
|
||||||
const successColour =
|
|
||||||
code === 71 ? 'fill-vega-orange' : 'fill-vega-green-600';
|
const icon = isSuccess ? '✅' : '❌';
|
||||||
const icon = isSuccess ? (
|
|
||||||
<Icon name="tick-circle" className={successColour} />
|
|
||||||
) : (
|
|
||||||
<Icon name="cross" className="fill-vega-pink-600" />
|
|
||||||
);
|
|
||||||
const label = ErrorCodes.get(code) || 'Unknown response code';
|
const label = ErrorCodes.get(code) || 'Unknown response code';
|
||||||
|
|
||||||
// Hack for batches with many errors - see https://github.com/vegaprotocol/vega/issues/7245
|
// Hack for batches with many errors - see https://github.com/vegaprotocol/vega/issues/7245
|
||||||
@@ -44,7 +36,7 @@ export const ChainResponseCode = ({
|
|||||||
error && error.length > 100 ? error.replace(/,/g, ',\r\n') : error;
|
error && error.length > 100 ? error.replace(/,/g, ',\r\n') : error;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div title={`Response code: ${code} - ${label}`} className=" inline-block">
|
<div title={`Response code: ${code} - ${label}`} className="inline-block">
|
||||||
<span
|
<span
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
aria-label={isSuccess ? 'Success' : 'Warning'}
|
aria-label={isSuccess ? 'Success' : 'Warning'}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint
|
|||||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
import ProposalLink from '../../links/proposal-link/proposal-link';
|
import ProposalLink from '../../links/proposal-link/proposal-link';
|
||||||
import { VoteIcon } from '../../vote-icon/vote-icon';
|
|
||||||
|
|
||||||
interface TxProposalVoteProps {
|
interface TxProposalVoteProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -31,22 +30,27 @@ export const TxProposalVote = ({
|
|||||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vote = txData.command.voteSubmission.value === 'VALUE_YES';
|
const vote = txData.command.voteSubmission.value ? '👍' : '👎';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableWithTbody className="mb-8" allowWrap={true}>
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Proposal ID')}</TableCell>
|
||||||
|
<TableCell>{txData.command.voteSubmission.proposalId}</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell>{t('Proposal details')}</TableCell>
|
<TableCell>{t('Proposal details')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<ProposalLink id={txData.command.voteSubmission.proposalId} />
|
<ProposalLink id={txData.command.voteSubmission.proposalId} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Proposal')}</TableCell>
|
||||||
|
<TableCell>{txData.command.voteSubmission.proposalId}</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell>{t('Vote')}</TableCell>
|
<TableCell>{t('Vote')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>{vote}</TableCell>
|
||||||
<VoteIcon vote={vote} />
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableWithTbody>
|
</TableWithTbody>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import type { Proposal } from './tx-proposal';
|
|
||||||
import { proposalRequiresSignatureBundle } from './tx-proposal';
|
|
||||||
|
|
||||||
describe('proposalRequiresSignatureBundle', () => {
|
|
||||||
it('should return false for freeform proposals, which do not require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newFreeform: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false for newMarket proposals, which do not require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newMarket: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for newAsset proposals, which do require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
newAsset: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true for updateAsset proposals, which do require a signature bundle to enact', () => {
|
|
||||||
const mock = {
|
|
||||||
terms: {
|
|
||||||
updateAsset: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(proposalRequiresSignatureBundle(mock)).toEqual(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false when bad data is supplied', () => {
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle(false as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle(undefined as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
expect(
|
|
||||||
proposalRequiresSignatureBundle({ test: false } as unknown as Proposal)
|
|
||||||
).toEqual(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -28,16 +28,11 @@ interface TxProposalProps {
|
|||||||
* @returns boolean True if a signature bundle is required. Used to fetch a signature bundle
|
* @returns boolean True if a signature bundle is required. Used to fetch a signature bundle
|
||||||
*/
|
*/
|
||||||
export function proposalRequiresSignatureBundle(proposal?: Proposal): boolean {
|
export function proposalRequiresSignatureBundle(proposal?: Proposal): boolean {
|
||||||
const proposalsThatRequireBundles = ['newAsset', 'updateAsset'];
|
|
||||||
|
|
||||||
if (!proposal?.terms) {
|
if (!proposal?.terms) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return !!['newAsset', 'updateAsset'].filter((requiredIfExists) =>
|
||||||
return (
|
has(proposal.terms, requiredIfExists)
|
||||||
proposalsThatRequireBundles.filter((requiredIfExists) =>
|
|
||||||
has(proposal.terms, requiredIfExists)
|
|
||||||
).length > 0
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +81,6 @@ export const TxProposal = ({ txData, pubKey, blockData }: TxProposalProps) => {
|
|||||||
|
|
||||||
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
|
const tx = proposal.terms?.newAsset || proposal.terms?.updateAsset;
|
||||||
|
|
||||||
// This component is not rendered if no bundle is required
|
|
||||||
const SignatureBundleComponent = proposal.terms?.newAsset
|
const SignatureBundleComponent = proposal.terms?.newAsset
|
||||||
? ProposalSignatureBundleNewAsset
|
? ProposalSignatureBundleNewAsset
|
||||||
: ProposalSignatureBundleUpdateAsset;
|
: ProposalSignatureBundleUpdateAsset;
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
|
|
||||||
export interface FilterLabelProps {
|
|
||||||
filters: Set<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the list (currently limited to 1) of filters set by the
|
|
||||||
* Transaction Filter
|
|
||||||
*/
|
|
||||||
export function FilterLabel({ filters }: FilterLabelProps) {
|
|
||||||
if (!filters || filters.size !== 1) {
|
|
||||||
return <span className="uppercase">{t('Filter')}</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<span className="uppercase">{t('Filters')}:</span>
|
|
||||||
<code className="bg-vega-light-150 px-2 rounded-md capitalize">
|
|
||||||
{Array.from(filters)[0]}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import {
|
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItemIndicator,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
DropdownMenuSub,
|
|
||||||
DropdownMenuSubTrigger,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
DropdownMenuSubContent,
|
|
||||||
Icon,
|
|
||||||
Button,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import type { Dispatch, SetStateAction } from 'react';
|
|
||||||
import { FilterLabel } from './tx-filter-label';
|
|
||||||
|
|
||||||
// All possible transaction types. Should be generated.
|
|
||||||
export type FilterOption =
|
|
||||||
| 'Amend LiquidityProvision Order'
|
|
||||||
| 'Amend Order'
|
|
||||||
| 'Batch Market Instructions'
|
|
||||||
| 'Cancel LiquidityProvision Order'
|
|
||||||
| 'Cancel Order'
|
|
||||||
| 'Cancel Transfer Funds'
|
|
||||||
| 'Chain Event'
|
|
||||||
| 'Delegate'
|
|
||||||
| 'Ethereum Key Rotate Submission'
|
|
||||||
| 'Issue Signatures'
|
|
||||||
| 'Key Rotate Submission'
|
|
||||||
| 'Liquidity Provision Order'
|
|
||||||
| 'Node Signature'
|
|
||||||
| 'Node Vote'
|
|
||||||
| 'Proposal'
|
|
||||||
| 'Protocol Upgrade'
|
|
||||||
| 'Register new Node'
|
|
||||||
| 'State Variable Proposal'
|
|
||||||
| 'Submit Oracle Data'
|
|
||||||
| 'Submit Order'
|
|
||||||
| 'Transfer Funds'
|
|
||||||
| 'Undelegate'
|
|
||||||
| 'Validator Heartbeat'
|
|
||||||
| 'Vote on Proposal'
|
|
||||||
| 'Withdraw';
|
|
||||||
|
|
||||||
// Alphabetised list of transaction types to appear at the top level
|
|
||||||
export const PrimaryFilterOptions: FilterOption[] = [
|
|
||||||
'Amend LiquidityProvision Order',
|
|
||||||
'Amend Order',
|
|
||||||
'Batch Market Instructions',
|
|
||||||
'Cancel LiquidityProvision Order',
|
|
||||||
'Cancel Order',
|
|
||||||
'Cancel Transfer Funds',
|
|
||||||
'Delegate',
|
|
||||||
'Liquidity Provision Order',
|
|
||||||
'Proposal',
|
|
||||||
'Submit Oracle Data',
|
|
||||||
'Submit Order',
|
|
||||||
'Transfer Funds',
|
|
||||||
'Undelegate',
|
|
||||||
'Vote on Proposal',
|
|
||||||
'Withdraw',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Alphabetised list of transaction types to nest under a 'More...' submenu
|
|
||||||
export const SecondaryFilterOptions: FilterOption[] = [
|
|
||||||
'Chain Event',
|
|
||||||
'Ethereum Key Rotate Submission',
|
|
||||||
'Issue Signatures',
|
|
||||||
'Key Rotate Submission',
|
|
||||||
'Node Signature',
|
|
||||||
'Node Vote',
|
|
||||||
'Protocol Upgrade',
|
|
||||||
'Register new Node',
|
|
||||||
'State Variable Proposal',
|
|
||||||
'Validator Heartbeat',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const AllFilterOptions: FilterOption[] = [
|
|
||||||
...PrimaryFilterOptions,
|
|
||||||
...SecondaryFilterOptions,
|
|
||||||
];
|
|
||||||
|
|
||||||
export interface TxFilterProps {
|
|
||||||
filters: Set<FilterOption>;
|
|
||||||
setFilters: Dispatch<SetStateAction<Set<FilterOption>>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders a structured dropdown menu of all of the available transaction
|
|
||||||
* types. It allows a user to select one transaction type to view. Later
|
|
||||||
* it will support multiple selection, but until the API supports that it is
|
|
||||||
* one or all.
|
|
||||||
* @param filters null or Set of tranaction types
|
|
||||||
* @param setFilters A function to update the filters prop
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export const TxsFilter = ({ filters, setFilters }: TxFilterProps) => {
|
|
||||||
return (
|
|
||||||
<DropdownMenu
|
|
||||||
modal={false}
|
|
||||||
trigger={
|
|
||||||
<DropdownMenuTrigger className="ml-2">
|
|
||||||
<Button size="xs">
|
|
||||||
<FilterLabel filters={filters} />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DropdownMenuContent>
|
|
||||||
{filters.size > 1 ? null : (
|
|
||||||
<>
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
onCheckedChange={() => setFilters(new Set(AllFilterOptions))}
|
|
||||||
>
|
|
||||||
{t('Clear filters')} <Icon name="cross" />
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{PrimaryFilterOptions.map((f) => (
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
key={f}
|
|
||||||
checked={filters.has(f)}
|
|
||||||
onCheckedChange={() => {
|
|
||||||
// NOTE: These act like radio buttons until the API supports multiple filters
|
|
||||||
setFilters(new Set([f]));
|
|
||||||
}}
|
|
||||||
id={`radio-${f}`}
|
|
||||||
>
|
|
||||||
{f}
|
|
||||||
<DropdownMenuItemIndicator>
|
|
||||||
<Icon name="tick-circle" />
|
|
||||||
</DropdownMenuItemIndicator>
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
))}
|
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger>
|
|
||||||
{t('More Types')}
|
|
||||||
<Icon name="chevron-right" />
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuSubContent>
|
|
||||||
{SecondaryFilterOptions.map((f) => (
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
key={f}
|
|
||||||
checked={filters.has(f)}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
// NOTE: These act like radio buttons until the API supports multiple filters
|
|
||||||
setFilters(new Set([f]));
|
|
||||||
}}
|
|
||||||
id={`radio-${f}`}
|
|
||||||
>
|
|
||||||
{f}
|
|
||||||
<DropdownMenuItemIndicator>
|
|
||||||
<Icon name="tick-circle" className="inline" />
|
|
||||||
</DropdownMenuItemIndicator>
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
))}
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { components } from '../../../types/explorer';
|
import type { components } from '../../../types/explorer';
|
||||||
import { VoteIcon } from '../vote-icon/vote-icon';
|
|
||||||
|
|
||||||
interface TxOrderTypeProps {
|
interface TxOrderTypeProps {
|
||||||
orderType: string;
|
orderType: string;
|
||||||
@@ -138,15 +137,12 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
|||||||
let type = displayString[orderType] || orderType;
|
let type = displayString[orderType] || orderType;
|
||||||
|
|
||||||
let colours =
|
let colours =
|
||||||
'text-white dark:text-white bg-vega-dark-150 dark:bg-vega-dark-250';
|
'text-white dark:text-white bg-vega-dark-150 dark:bg-vega-dark-150';
|
||||||
|
|
||||||
// This will get unwieldy and should probably produce a different colour of tag
|
// This will get unwieldy and should probably produce a different colour of tag
|
||||||
if (type === 'Chain Event' && !!command?.chainEvent) {
|
if (type === 'Chain Event' && !!command?.chainEvent) {
|
||||||
type = getLabelForChainEvent(command.chainEvent);
|
type = getLabelForChainEvent(command.chainEvent);
|
||||||
colours = 'text-white dark-text-white bg-vega-pink dark:bg-vega-pink';
|
colours = 'text-white dark-text-white bg-vega-pink dark:bg-vega-pink';
|
||||||
} else if (type === 'Validator Heartbeat') {
|
|
||||||
colours =
|
|
||||||
'text-white dark-text-white bg-vega-light-200 dark:bg-vega-dark-100';
|
|
||||||
} else if (type === 'Proposal' || type === 'Governance Proposal') {
|
} else if (type === 'Proposal' || type === 'Governance Proposal') {
|
||||||
if (command && !!command.proposalSubmission) {
|
if (command && !!command.proposalSubmission) {
|
||||||
type = getLabelForProposal(command.proposalSubmission);
|
type = getLabelForProposal(command.proposalSubmission);
|
||||||
@@ -154,17 +150,6 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
|
|||||||
colours = 'text-black bg-vega-yellow';
|
colours = 'text-black bg-vega-yellow';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'Vote on Proposal') {
|
|
||||||
return (
|
|
||||||
<VoteIcon
|
|
||||||
vote={command?.voteSubmission?.value === 'VALUE_YES'}
|
|
||||||
yesText="Proposal vote"
|
|
||||||
noText="Proposal vote"
|
|
||||||
useVoteColour={false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'Vote on Proposal' || type === 'Vote Submission') {
|
if (type === 'Vote on Proposal' || type === 'Vote Submission') {
|
||||||
colours = 'text-black bg-vega-yellow';
|
colours = 'text-black bg-vega-yellow';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,6 @@ describe('Txs infinite list item', () => {
|
|||||||
expect(screen.getByTestId('pub-key')).toHaveTextContent('testPubKey');
|
expect(screen.getByTestId('pub-key')).toHaveTextContent('testPubKey');
|
||||||
expect(screen.getByTestId('tx-type')).toHaveTextContent('testType');
|
expect(screen.getByTestId('tx-type')).toHaveTextContent('testType');
|
||||||
expect(screen.getByTestId('tx-block')).toHaveTextContent('1');
|
expect(screen.getByTestId('tx-block')).toHaveTextContent('1');
|
||||||
expect(screen.getByTestId('tx-success')).toHaveTextContent('Success');
|
expect(screen.getByTestId('tx-success')).toHaveTextContent('Success: ✅');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export const TxsInfiniteListItem = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-testid="transaction-row"
|
data-testid="transaction-row"
|
||||||
className="flex items-center h-full border-t border-neutral-600 dark:border-neutral-800 txs-infinite-list-item grid grid-cols-10"
|
className="flex items-center h-full border-t border-neutral-600 dark:border-neutral-800 txs-infinite-list-item grid grid-cols-10 py-2"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="text-sm col-span-10 md:col-span-3 leading-none"
|
className="text-sm col-span-10 md:col-span-3 leading-none"
|
||||||
@@ -83,7 +83,7 @@ export const TxsInfiniteListItem = ({
|
|||||||
data-testid="tx-success"
|
data-testid="tx-success"
|
||||||
>
|
>
|
||||||
<span className="md:hidden uppercase text-vega-dark-300">
|
<span className="md:hidden uppercase text-vega-dark-300">
|
||||||
Success
|
Success:
|
||||||
</span>
|
</span>
|
||||||
{isNumber(code) ? (
|
{isNumber(code) ? (
|
||||||
<ChainResponseCode code={code} hideLabel={true} />
|
<ChainResponseCode code={code} hideLabel={true} />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef } from 'react';
|
import React from 'react';
|
||||||
import { FixedSizeList as List } from 'react-window';
|
import { FixedSizeList as List } from 'react-window';
|
||||||
import InfiniteLoader from 'react-window-infinite-loader';
|
import InfiniteLoader from 'react-window-infinite-loader';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
@@ -69,17 +69,6 @@ export const TxsInfiniteList = ({
|
|||||||
}: TxsInfiniteListProps) => {
|
}: TxsInfiniteListProps) => {
|
||||||
const { screenSize } = useScreenDimensions();
|
const { screenSize } = useScreenDimensions();
|
||||||
const isStacked = ['xs', 'sm'].includes(screenSize);
|
const isStacked = ['xs', 'sm'].includes(screenSize);
|
||||||
const infiniteLoaderRef = useRef<InfiniteLoader>(null);
|
|
||||||
const hasMountedRef = useRef(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (hasMountedRef.current) {
|
|
||||||
if (infiniteLoaderRef.current) {
|
|
||||||
infiniteLoaderRef.current.resetloadMoreItemsCache(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hasMountedRef.current = true;
|
|
||||||
}, [loadMoreTxs]);
|
|
||||||
|
|
||||||
if (!txs) {
|
if (!txs) {
|
||||||
if (!areTxsLoading) {
|
if (!areTxsLoading) {
|
||||||
@@ -121,7 +110,6 @@ export const TxsInfiniteList = ({
|
|||||||
isItemLoaded={isItemLoaded}
|
isItemLoaded={isItemLoaded}
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
loadMoreItems={loadMoreItems}
|
loadMoreItems={loadMoreItems}
|
||||||
ref={infiniteLoaderRef}
|
|
||||||
>
|
>
|
||||||
{({ onItemsRendered, ref }) => (
|
{({ onItemsRendered, ref }) => (
|
||||||
<List
|
<List
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
import { VoteIcon } from './vote-icon';
|
|
||||||
|
|
||||||
describe('Vote TX icon', () => {
|
|
||||||
it('should use the text For by default for yes votes', () => {
|
|
||||||
const yes = render(<VoteIcon vote={true} />);
|
|
||||||
expect(yes.getByTestId('label')).toHaveTextContent('For');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the yesText for yes votes if specified', () => {
|
|
||||||
const yes = render(<VoteIcon vote={true} yesText="Test" />);
|
|
||||||
expect(yes.getByTestId('label')).toHaveTextContent('Test');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the tick icon for yes votes', () => {
|
|
||||||
const no = render(<VoteIcon vote={true} />);
|
|
||||||
expect(no.getByRole('img')).toHaveAttribute(
|
|
||||||
'aria-label',
|
|
||||||
'tick-circle icon'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the text Against by default for no votes', () => {
|
|
||||||
const no = render(<VoteIcon vote={false} />);
|
|
||||||
expect(no.getByTestId('label')).toHaveTextContent('Against');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the noText for no votes if specified', () => {
|
|
||||||
const no = render(<VoteIcon vote={false} noText="Test" />);
|
|
||||||
expect(no.getByTestId('label')).toHaveTextContent('Test');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should display the delete icon for no votes', () => {
|
|
||||||
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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { Icon } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import type { IconName } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
export interface VoteIconProps {
|
|
||||||
// True is a yes vote, false is undefined or no vorte
|
|
||||||
vote: boolean;
|
|
||||||
// Defaults to 'For', but can be any text
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a lozenge with an icon representing the way a user voted for a proposal.
|
|
||||||
* The yes and no text can be overridden
|
|
||||||
*
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function VoteIcon({
|
|
||||||
vote,
|
|
||||||
useVoteColour = true,
|
|
||||||
yesText = 'For',
|
|
||||||
noText = 'Against',
|
|
||||||
}: VoteIconProps) {
|
|
||||||
const label = vote ? yesText : noText;
|
|
||||||
const icon: IconName = vote ? 'tick-circle' : 'delete';
|
|
||||||
const bg = getBgColour(useVoteColour, vote);
|
|
||||||
const fill = getFillColour(useVoteColour, vote);
|
|
||||||
const text = getTextColour(useVoteColour, vote);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={`voteicon inline-block my-1 py-1 px-2 py rounded-md text-white leading-one sm align-top ${bg}`}
|
|
||||||
>
|
|
||||||
<Icon name={icon} size={3} className={`mr-2 p-0 fill-${fill}`} />
|
|
||||||
<span className={`text-base text-${text}`} data-testid="label">
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -33,7 +33,7 @@ export const getTxsDataUrl = ({ limit, filters }: IGetTxsDataUrl) => {
|
|||||||
// Hacky fix for param as array
|
// Hacky fix for param as array
|
||||||
let urlAsString = url.toString();
|
let urlAsString = url.toString();
|
||||||
if (filters) {
|
if (filters) {
|
||||||
urlAsString += '&' + filters.replace(' ', '%20');
|
urlAsString += '&' + filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
return urlAsString;
|
return urlAsString;
|
||||||
@@ -65,14 +65,6 @@ export const useTxsData = ({ limit, filters }: IUseTxsData) => {
|
|||||||
}
|
}
|
||||||
}, [setTxsState, data]);
|
}, [setTxsState, data]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTxsState((prev) => ({
|
|
||||||
txsData: [],
|
|
||||||
hasMoreTxs: true,
|
|
||||||
lastCursor: '',
|
|
||||||
}));
|
|
||||||
}, [filters]);
|
|
||||||
|
|
||||||
const loadTxs = useCallback(() => {
|
const loadTxs = useCallback(() => {
|
||||||
return refetch({
|
return refetch({
|
||||||
limit: limit,
|
limit: limit,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
|||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
import compact from 'lodash/compact';
|
import compact from 'lodash/compact';
|
||||||
import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
||||||
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
|
import { marketInfoWithDataProvider } from '@vegaprotocol/market-info';
|
||||||
import { PageTitle } from '../../components/page-helpers/page-title';
|
import { PageTitle } from '../../components/page-helpers/page-title';
|
||||||
|
|
||||||
export const MarketPage = () => {
|
export const MarketPage = () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
import { useScrollToLocation } from '../../hooks/scroll-to-location';
|
||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
import { marketsProvider } from '@vegaprotocol/markets';
|
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { OracleDetailsType, isInternalSourceType } from './oracle-details-type';
|
import { OracleDetailsType } from './oracle-details-type';
|
||||||
import type { SourceType } from './oracle';
|
import type { SourceTypeName } from './oracle-details-type';
|
||||||
import { PropertyKeyType } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
function renderComponent(type: SourceType) {
|
function renderComponent(type: SourceTypeName) {
|
||||||
return <OracleDetailsType sourceType={type} />;
|
return <OracleDetailsType type={type} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderWrappedComponent(type: SourceType) {
|
function renderWrappedComponent(type: SourceTypeName) {
|
||||||
return (
|
return (
|
||||||
<table>
|
<table>
|
||||||
<tbody>{renderComponent(type)}</tbody>
|
<tbody>{renderComponent(type)}</tbody>
|
||||||
@@ -15,53 +14,19 @@ function renderWrappedComponent(type: SourceType) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mock(name: string): SourceType {
|
|
||||||
return {
|
|
||||||
sourceType: {
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
__typename: 'Filter',
|
|
||||||
key: {
|
|
||||||
name,
|
|
||||||
type: PropertyKeyType.TYPE_STRING,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Oracle type view', () => {
|
describe('Oracle type view', () => {
|
||||||
it('Renders nothing when type is null', () => {
|
it('Renders nothing when type is null', () => {
|
||||||
const res = render(renderComponent(null as unknown as SourceType));
|
const res = render(renderComponent(null as unknown as SourceTypeName));
|
||||||
expect(res.container).toBeEmptyDOMElement();
|
expect(res.container).toBeEmptyDOMElement();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Renders Internal time for internal sources - timestamp', () => {
|
it('Renders Internal time for internal sources', () => {
|
||||||
const s = mock('vegaprotocol.builtin.timestamp');
|
const res = render(renderWrappedComponent('DataSourceDefinitionInternal'));
|
||||||
expect(isInternalSourceType(s)).toEqual(true);
|
expect(res.getByText('Internal time')).toBeInTheDocument();
|
||||||
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', () => {
|
it('Renders External data otherwise', () => {
|
||||||
const s = mock('prices.external.vegaprotocol.builtin.');
|
const res = render(renderWrappedComponent('DataSourceDefinitionExternal'));
|
||||||
expect(isInternalSourceType(s)).toEqual(false);
|
|
||||||
const res = render(renderWrappedComponent(s));
|
|
||||||
expect(res.getByText('External data')).toBeInTheDocument();
|
expect(res.getByText('External data')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,51 +1,27 @@
|
|||||||
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
||||||
import type { SourceType } from './oracle';
|
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 {
|
interface OracleDetailsTypeProps {
|
||||||
sourceType: SourceType;
|
type: SourceTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a a single table row for the Oracle Details view that shows
|
* 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
|
* if the oracle is using the internal time oracle or external data
|
||||||
*/
|
*/
|
||||||
export function OracleDetailsType({ sourceType }: OracleDetailsTypeProps) {
|
export function OracleDetailsType({ type }: OracleDetailsTypeProps) {
|
||||||
if (!sourceType) {
|
if (!type) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isInternal = isInternalSourceType(sourceType);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableHeader scope="row">Type</TableHeader>
|
<TableHeader scope="row">Type</TableHeader>
|
||||||
<TableCell modifier="bordered">
|
<TableCell modifier="bordered">
|
||||||
{isInternal ? 'Internal data' : 'External data'}
|
{type === 'DataSourceDefinitionInternal'
|
||||||
|
? 'Internal time'
|
||||||
|
: 'External data'}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const OracleDetails = ({
|
|||||||
<OracleLink id={id} />
|
<OracleLink id={id} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<OracleDetailsType sourceType={sourceType} />
|
<OracleDetailsType type={sourceType.__typename} />
|
||||||
<OracleSigners sourceType={sourceType} />
|
<OracleSigners sourceType={sourceType} />
|
||||||
<OracleMarkets id={id} />
|
<OracleMarkets id={id} />
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
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,5 +10,4 @@ export const Routes = {
|
|||||||
MARKETS: 'markets',
|
MARKETS: 'markets',
|
||||||
ORACLES: 'oracles',
|
ORACLES: 'oracles',
|
||||||
NETWORK_PARAMETERS: 'network-parameters',
|
NETWORK_PARAMETERS: 'network-parameters',
|
||||||
DISCLAIMER: 'disclaimer',
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import { AssetLink, MarketLink } from '../components/links';
|
|||||||
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||||
import { remove0x } from '@vegaprotocol/utils';
|
import { remove0x } from '@vegaprotocol/utils';
|
||||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
import { PartyAccountsByAsset } from './parties/id/accounts';
|
||||||
import { Disclaimer } from './pages/disclaimer';
|
|
||||||
|
|
||||||
export type Navigable = {
|
export type Navigable = {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -336,17 +335,6 @@ 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,
|
...partiesRoutes,
|
||||||
...assetsRoutes,
|
...assetsRoutes,
|
||||||
...genesisRoutes,
|
...genesisRoutes,
|
||||||
|
|||||||
@@ -5,43 +5,17 @@ import { TxsInfiniteList } from '../../../components/txs';
|
|||||||
import { useTxsData } from '../../../hooks/use-txs-data';
|
import { useTxsData } from '../../../hooks/use-txs-data';
|
||||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||||
|
|
||||||
import { useState } from 'react';
|
const BE_TXS_PER_REQUEST = 20;
|
||||||
import { AllFilterOptions, TxsFilter } from '../../../components/txs/tx-filter';
|
|
||||||
|
|
||||||
const BE_TXS_PER_REQUEST = 15;
|
|
||||||
|
|
||||||
export const TxsList = () => {
|
export const TxsList = () => {
|
||||||
useDocumentTitle(['Transactions']);
|
useDocumentTitle(['Transactions']);
|
||||||
|
|
||||||
return (
|
|
||||||
<section className="md:p-2 lg:p-4 xl:p-6 relative">
|
|
||||||
<RouteTitle>{t('Transactions')}</RouteTitle>
|
|
||||||
<TxsListFiltered />
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TxsListFiltered = () => {
|
|
||||||
const [filters, setFilters] = useState(new Set(AllFilterOptions));
|
|
||||||
|
|
||||||
const f =
|
|
||||||
filters && filters.size === 1
|
|
||||||
? `filters[cmd.type]=${Array.from(filters)[0]}`
|
|
||||||
: '';
|
|
||||||
|
|
||||||
const { hasMoreTxs, loadTxs, error, txsData, refreshTxs, loading } =
|
const { hasMoreTxs, loadTxs, error, txsData, refreshTxs, loading } =
|
||||||
useTxsData({
|
useTxsData({ limit: BE_TXS_PER_REQUEST });
|
||||||
limit: BE_TXS_PER_REQUEST,
|
|
||||||
filters: f,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<section className="md:p-2 lg:p-4 xl:p-6">
|
||||||
<menu className="mb-2">
|
<RouteTitle>{t('Transactions')}</RouteTitle>
|
||||||
<BlocksRefetch refetch={refreshTxs} />
|
<BlocksRefetch refetch={refreshTxs} />
|
||||||
<TxsFilter filters={filters} setFilters={setFilters} />
|
|
||||||
</menu>
|
|
||||||
|
|
||||||
<TxsInfiniteList
|
<TxsInfiniteList
|
||||||
hasMoreTxs={hasMoreTxs}
|
hasMoreTxs={hasMoreTxs}
|
||||||
areTxsLoading={loading}
|
areTxsLoading={loading}
|
||||||
@@ -50,6 +24,6 @@ export const TxsListFiltered = () => {
|
|||||||
error={error}
|
error={error}
|
||||||
className="mb-28"
|
className="mb-28"
|
||||||
/>
|
/>
|
||||||
</>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
line-height: calc(min(var(--ag-line-height, 26px), 26px) - 4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vega-ag-grid .ag-row,
|
.vega-ag-grid .ag-row {
|
||||||
.vega-ag-grid .ag-cell {
|
border-width: 1px 0;
|
||||||
border-width: 0;
|
border-bottom: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light variables */
|
/* Light variables */
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
--ag-header-column-separator-color: theme(colors.neutral[300]);
|
||||||
--ag-row-border-color: theme(colors.white);
|
--ag-row-border-color: theme(colors.white);
|
||||||
--ag-row-hover-color: theme(colors.neutral[100]);
|
--ag-row-hover-color: theme(colors.neutral[100]);
|
||||||
|
--ag-font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark variables */
|
/* Dark variables */
|
||||||
@@ -57,8 +58,5 @@
|
|||||||
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
--ag-header-column-separator-color: theme(colors.neutral[600]);
|
||||||
--ag-row-border-color: theme(colors.black);
|
--ag-row-border-color: theme(colors.black);
|
||||||
--ag-row-hover-color: theme(colors.neutral[800]);
|
--ag-row-hover-color: theme(colors.neutral[800]);
|
||||||
}
|
--ag-font-size: 12px;
|
||||||
|
|
||||||
.voteicon svg {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+421
-428
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,6 @@ NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
|||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
|
||||||
|
|
||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
reporter: '../../node_modules/cypress-mochawesome-reporter',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
require('cypress-mochawesome-reporter/plugin')(on);
|
|
||||||
require('@cypress/grep/src/plugin')(config);
|
require('@cypress/grep/src/plugin')(config);
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
@@ -26,7 +25,6 @@ module.exports = defineConfig({
|
|||||||
viewportWidth: 1440,
|
viewportWidth: 1440,
|
||||||
viewportHeight: 900,
|
viewportHeight: 900,
|
||||||
numTestsKeptInMemory: 5,
|
numTestsKeptInMemory: 5,
|
||||||
downloadsFolder: 'cypress/downloads',
|
|
||||||
testIsolation: false,
|
testIsolation: false,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
@@ -49,7 +47,7 @@ module.exports = defineConfig({
|
|||||||
vegaTokenContractAddress: '0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7',
|
vegaTokenContractAddress: '0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7',
|
||||||
vegaTokenAddress: '0x67175Da1D5e966e40D11c4B2519392B2058373de',
|
vegaTokenAddress: '0x67175Da1D5e966e40D11c4B2519392B2058373de',
|
||||||
txTimeout: { timeout: 70000 },
|
txTimeout: { timeout: 70000 },
|
||||||
epochTimeout: { timeout: 10000 },
|
epochTimeout: { timeout: 6000 },
|
||||||
blockConfirmations: 3,
|
blockConfirmations: 3,
|
||||||
grepTags: '@regression @smoke @slow',
|
grepTags: '@regression @smoke @slow',
|
||||||
grepFilterSpecs: true,
|
grepFilterSpecs: true,
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
{
|
|
||||||
"rationale": {
|
|
||||||
"title": "New Market Proposal E2E submission",
|
|
||||||
"description": "E2E new market proposal"
|
|
||||||
},
|
|
||||||
"terms": {
|
|
||||||
"newMarket": {
|
|
||||||
"changes": {
|
|
||||||
"decimalPlaces": "5",
|
|
||||||
"positionDecimalPlaces": "5",
|
|
||||||
"linearSlippageFactor": "0.001",
|
|
||||||
"quadraticSlippageFactor": "0",
|
|
||||||
"lpPriceRange": "10",
|
|
||||||
"instrument": {
|
|
||||||
"name": "Token test market",
|
|
||||||
"code": "TEST.24h",
|
|
||||||
"future": {
|
|
||||||
"settlementAsset": "73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0",
|
|
||||||
"quoteName": "fBTC",
|
|
||||||
"dataSourceSpecForSettlementData": {
|
|
||||||
"external": {
|
|
||||||
"oracle": {
|
|
||||||
"signers": [
|
|
||||||
{
|
|
||||||
"pubKey": {
|
|
||||||
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"name": "prices.ETH.value",
|
|
||||||
"type": "TYPE_INTEGER",
|
|
||||||
"numberDecimalPlaces": "0"
|
|
||||||
},
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"operator": "OPERATOR_GREATER_THAN",
|
|
||||||
"value": "0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dataSourceSpecForTradingTermination": {
|
|
||||||
"external": {
|
|
||||||
"oracle": {
|
|
||||||
"signers": [
|
|
||||||
{
|
|
||||||
"pubKey": {
|
|
||||||
"key": "70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"filters": [
|
|
||||||
{
|
|
||||||
"key": {
|
|
||||||
"name": "trading.terminated.ETH5",
|
|
||||||
"type": "TYPE_BOOLEAN"
|
|
||||||
},
|
|
||||||
"conditions": [
|
|
||||||
{
|
|
||||||
"operator": "OPERATOR_EQUALS",
|
|
||||||
"value": "true"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dataSourceSpecBinding": {
|
|
||||||
"settlementDataProperty": "prices.ETH.value",
|
|
||||||
"tradingTerminationProperty": "trading.terminated.ETH5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"metadata": ["sector:energy", "sector:tech", "source:docs.vega.xyz"],
|
|
||||||
"priceMonitoringParameters": {
|
|
||||||
"triggers": [
|
|
||||||
{
|
|
||||||
"horizon": "43200",
|
|
||||||
"probability": "0.9999999",
|
|
||||||
"auctionExtension": "600"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"liquidityMonitoringParameters": {
|
|
||||||
"targetStakeParameters": {
|
|
||||||
"timeWindow": "3600",
|
|
||||||
"scalingFactor": 10
|
|
||||||
},
|
|
||||||
"triggeringRatio": "0.7",
|
|
||||||
"auctionExtension": "1"
|
|
||||||
},
|
|
||||||
"logNormal": {
|
|
||||||
"tau": 0.0001140771161,
|
|
||||||
"riskAversionParameter": 0.01,
|
|
||||||
"params": {
|
|
||||||
"mu": 0,
|
|
||||||
"r": 0.016,
|
|
||||||
"sigma": 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"closingTimestamp": 0,
|
|
||||||
"enactmentTimestamp": 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,23 +7,21 @@ import {
|
|||||||
import {
|
import {
|
||||||
createRawProposal,
|
createRawProposal,
|
||||||
createTenDigitUnixTimeStampForSpecifiedDays,
|
createTenDigitUnixTimeStampForSpecifiedDays,
|
||||||
|
enterUniqueFreeFormProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getDateFormatForSpecifiedDays,
|
getDateFormatForSpecifiedDays,
|
||||||
getProposalFromTitle,
|
getProposalIdFromList,
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
submitUniqueRawProposal,
|
getSubmittedProposalFromProposalList,
|
||||||
|
goToMakeNewProposal,
|
||||||
|
governanceProposalType,
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
|
waitForProposalSubmitted,
|
||||||
|
waitForProposalSync,
|
||||||
} from '../../../../governance-e2e/src/support/governance.functions';
|
} from '../../../../governance-e2e/src/support/governance.functions';
|
||||||
import {
|
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../../../governance-e2e/src/support/staking.functions';
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated,
|
|
||||||
stakingPageAssociateTokens,
|
|
||||||
stakingPageDisassociateAllTokens,
|
|
||||||
} from '../../../../governance-e2e/src/support/staking.functions';
|
|
||||||
import { ethereumWalletConnect } from '../../../../governance-e2e/src/support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../../../governance-e2e/src/support/wallet-eth.functions';
|
||||||
import {
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../../../governance-e2e/src/support/wallet-teardown.functions';
|
||||||
switchVegaWalletPubKey,
|
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
|
||||||
} from '../../support/wallet-functions';
|
|
||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import type { testFreeformProposal } from '../../support/common-interfaces';
|
||||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
||||||
|
|
||||||
@@ -40,9 +38,6 @@ const proposalDetailsTitle = '[data-testid="proposal-title"]';
|
|||||||
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
const proposalDetailsDescription = '[data-testid="proposal-description"]';
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const proposalDescriptionToggle = 'proposal-description-toggle';
|
|
||||||
const voteBreakdownToggle = 'vote-breakdown-toggle';
|
|
||||||
const proposalTermsToggle = 'proposal-json-toggle';
|
|
||||||
|
|
||||||
describe(
|
describe(
|
||||||
'Governance flow for proposal details',
|
'Governance flow for proposal details',
|
||||||
@@ -51,7 +46,7 @@ describe(
|
|||||||
before('connect wallets and set approval limit', function () {
|
before('connect wallets and set approval limit', function () {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
// cy.associateTokensToVegaWallet('1');
|
cy.associateTokensToVegaWallet('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit proposals tab', function () {
|
beforeEach('visit proposals tab', function () {
|
||||||
@@ -67,69 +62,61 @@ describe(
|
|||||||
|
|
||||||
// 3001-VOTE-050 3001-VOTE-054 3001-VOTE-055 3002-PROP-019
|
// 3001-VOTE-050 3001-VOTE-054 3001-VOTE-055 3002-PROP-019
|
||||||
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
it('Newly created raw proposal details - shows proposal title and full description', function () {
|
||||||
const proposalDescription =
|
|
||||||
'I propose that everyone evaluate the following IPFS document and vote Yes if they agree. bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si';
|
|
||||||
|
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
cy.get(openProposals).within(() => {
|
getProposalIdFromList(rawProposal.rationale.title);
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
cy.get(viewProposalButton).should('be.visible').click();
|
cy.get(openProposals).within(() => {
|
||||||
|
cy.get(`#${proposalId}`).within(() => {
|
||||||
|
cy.get(viewProposalButton).should('be.visible').click();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.get(proposalDetailsTitle).should(
|
cy.get(proposalDetailsTitle)
|
||||||
'contain.text',
|
.should('contain', rawProposal.rationale.title)
|
||||||
rawProposal.rationale.title
|
.and('be.visible');
|
||||||
);
|
|
||||||
cy.getByTestId(proposalDescriptionToggle).click();
|
|
||||||
cy.getByTestId('proposal-description-toggle');
|
|
||||||
cy.get(proposalDetailsDescription)
|
cy.get(proposalDetailsDescription)
|
||||||
.find('p')
|
.should('contain', rawProposal.rationale.description)
|
||||||
.should('have.text', proposalDescription);
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
// 3001-VOTE-008
|
// 3001-VOTE-052
|
||||||
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-010
|
|
||||||
cy.get('code.language-json')
|
cy.get('code.language-json')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get('.hljs-attr').eq(0).should('have.text', '"id"');
|
cy.get('.hljs-string').eq(0).should('have.text', '"ProposalTerms"');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-043
|
// 3001-VOTE-043
|
||||||
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
it('Newly created freeform proposal details - shows proposed and closing dates', function () {
|
||||||
|
const closingVoteHrs = '72';
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
const proposalTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
const proposalTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
||||||
|
|
||||||
submitUniqueRawProposal({
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
proposalTitle: proposalTitle,
|
enterUniqueFreeFormProposalBody(closingVoteHrs, proposalTitle);
|
||||||
closingTimestamp: proposalTimeStamp,
|
waitForProposalSubmitted();
|
||||||
});
|
waitForProposalSync();
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() =>
|
getSubmittedProposalFromProposalList(proposalTitle).within(() =>
|
||||||
cy.get(viewProposalButton).click()
|
cy.get(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
formatDateWithLocalTimezone(new Date(proposalTimeStamp * 1000))
|
formatDateWithLocalTimezone(new Date(proposalTimeStamp * 1000))
|
||||||
).then((closingDate) => {
|
).then((closingDate) => {
|
||||||
getProposalInformationFromTable('Closes on').should(
|
getProposalInformationFromTable('Closes on')
|
||||||
'have.text',
|
.contains(closingDate)
|
||||||
closingDate
|
.should('be.visible');
|
||||||
);
|
});
|
||||||
|
cy.wrap(
|
||||||
|
formatDateWithLocalTimezone(
|
||||||
|
new Date(createTenDigitUnixTimeStampForSpecifiedDays(0) * 1000)
|
||||||
|
)
|
||||||
|
).then((proposalDate) => {
|
||||||
|
getProposalInformationFromTable('Proposed on')
|
||||||
|
.contains(proposalDate)
|
||||||
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
getProposalInformationFromTable('Proposed on')
|
|
||||||
.invoke('text')
|
|
||||||
.should('not.be.empty');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposal details - shows default status set to fail', function () {
|
it('Newly created proposal details - shows default status set to fail', function () {
|
||||||
@@ -138,14 +125,13 @@ describe(
|
|||||||
// 3001-VOTE-067
|
// 3001-VOTE-067
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should(
|
||||||
'be.visible'
|
'be.visible'
|
||||||
);
|
);
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
getProposalInformationFromTable('Expected to pass')
|
||||||
.contains('👎')
|
.contains('👎')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
@@ -165,9 +151,9 @@ describe(
|
|||||||
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
it('Newly created proposal details - ability to vote for and against proposal - with minimum required tokens associated', function () {
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
// 3001-VOTE-080
|
// 3001-VOTE-080
|
||||||
cy.getByTestId('vote-buttons').contains('against').should('be.visible');
|
cy.getByTestId('vote-buttons').contains('against').should('be.visible');
|
||||||
@@ -193,7 +179,6 @@ describe(
|
|||||||
cy.get(proposalVoteProgressAgainstTokens)
|
cy.get(proposalVoteProgressAgainstTokens)
|
||||||
.contains('0.00')
|
.contains('0.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Tokens for proposal')
|
getProposalInformationFromTable('Tokens for proposal')
|
||||||
.should('have.text', (1).toFixed(2))
|
.should('have.text', (1).toFixed(2))
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -235,15 +220,14 @@ describe(
|
|||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
createRawProposal();
|
createRawProposal();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
// 3001-VOTE-079
|
// 3001-VOTE-079
|
||||||
cy.contains('You voted: For').should('be.visible');
|
cy.contains('You voted: For').should('be.visible');
|
||||||
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
cy.get(proposalVoteProgressForTokens).contains('1').and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Total Supply')
|
getProposalInformationFromTable('Total Supply')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((totalSupply) => {
|
.then((totalSupply) => {
|
||||||
@@ -251,15 +235,14 @@ describe(
|
|||||||
(Number(totalSupply.replace(/,/g, '')) * 0.001) /
|
(Number(totalSupply.replace(/,/g, '')) * 0.001) /
|
||||||
100
|
100
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
ethereumWalletConnect();
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated(
|
ensureSpecifiedUnstakedTokensAreAssociated(
|
||||||
tokensRequiredToAchieveResult
|
tokensRequiredToAchieveResult
|
||||||
);
|
);
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalVoteProgressForPercentage)
|
cy.get(proposalVoteProgressForPercentage)
|
||||||
.contains('100.00%')
|
.contains('100.00%')
|
||||||
@@ -276,7 +259,6 @@ describe(
|
|||||||
cy.get(proposalVoteProgressAgainstTokens)
|
cy.get(proposalVoteProgressAgainstTokens)
|
||||||
.contains('0.00')
|
.contains('0.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(voteBreakdownToggle).click();
|
|
||||||
getProposalInformationFromTable('Total tokens voted percentage')
|
getProposalInformationFromTable('Total tokens voted percentage')
|
||||||
.should('have.text', '0.00%')
|
.should('have.text', '0.00%')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -304,33 +286,5 @@ describe(
|
|||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to vote for proposal twice by switching public key', function () {
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
|
||||||
createRawProposal();
|
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
|
||||||
cy.get(viewProposalButton).click()
|
|
||||||
);
|
|
||||||
voteForProposal('for');
|
|
||||||
cy.contains('You voted: For').should('be.visible');
|
|
||||||
ethereumWalletConnect();
|
|
||||||
switchVegaWalletPubKey();
|
|
||||||
stakingPageAssociateTokens('2');
|
|
||||||
navigateTo(navigation.proposals);
|
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
|
||||||
cy.get(viewProposalButton).click()
|
|
||||||
);
|
|
||||||
cy.getByTestId('you-voted').should('not.exist');
|
|
||||||
voteForProposal('against');
|
|
||||||
cy.contains('You voted: Against').should('be.visible');
|
|
||||||
switchVegaWalletPubKey();
|
|
||||||
cy.get(proposalVoteProgressForTokens).should('contain.text', '1.00');
|
|
||||||
// Checking vote status for different public keys is displayed correctly
|
|
||||||
cy.contains('You voted: For').should('be.visible');
|
|
||||||
});
|
|
||||||
switchVegaWalletPubKey();
|
|
||||||
stakingPageDisassociateAllTokens();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ import {
|
|||||||
createUpdateNetworkProposalTxBody,
|
createUpdateNetworkProposalTxBody,
|
||||||
createFreeFormProposalTxBody,
|
createFreeFormProposalTxBody,
|
||||||
} from '../../support/proposal.functions';
|
} from '../../support/proposal.functions';
|
||||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-functions';
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||||
const closedProposals = '[data-testid="closed-proposals"]';
|
const closedProposals = '[data-testid="closed-proposals"]';
|
||||||
@@ -44,7 +43,6 @@ context(
|
|||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,12 +58,14 @@ context(
|
|||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
.last()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(proposalStatus).should('have.text', 'Enacted');
|
cy.get(proposalStatus).should('have.text', 'Enacted ');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
cy.getByTestId('proposal-type').should('have.text', 'New market');
|
||||||
cy.get(proposalStatus).should('have.text', 'Enacted');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted')
|
||||||
|
.and('be.visible');
|
||||||
cy.get(votesTable).within(() => {
|
cy.get(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
@@ -87,10 +87,16 @@ context(
|
|||||||
.last()
|
.last()
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Passed');
|
getProposalInformationFromTable('State') // 3001-VOTE-047
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Enacted');
|
.contains('Passed', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
cy.get(votesTable).within(() => {
|
cy.get(votesTable).within(() => {
|
||||||
cy.contains('Vote passed.').should('be.visible');
|
cy.contains('Vote passed.').should('be.visible');
|
||||||
cy.contains('Voting has ended.').should('be.visible');
|
cy.contains('Voting has ended.').should('be.visible');
|
||||||
@@ -115,9 +121,13 @@ context(
|
|||||||
.last()
|
.last()
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Enacted');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Enacted', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3001-VOTE-048 3001-VOTE-049 3001-VOTE-050
|
// 3001-VOTE-048 3001-VOTE-049 3001-VOTE-050
|
||||||
@@ -134,8 +144,12 @@ context(
|
|||||||
.last()
|
.last()
|
||||||
.within(() => cy.get(viewProposalButton).click());
|
.within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
cy.get(proposalStatus).should('have.text', 'Open');
|
getProposalInformationFromTable('State')
|
||||||
cy.get(proposalStatus, proposalTimeout).should('have.text', 'Declined');
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('State') // 3001-VOTE-047
|
||||||
|
.contains('Declined', proposalTimeout)
|
||||||
|
.and('be.visible');
|
||||||
getProposalInformationFromTable('Rejection reason')
|
getProposalInformationFromTable('Rejection reason')
|
||||||
.contains('PROPOSAL_ERROR_PARTICIPATION_THRESHOLD_NOT_REACHED')
|
.contains('PROPOSAL_ERROR_PARTICIPATION_THRESHOLD_NOT_REACHED')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import {
|
|||||||
enterRawProposalBody,
|
enterRawProposalBody,
|
||||||
enterUniqueFreeFormProposalBody,
|
enterUniqueFreeFormProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getProposalFromTitle,
|
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
|
getSubmittedProposalFromProposalList,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
governanceProposalType,
|
||||||
submitUniqueRawProposal,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
|
waitForProposalSubmitted,
|
||||||
waitForProposalSync,
|
waitForProposalSync,
|
||||||
} from '../../support/governance.functions';
|
} from '../../support/governance.functions';
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
vegaWalletSetSpecifiedApprovalAmount,
|
||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-teardown.functions';
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import type { testFreeformProposal } from '../../support/common-interfaces';
|
||||||
|
|
||||||
@@ -45,7 +45,11 @@ const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
|||||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const rawProposalData = '[data-testid="proposal-data"]';
|
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 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 rejectProposalsLink = '[href="/proposals/rejected"]';
|
||||||
const feedbackError = '[data-testid="Error"]';
|
const feedbackError = '[data-testid="Error"]';
|
||||||
const noOpenProposals = '[data-testid="no-open-proposals"]';
|
const noOpenProposals = '[data-testid="no-open-proposals"]';
|
||||||
@@ -77,6 +81,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
|
cy.associateTokensToVegaWallet('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('visit governance tab', function () {
|
beforeEach('visit governance tab', function () {
|
||||||
@@ -90,8 +95,7 @@ context(
|
|||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Test can only pass if run before other proposal tests.
|
it('Should be able to see that no proposals exist', function () {
|
||||||
it.skip('Should be able to see that no proposals exist', function () {
|
|
||||||
// 3001-VOTE-003
|
// 3001-VOTE-003
|
||||||
cy.get(noOpenProposals)
|
cy.get(noOpenProposals)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
@@ -101,8 +105,9 @@ context(
|
|||||||
.and('have.text', 'There are no enacted or rejected proposals');
|
.and('have.text', 'There are no enacted or rejected proposals');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3002-PROP-002 3002-PROP-003 3001-VOTE-012 3007-PNE-020 3004-PMAC-004 3005-PASN-004 3008-PFRO-016 3003-PMAN-004
|
// 3002-PROP-002
|
||||||
it('Proposal form - shows how many vega tokens are required to make a proposal', function () {
|
// 3002-PROP-003
|
||||||
|
it('Submit a proposal form - shows how many vega tokens are required to make a proposal', function () {
|
||||||
// 3002-PROP-005
|
// 3002-PROP-005
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||||
cy.contains(
|
cy.contains(
|
||||||
@@ -110,14 +115,22 @@ context(
|
|||||||
).should('be.visible');
|
).should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3002-PROP-011 3008-PFRO-005
|
// 3002-PROP-011
|
||||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
it('Able to submit a valid freeform proposal - with minimum required tokens associated', function () {
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
verifyUnstakedBalance(1);
|
cy.get(minVoteButton).should('be.visible'); // 3002-PROP-008
|
||||||
createRawProposal();
|
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();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3008-PFRO-002 3008-PFRO-004
|
|
||||||
it('Able to submit a valid freeform proposal - with minimum required tokens associated - but also staked', function () {
|
it('Able to submit a valid freeform proposal - with minimum required tokens associated - but also staked', function () {
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('2');
|
ensureSpecifiedUnstakedTokensAreAssociated('2');
|
||||||
verifyUnstakedBalance(2);
|
verifyUnstakedBalance(2);
|
||||||
@@ -127,18 +140,25 @@ context(
|
|||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
|
|
||||||
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
cy.get(vegaWalletStakedBalances, txTimeout).should('contain', '2');
|
||||||
createRawProposal();
|
|
||||||
|
navigateTo(navigation.proposals);
|
||||||
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
|
enterUniqueFreeFormProposalBody('50', generateFreeFormProposalTitle());
|
||||||
|
waitForProposalSubmitted();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
it('Creating a proposal - proposal rejected - when closing time sooner than system default', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
enterUniqueFreeFormProposalBody('0.1', generateFreeFormProposalTitle());
|
enterUniqueFreeFormProposalBody('0.1', generateFreeFormProposalTitle());
|
||||||
|
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||||
|
'not.exist'
|
||||||
|
);
|
||||||
cy.get('input:invalid')
|
cy.get('input:invalid')
|
||||||
.invoke('prop', 'validationMessage')
|
.invoke('prop', 'validationMessage')
|
||||||
.should('equal', 'Value must be greater than or equal to 1.');
|
.should('equal', 'Value must be greater than or equal to 1.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
it('Creating a proposal - proposal rejected - when closing time later than system default', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
enterUniqueFreeFormProposalBody(
|
enterUniqueFreeFormProposalBody(
|
||||||
'100000',
|
'100000',
|
||||||
@@ -165,13 +185,17 @@ context(
|
|||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get(rejectProposalsLink).click();
|
cy.get(rejectProposalsLink).click();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getSubmittedProposalFromProposalList(
|
||||||
|
rawProposal.rationale.title
|
||||||
|
).within(() => {
|
||||||
cy.contains('Rejected').should('be.visible');
|
cy.contains('Rejected').should('be.visible');
|
||||||
cy.contains('Close time too late').should('be.visible');
|
cy.contains('Close time too late').should('be.visible');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.getByTestId('proposal-status').should('have.text', 'Rejected');
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Rejected')
|
||||||
|
.and('be.visible');
|
||||||
getProposalInformationFromTable('Rejection reason')
|
getProposalInformationFromTable('Rejection reason')
|
||||||
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
.contains('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@@ -261,38 +285,23 @@ context(
|
|||||||
closeDialog();
|
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
|
// 1005-PROP-009
|
||||||
it('Unable to vote on a freeform proposal - when some but not enough vega associated', function () {
|
it('Unable to vote on a freeform proposal - when some but not enough vega associated', function () {
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
||||||
ethereumWalletConnect();
|
enterUniqueFreeFormProposalBody('50', proposalTitle);
|
||||||
|
waitForProposalSubmitted();
|
||||||
stakingPageDisassociateTokens('0.0001');
|
stakingPageDisassociateTokens('0.0001');
|
||||||
cy.get(vegaWallet)
|
cy.get(vegaWallet).within(() => {
|
||||||
.first()
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
.within(() => {
|
'contain',
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
'0.9999'
|
||||||
'contain',
|
);
|
||||||
'0.9999'
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() =>
|
getSubmittedProposalFromProposalList(proposalTitle).within(() =>
|
||||||
cy.get(viewProposalButton).click()
|
cy.get(viewProposalButton).click()
|
||||||
);
|
);
|
||||||
cy.contains('Vote breakdown').should('be.visible', {
|
cy.contains('Vote breakdown').should('be.visible', {
|
||||||
@@ -310,9 +319,9 @@ context(
|
|||||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||||
cy.get('[data-testid="disconnect"]').click();
|
cy.get('[data-testid="disconnect"]').click();
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
getSubmittedProposalFromProposalList(
|
||||||
cy.get(viewProposalButton).click()
|
rawProposal.rationale.title
|
||||||
);
|
).within(() => cy.get(viewProposalButton).click());
|
||||||
});
|
});
|
||||||
// 3001-VOTE-075
|
// 3001-VOTE-075
|
||||||
// 3001-VOTE-076
|
// 3001-VOTE-076
|
||||||
|
|||||||
@@ -1,33 +1,23 @@
|
|||||||
import {
|
import {
|
||||||
closeDialog,
|
closeDialog,
|
||||||
dissociateFromSecondWalletKey,
|
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
turnTelemetryOff,
|
||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
|
||||||
getDownloadedProposalJsonPath,
|
|
||||||
submitUniqueRawProposal,
|
|
||||||
} from '../../support/governance.functions';
|
|
||||||
import {
|
import {
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
|
waitForProposalSubmitted,
|
||||||
} from '../../support/governance.functions';
|
} from '../../support/governance.functions';
|
||||||
import {
|
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated,
|
|
||||||
stakingPageAssociateTokens,
|
|
||||||
stakingPageDisassociateAllTokens,
|
|
||||||
} from '../../support/staking.functions';
|
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import {
|
import {
|
||||||
switchVegaWalletPubKey,
|
|
||||||
vegaWalletFaucetAssetsWithoutCheck,
|
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
vegaWalletSetSpecifiedApprovalAmount,
|
||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-teardown.functions';
|
||||||
|
import { vegaWalletFaucetAssetsWithoutCheck } from '../../support/wallet-vega.functions';
|
||||||
|
|
||||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
@@ -35,11 +25,15 @@ const proposalType = '[data-testid="proposal-type"]';
|
|||||||
const proposalDetails = '[data-testid="proposal-details"]';
|
const proposalDetails = '[data-testid="proposal-details"]';
|
||||||
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
const newProposalSubmitButton = '[data-testid="proposal-submit"]';
|
||||||
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]';
|
||||||
|
const proposalValidationDeadline =
|
||||||
|
'[data-testid="proposal-validation-deadline"]';
|
||||||
const proposalParameterSelect = '[data-testid="proposal-parameter-select"]';
|
const proposalParameterSelect = '[data-testid="proposal-parameter-select"]';
|
||||||
const proposalMarketSelect = '[data-testid="proposal-market-select"]';
|
const proposalMarketSelect = '[data-testid="proposal-market-select"]';
|
||||||
const newProposalTitle = '[data-testid="proposal-title"]';
|
const newProposalTitle = '[data-testid="proposal-title"]';
|
||||||
const newProposalDescription = '[data-testid="proposal-description"]';
|
const newProposalDescription = '[data-testid="proposal-description"]';
|
||||||
const newProposalTerms = '[data-testid="proposal-terms"]';
|
const newProposalTerms = '[data-testid="proposal-terms"]';
|
||||||
|
const currentParameterValue =
|
||||||
|
'[data-testid="selected-proposal-param-current-value"]';
|
||||||
const newProposedParameterValue =
|
const newProposedParameterValue =
|
||||||
'[data-testid="selected-proposal-param-new-value"]';
|
'[data-testid="selected-proposal-param-new-value"]';
|
||||||
const minVoteDeadline = '[data-testid="min-vote"]';
|
const minVoteDeadline = '[data-testid="min-vote"]';
|
||||||
@@ -59,8 +53,19 @@ const proposalTermsSection = 'proposal';
|
|||||||
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
||||||
const fUSDCId =
|
const fUSDCId =
|
||||||
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
|
'816af99af60d684502a40824758f6b5377e6af48e50a9ee8ef478ecb879ea8bc';
|
||||||
|
const epochTimeout = Cypress.env('epochTimeout');
|
||||||
const proposalTimeout = { timeout: 14000 };
|
const proposalTimeout = { timeout: 14000 };
|
||||||
|
|
||||||
|
const governanceProposalType = {
|
||||||
|
NETWORK_PARAMETER: 'Network parameter',
|
||||||
|
NEW_MARKET: 'New market',
|
||||||
|
UPDATE_MARKET: 'Update market',
|
||||||
|
NEW_ASSET: 'New asset',
|
||||||
|
UPDATE_ASSET: 'Update asset',
|
||||||
|
FREEFORM: 'Freeform',
|
||||||
|
RAW: 'raw proposal',
|
||||||
|
};
|
||||||
|
|
||||||
// 3001-VOTE-007
|
// 3001-VOTE-007
|
||||||
context(
|
context(
|
||||||
'Governance flow - form validations for different governance proposals',
|
'Governance flow - form validations for different governance proposals',
|
||||||
@@ -83,10 +88,28 @@ context(
|
|||||||
navigateTo(navigation.proposals);
|
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 () {
|
it('Unable to submit network parameter with missing/invalid fields', function () {
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||||
cy.get(proposalDownloadBtn).click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.get(inputError).should('have.length', 3);
|
cy.get(inputError).should('have.length', 3);
|
||||||
cy.get(newProposalTitle).type(
|
cy.get(newProposalTitle).type(
|
||||||
'Invalid update network parameter proposal'
|
'Invalid update network parameter proposal'
|
||||||
@@ -97,78 +120,62 @@ context(
|
|||||||
);
|
);
|
||||||
cy.get(newProposedParameterValue).type('0');
|
cy.get(newProposedParameterValue).type('0');
|
||||||
cy.get(proposalVoteDeadline).clear().type('0');
|
cy.get(proposalVoteDeadline).clear().type('0');
|
||||||
cy.get(proposalDownloadBtn)
|
|
||||||
.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(newProposalSubmitButton).click();
|
||||||
validateDialogContentMsg('PROPOSAL_ERROR_CLOSE_TIME_TOO_SOON');
|
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'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3007-PNEC-001 3007-PNEC-003
|
it('Able to download network param proposal json', function () {
|
||||||
it('Able to download and submit network param proposal', function () {
|
const downloadFolder = './cypress/downloads/';
|
||||||
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||||
// 3007-PNEC-006
|
cy.log('Download proposal file');
|
||||||
cy.get(newProposalTitle)
|
cy.get(proposalDownloadBtn)
|
||||||
.siblings()
|
.should('be.visible')
|
||||||
.should('contain.text', '(100 characters or less)');
|
.click()
|
||||||
// 3007-PNEC-004 3007-PNEC-005
|
.then(() => {
|
||||||
cy.get(newProposalTitle).type('Test update network parameter proposal');
|
const filename =
|
||||||
// 3007-PNEC-009
|
downloadFolder +
|
||||||
cy.get(newProposalDescription)
|
'vega-network-param-proposal-' +
|
||||||
.siblings()
|
getFormattedTime() +
|
||||||
.should('contain.text', '(20,000 characters or less)');
|
'.json';
|
||||||
// 3007-PNEC-007 3007-PNEC-008
|
cy.readFile(filename, proposalTimeout)
|
||||||
|
.its('terms.updateNetworkParameter')
|
||||||
|
.should('exist');
|
||||||
|
});
|
||||||
|
|
||||||
cy.get(newProposalDescription).type('E2E test for downloading proposals');
|
cy.get(newProposalDescription).type('E2E test for downloading proposals');
|
||||||
// 3007-PNEC-010
|
|
||||||
cy.get(proposalParameterSelect).select(
|
cy.get(proposalParameterSelect).select(
|
||||||
'governance_proposal_asset_minClose'
|
'governance_proposal_asset_minClose'
|
||||||
);
|
);
|
||||||
// 3007-PNEC-011
|
|
||||||
cy.get(newProposedParameterValue).type('10s');
|
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.log('Download updated proposal file');
|
||||||
cy.get(proposalDownloadBtn)
|
cy.get(proposalDownloadBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click()
|
.click()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cy.wrap(
|
const filename =
|
||||||
getDownloadedProposalJsonPath('vega-network-param-proposal-')
|
downloadFolder +
|
||||||
).then((filePath) => {
|
'vega-network-param-proposal-' +
|
||||||
cy.readFile(String(filePath), { timeout: 14000 }).then(
|
getFormattedTime() +
|
||||||
(jsonFile) => {
|
'.json';
|
||||||
cy.wrap(jsonFile)
|
cy.get(proposalDownloadBtn).should('be.visible').click();
|
||||||
.its('rationale.description')
|
cy.readFile(filename, proposalTimeout).then((jsonFile) => {
|
||||||
.should('eq', 'E2E test for downloading proposals');
|
cy.wrap(jsonFile)
|
||||||
cy.wrap(jsonFile)
|
.its('rationale.description')
|
||||||
.its('terms.updateNetworkParameter.changes.key')
|
.should('eq', 'E2E test for downloading proposals');
|
||||||
.should('eq', 'governance.proposal.asset.minClose');
|
cy.wrap(jsonFile)
|
||||||
cy.wrap(jsonFile)
|
.its('terms.updateNetworkParameter.changes.key')
|
||||||
.its('terms.updateNetworkParameter.changes.value')
|
.should('eq', 'governance.proposal.asset.minClose');
|
||||||
.should('eq', '10s');
|
cy.wrap(jsonFile)
|
||||||
}
|
.its('terms.updateNetworkParameter.changes.value')
|
||||||
);
|
.should('eq', '10s');
|
||||||
// 3007-PNE-019
|
|
||||||
goToMakeNewProposal(governanceProposalType.RAW);
|
|
||||||
submitUniqueRawProposal({ proposalBody: filePath });
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -188,58 +195,38 @@ context(
|
|||||||
'have.text',
|
'have.text',
|
||||||
'Proposal will fail if enactment is earlier than the voting deadline'
|
'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(newProposalSubmitButton).click();
|
||||||
validateFeedBackMsg(
|
cy.get(feedbackError).should(
|
||||||
|
'have.text',
|
||||||
'Invalid params: proposal_submission.terms.closing_timestamp (cannot be after enactment time)'
|
'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
|
// 3003-PMAN-001
|
||||||
it(
|
it('Able to submit valid new market proposal', function () {
|
||||||
'Able to submit valid new market proposal',
|
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||||
{ tags: '@smoke' },
|
cy.get(newProposalTitle).type('Test new market proposal');
|
||||||
function () {
|
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
cy.fixture('/proposals/new-market').then((newMarketProposal) => {
|
||||||
cy.get(newProposalTitle).type('Test new market proposal');
|
const newMarketPayload = JSON.stringify(newMarketProposal);
|
||||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
cy.get(newProposalTerms).type(newMarketPayload, {
|
||||||
cy.fixture('/proposals/new-market').then((newMarketProposal) => {
|
parseSpecialCharSequences: false,
|
||||||
const newMarketPayload = JSON.stringify(newMarketProposal);
|
delay: 2,
|
||||||
cy.get(newProposalTerms).type(newMarketPayload, {
|
|
||||||
parseSpecialCharSequences: false,
|
|
||||||
delay: 2,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
cy.get(proposalDownloadBtn)
|
});
|
||||||
.should('be.visible')
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
.click()
|
waitForProposalSubmitted();
|
||||||
.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 () {
|
it('Unable to submit new market proposal with missing/invalid fields', function () {
|
||||||
const errorMsg =
|
const errorMsg =
|
||||||
'Invalid params: the transaction does not use a valid Vega command: unknown field "invalid" in vega.NewMarket';
|
'Invalid params: the transaction does not use a valid Vega command: unknown field "invalid" in vega.NewMarket';
|
||||||
|
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
goToMakeNewProposal(governanceProposalType.NEW_MARKET);
|
||||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.get(inputError).should('have.length', 3);
|
cy.get(inputError).should('have.length', 3);
|
||||||
cy.get(newProposalTitle).type('Test new market proposal');
|
cy.get(newProposalTitle).type('Test new market proposal');
|
||||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||||
@@ -251,27 +238,14 @@ context(
|
|||||||
delay: 2,
|
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.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||||
validateFeedBackMsg(errorMsg);
|
cy.get(feedbackError).should('have.text', errorMsg);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Will fail if run after 'Able to submit update market proposal and vote for proposal'
|
// Will fail if run after 'Able to submit update market proposal and vote for proposal'
|
||||||
// 3002-PROP-022
|
// 3002-PROP-022
|
||||||
it('Unable to submit update market proposal without equity-like share in the market', function () {
|
it('Unable to submit update market proposal without equity-like share in the market', function () {
|
||||||
switchVegaWalletPubKey();
|
|
||||||
stakingPageAssociateTokens('1');
|
|
||||||
goToMakeNewProposal(governanceProposalType.UPDATE_MARKET);
|
goToMakeNewProposal(governanceProposalType.UPDATE_MARKET);
|
||||||
cy.get(newProposalTitle).type('Test update market proposal - rejected');
|
cy.get(newProposalTitle).type('Test update market proposal - rejected');
|
||||||
cy.get(newProposalDescription).type('E2E test for proposals');
|
cy.get(newProposalDescription).type('E2E test for proposals');
|
||||||
@@ -283,24 +257,12 @@ context(
|
|||||||
delay: 2,
|
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.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||||
validateDialogContentMsg('PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE');
|
cy.getByTestId('dialog-content')
|
||||||
closeDialog();
|
.find('p')
|
||||||
ethereumWalletConnect();
|
.should('have.text', 'PROPOSAL_ERROR_INSUFFICIENT_EQUITY_LIKE_SHARE');
|
||||||
stakingPageDisassociateAllTokens();
|
ensureSpecifiedUnstakedTokensAreAssociated('1');
|
||||||
switchVegaWalletPubKey();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3002-PROP-020
|
// 3002-PROP-020
|
||||||
@@ -322,25 +284,15 @@ context(
|
|||||||
delay: 2,
|
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.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
cy.contains('Transaction failed', proposalTimeout).should('be.visible');
|
||||||
validateFeedBackMsg(
|
cy.get(feedbackError).should(
|
||||||
|
'have.text',
|
||||||
'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)'
|
'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 3004-PMAC-003
|
// 3001-VOTE-092 3004-PMAC-001
|
||||||
it('Able to submit update market proposal and vote for proposal', function () {
|
it('Able to submit update market proposal and vote for proposal', function () {
|
||||||
vegaWalletFaucetAssetsWithoutCheck(
|
vegaWalletFaucetAssetsWithoutCheck(
|
||||||
fUSDCId,
|
fUSDCId,
|
||||||
@@ -370,20 +322,11 @@ context(
|
|||||||
delay: 2,
|
delay: 2,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.get(proposalDownloadBtn)
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
.should('be.visible')
|
waitForProposalSubmitted();
|
||||||
.click()
|
|
||||||
.then(() => {
|
|
||||||
cy.wrap(
|
|
||||||
getDownloadedProposalJsonPath('vega-update-market-proposal-')
|
|
||||||
).then((filePath) => {
|
|
||||||
goToMakeNewProposal(governanceProposalType.RAW);
|
|
||||||
submitUniqueRawProposal({ proposalBody: filePath });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get('@EnactedMarketId').then((marketId) => {
|
cy.get('@EnactedMarketId').then((marketId) => {
|
||||||
cy.contains(String(marketId).slice(0, 6))
|
cy.contains(String(marketId))
|
||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
.last()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
@@ -407,13 +350,12 @@ context(
|
|||||||
'contain.text',
|
'contain.text',
|
||||||
'Currently expected to pass'
|
'Currently expected to pass'
|
||||||
);
|
);
|
||||||
cy.getByTestId('vote-breakdown-toggle').click();
|
|
||||||
getProposalInformationFromTable('Expected to pass')
|
getProposalInformationFromTable('Expected to pass')
|
||||||
.contains('👍 by token vote')
|
.contains('👍 by token vote')
|
||||||
.should('be.visible');
|
.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 () {
|
it('Able to submit new asset proposal using min deadlines', function () {
|
||||||
const proposalTitle = 'Test new asset proposal';
|
const proposalTitle = 'Test new asset proposal';
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
||||||
@@ -429,23 +371,25 @@ context(
|
|||||||
cy.get(minVoteDeadline).click();
|
cy.get(minVoteDeadline).click();
|
||||||
cy.get(minValidationDeadline).click();
|
cy.get(minValidationDeadline).click();
|
||||||
cy.get(minEnactDeadline).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.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();
|
closeDialog();
|
||||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
// cannot submit a proposal with ERC20 address already in use
|
// cannot submit a proposal with ERC20 address already in use
|
||||||
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
cy.contains('Proposal rejected', proposalTimeout).should('be.visible');
|
||||||
validateDialogContentMsg('PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE');
|
cy.getByTestId('dialog-content')
|
||||||
|
.last()
|
||||||
|
.within(() => {
|
||||||
|
cy.get('p').should(
|
||||||
|
'have.text',
|
||||||
|
'PROPOSAL_ERROR_ERC20_ADDRESS_ALREADY_IN_USE'
|
||||||
|
);
|
||||||
|
});
|
||||||
closeDialog();
|
closeDialog();
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.contains(proposalTitle)
|
cy.contains(proposalTitle)
|
||||||
@@ -454,7 +398,6 @@ context(
|
|||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
});
|
});
|
||||||
cy.getByTestId('proposal-terms-toggle').click();
|
|
||||||
cy.getByTestId(proposalTermsSection).within(() => {
|
cy.getByTestId(proposalTermsSection).within(() => {
|
||||||
cy.contains('USDT Coin').should('be.visible');
|
cy.contains('USDT Coin').should('be.visible');
|
||||||
cy.contains('USDT').should('be.visible');
|
cy.contains('USDT').should('be.visible');
|
||||||
@@ -463,8 +406,15 @@ context(
|
|||||||
|
|
||||||
it('Unable to submit new asset proposal with missing/invalid fields', function () {
|
it('Unable to submit new asset proposal with missing/invalid fields', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
goToMakeNewProposal(governanceProposalType.NEW_ASSET);
|
||||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.get(inputError).should('have.length', 3);
|
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 () {
|
it('Able to submit update asset proposal using min deadline', function () {
|
||||||
@@ -475,17 +425,8 @@ context(
|
|||||||
enterUpdateAssetProposalDetails();
|
enterUpdateAssetProposalDetails();
|
||||||
cy.get(minVoteDeadline).click();
|
cy.get(minVoteDeadline).click();
|
||||||
cy.get(minEnactDeadline).click();
|
cy.get(minEnactDeadline).click();
|
||||||
cy.get(proposalDownloadBtn)
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
.should('be.visible')
|
waitForProposalSubmitted();
|
||||||
.click()
|
|
||||||
.then(() => {
|
|
||||||
cy.wrap(
|
|
||||||
getDownloadedProposalJsonPath('vega-update-asset-proposal-')
|
|
||||||
).then((filePath) => {
|
|
||||||
goToMakeNewProposal(governanceProposalType.RAW);
|
|
||||||
submitUniqueRawProposal({ proposalBody: filePath });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get(openProposals).within(() => {
|
cy.get(openProposals).within(() => {
|
||||||
cy.get(proposalType)
|
cy.get(proposalType)
|
||||||
@@ -493,7 +434,7 @@ context(
|
|||||||
.parentsUntil(proposalListItem)
|
.parentsUntil(proposalListItem)
|
||||||
.last()
|
.last()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(proposalDetails).should('contain.text', assetId.slice(0, 6)); // 3001-VOTE-029
|
cy.get(proposalDetails).should('contain.text', assetId); // 3001-VOTE-029
|
||||||
cy.getByTestId(viewProposalBtn).click();
|
cy.getByTestId(viewProposalBtn).click();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -501,97 +442,37 @@ context(
|
|||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('not.be.empty');
|
.should('not.be.empty');
|
||||||
// 3001-VOTE-030 3001-VOTE-031
|
// 3001-VOTE-030 3001-VOTE-031
|
||||||
cy.getByTestId('proposal-terms-toggle').click();
|
cy.getByTestId(proposalTermsSection).within(() => {
|
||||||
cy.getByTestId('proposal-terms').within(() => {
|
cy.contains('UpdateAsset').should('be.visible');
|
||||||
getProposalInformationFromTable('assetId').should('have.text', assetId);
|
cy.contains('UpdateERC20').should('be.visible');
|
||||||
getProposalInformationFromTable('lifetimeLimit').should(
|
cy.contains('"lifetimeLimit": "10"').should('be.visible');
|
||||||
'have.text',
|
|
||||||
'10'
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3006-PASC-001 3006-PASC-003
|
|
||||||
it('Able to submit update asset proposal using max deadline', function () {
|
it('Able to submit update asset proposal using max deadline', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
||||||
enterUpdateAssetProposalDetails();
|
enterUpdateAssetProposalDetails();
|
||||||
cy.get(maxVoteDeadline).click();
|
cy.get(maxVoteDeadline).click();
|
||||||
cy.get(maxEnactDeadline).click();
|
cy.get(maxEnactDeadline).click();
|
||||||
cy.get(proposalDownloadBtn)
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
.should('be.visible')
|
waitForProposalSubmitted();
|
||||||
.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 () {
|
it('Unable to submit edit asset proposal with missing/invalid fields', function () {
|
||||||
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
goToMakeNewProposal(governanceProposalType.UPDATE_ASSET);
|
||||||
cy.get(proposalDownloadBtn).should('be.visible').click();
|
cy.get(newProposalSubmitButton).should('be.visible').click();
|
||||||
cy.get(inputError).should('have.length', 3);
|
cy.get(inputError).should('have.length', 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to download and submit freeform proposal', function () {
|
function getFormattedTime() {
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
const now = new Date();
|
||||||
// 3008-PFRO-006
|
const day = now.getDate().toString().padStart(2, '0');
|
||||||
cy.get(newProposalTitle)
|
const month = now.toLocaleString('en-US', { month: 'short' });
|
||||||
.siblings()
|
const year = now.getFullYear().toString();
|
||||||
.should('contain.text', '(100 characters or less)'); // 3008-PFRO-007
|
const hours = now.getHours().toString().padStart(2, '0');
|
||||||
// 3008-PFRO-005
|
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||||
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 });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
after('Disassociate from second wallet key if present', function () {
|
return `${day}-${month}-${year}-${hours}-${minutes}`;
|
||||||
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() {
|
function enterUpdateAssetProposalDetails() {
|
||||||
|
|||||||
@@ -6,31 +6,28 @@ import {
|
|||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
|
createFreeformProposal,
|
||||||
createRawProposal,
|
createRawProposal,
|
||||||
createTenDigitUnixTimeStampForSpecifiedDays,
|
createTenDigitUnixTimeStampForSpecifiedDays,
|
||||||
enterRawProposalBody,
|
enterRawProposalBody,
|
||||||
generateFreeFormProposalTitle,
|
generateFreeFormProposalTitle,
|
||||||
getProposalFromTitle,
|
getProposalIdFromList,
|
||||||
getProposalInformationFromTable,
|
getProposalInformationFromTable,
|
||||||
|
getSubmittedProposalFromProposalList,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
governanceProposalType,
|
||||||
submitUniqueRawProposal,
|
|
||||||
voteForProposal,
|
voteForProposal,
|
||||||
waitForProposalSubmitted,
|
waitForProposalSubmitted,
|
||||||
waitForProposalSync,
|
waitForProposalSync,
|
||||||
} from '../../support/governance.functions';
|
} from '../../support/governance.functions';
|
||||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
import { ensureSpecifiedUnstakedTokensAreAssociated } from '../../support/staking.functions';
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-functions';
|
import { vegaWalletSetSpecifiedApprovalAmount } from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const proposalListItem = 'proposals-list-item';
|
|
||||||
const openProposals = '[data-testid="open-proposals"]';
|
const openProposals = '[data-testid="open-proposals"]';
|
||||||
const voteStatus = 'vote-status';
|
const voteStatus = '[data-testid="vote-status"]';
|
||||||
const proposalType = 'proposal-type';
|
|
||||||
const proposalStatus = 'proposal-status';
|
|
||||||
const proposalClosingDate = '[data-testid="vote-details"]';
|
const proposalClosingDate = '[data-testid="vote-details"]';
|
||||||
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
const viewProposalButton = '[data-testid="view-proposal-btn"]';
|
||||||
const voteBreakDownToggle = 'vote-breakdown-toggle';
|
|
||||||
|
|
||||||
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||||
before('connect wallets and set approval limit', function () {
|
before('connect wallets and set approval limit', function () {
|
||||||
@@ -63,12 +60,12 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
cy.get(openProposals).within(() => {
|
cy.get(openProposals).within(() => {
|
||||||
|
cy.get(proposalClosingDate).first().should('contain.text', 'year');
|
||||||
|
cy.get(proposalClosingDate).should('contain.text', 'months');
|
||||||
cy.get(proposalClosingDate)
|
cy.get(proposalClosingDate)
|
||||||
.first()
|
.last()
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('match', /days|minutes/);
|
.should('match', /days|minutes/);
|
||||||
cy.get(proposalClosingDate).should('contain.text', 'months');
|
|
||||||
cy.get(proposalClosingDate).last().should('contain.text', 'year');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,28 +73,36 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
const proposerId = Cypress.env('vegaWalletPublicKey');
|
const proposerId = Cypress.env('vegaWalletPublicKey');
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
createFreeformProposal(proposalTitle);
|
||||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
getProposalIdFromList(proposalTitle);
|
||||||
cy.get('[data-testid="filter-input"]').type(proposerId);
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
// cy.get(`#${proposalId}`).should('contain', proposalId);
|
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||||
cy.contains(proposalTitle).should('be.visible');
|
cy.get('[data-testid="filter-input"]').type(proposerId);
|
||||||
cy.get('[data-testid="filter-input"]').type('123');
|
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||||
cy.getByTestId(proposalListItem).should('not.exist');
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposals list - shows title and portion of summary', function () {
|
it('Newly created proposals list - shows title and portion of summary', function () {
|
||||||
const proposalPath = 'src/fixtures/proposals/new-market-raw.json';
|
createRawProposal(this.minProposerBalance); // 3001-VOTE-052
|
||||||
const proposalTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(3);
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
submitUniqueRawProposal({
|
getProposalIdFromList(rawProposal.rationale.title);
|
||||||
proposalBody: proposalPath,
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
enactmentTimestamp: proposalTimestamp,
|
cy.get(openProposals).within(() => {
|
||||||
closingTimestamp: proposalTimestamp,
|
// 3001-VOTE-008
|
||||||
}); // 3001-VOTE-052
|
// 3001-VOTE-034
|
||||||
// 3001-VOTE-008
|
cy.get(`#${proposalId}`)
|
||||||
// 3001-VOTE-034
|
// 3001-VOTE-097
|
||||||
// 3001-VOTE-097
|
.should('contain', rawProposal.rationale.title)
|
||||||
cy.contains('New Market Proposal E2E submission');
|
.and('be.visible');
|
||||||
cy.contains('Code: TEST.24h. fBTC settled future.').should('be.visible');
|
cy.get(`#${proposalId}`)
|
||||||
|
.should(
|
||||||
|
'contain',
|
||||||
|
rawProposal.rationale.description.substring(0, 59)
|
||||||
|
)
|
||||||
|
.and('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Newly created proposals list - shows open proposals in an open state', function () {
|
it('Newly created proposals list - shows open proposals in an open state', function () {
|
||||||
@@ -105,11 +110,23 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
// 3001-VOTE-035
|
// 3001-VOTE-035
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getSubmittedProposalFromProposalList(rawProposal.rationale.title).within(
|
||||||
cy.get(viewProposalButton).should('be.visible');
|
() => {
|
||||||
cy.getByTestId(proposalType).should('have.text', 'Freeform');
|
cy.get(viewProposalButton).should('be.visible').click();
|
||||||
cy.getByTestId(proposalStatus).should('have.text', 'Open');
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('@proposalIdText').then((proposalId) => {
|
||||||
|
getProposalInformationFromTable('ID')
|
||||||
|
.contains(String(proposalId))
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
getProposalInformationFromTable('State')
|
||||||
|
.contains('Open')
|
||||||
|
.and('be.visible');
|
||||||
|
getProposalInformationFromTable('Type')
|
||||||
|
.contains('Freeform')
|
||||||
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -117,22 +134,18 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
it('Newly created freeform proposals list - shows proposal participation - both met and not', function () {
|
||||||
const proposalTitle = generateFreeFormProposalTitle();
|
const proposalTitle = generateFreeFormProposalTitle();
|
||||||
|
|
||||||
submitUniqueRawProposal({ proposalTitle: proposalTitle });
|
createFreeformProposal(proposalTitle);
|
||||||
getProposalFromTitle(proposalTitle).within(() => {
|
getSubmittedProposalFromProposalList(proposalTitle).within(() => {
|
||||||
// 3001-VOTE-039
|
// 3001-VOTE-039
|
||||||
cy.getByTestId(voteStatus).should(
|
cy.get(voteStatus).should('have.text', 'Participation not reached');
|
||||||
'have.text',
|
|
||||||
'Participation not reached'
|
|
||||||
);
|
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
voteForProposal('for');
|
voteForProposal('for');
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
getProposalFromTitle(proposalTitle).within(() => {
|
getSubmittedProposalFromProposalList(proposalTitle).within(() => {
|
||||||
cy.getByTestId(voteStatus).should('have.text', 'Set to pass');
|
cy.get(voteStatus).should('have.text', 'Set to pass');
|
||||||
cy.get(viewProposalButton).click();
|
cy.get(viewProposalButton).click();
|
||||||
});
|
});
|
||||||
cy.getByTestId(voteBreakDownToggle).click();
|
|
||||||
getProposalInformationFromTable('Token participation met')
|
getProposalInformationFromTable('Token participation met')
|
||||||
.contains('👍')
|
.contains('👍')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
clickOnValidatorFromList,
|
clickOnValidatorFromList,
|
||||||
closeStakingDialog,
|
closeStakingDialog,
|
||||||
|
stakingPageAssociateTokens,
|
||||||
stakingValidatorPageAddStake,
|
stakingValidatorPageAddStake,
|
||||||
waitForBeginningOfEpoch,
|
waitForBeginningOfEpoch,
|
||||||
} from '../../support/staking.functions';
|
} from '../../support/staking.functions';
|
||||||
@@ -14,7 +15,7 @@ import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
|||||||
import {
|
import {
|
||||||
depositAsset,
|
depositAsset,
|
||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const vegaAssetAddress = '0x67175Da1D5e966e40D11c4B2519392B2058373de';
|
const vegaAssetAddress = '0x67175Da1D5e966e40D11c4B2519392B2058373de';
|
||||||
const vegaWalletUnstakedBalance =
|
const vegaWalletUnstakedBalance =
|
||||||
@@ -29,22 +30,20 @@ context('rewards - flow', { tags: '@slow' }, function () {
|
|||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
|
depositAsset(vegaAssetAddress, '1000', 18);
|
||||||
|
cy.validatorsSelfDelegate();
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
depositAsset(vegaAssetAddress, '1000', 18);
|
cy.VegaWalletTopUpRewardsPool(30, 200);
|
||||||
cy.getByTestId('currency-title', txTimeout).should(
|
|
||||||
'contain.text',
|
|
||||||
'Collateral'
|
|
||||||
);
|
|
||||||
vegaWalletTeardown();
|
|
||||||
cy.associateTokensToVegaWallet('6000');
|
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
cy.VegaWalletTopUpRewardsPool();
|
vegaWalletTeardown();
|
||||||
|
stakingPageAssociateTokens('6000');
|
||||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
|
cy.get(vegaWalletUnstakedBalance, txTimeout).should(
|
||||||
'contain',
|
'contain',
|
||||||
'6,000.0',
|
'6,000.0',
|
||||||
txTimeout
|
txTimeout
|
||||||
);
|
);
|
||||||
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
clickOnValidatorFromList(0);
|
clickOnValidatorFromList(0);
|
||||||
stakingValidatorPageAddStake('3000');
|
stakingValidatorPageAddStake('3000');
|
||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {
|
|||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
turnTelemetryOff,
|
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import {
|
||||||
clickOnValidatorFromList,
|
clickOnValidatorFromList,
|
||||||
@@ -25,7 +24,7 @@ import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
|||||||
import {
|
import {
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
vegaWalletSetSpecifiedApprovalAmount,
|
||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-teardown.functions';
|
||||||
const stakeValidatorListTotalStake = 'total-stake';
|
const stakeValidatorListTotalStake = 'total-stake';
|
||||||
const stakeValidatorListTotalShare = 'total-stake-share';
|
const stakeValidatorListTotalShare = 'total-stake-share';
|
||||||
const stakeValidatorListStakePercentage = 'stake-percentage';
|
const stakeValidatorListStakePercentage = 'stake-percentage';
|
||||||
@@ -54,7 +53,7 @@ context(
|
|||||||
'Staking Tab - with eth and vega wallets connected',
|
'Staking Tab - with eth and vega wallets connected',
|
||||||
{ tags: '@slow' },
|
{ tags: '@slow' },
|
||||||
function () {
|
function () {
|
||||||
// 1002-STKE-002, 1002-STKE-032
|
// 2001-STKE-002, 2001-STKE-032
|
||||||
before('visit staking tab and connect vega wallet', function () {
|
before('visit staking tab and connect vega wallet', function () {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
@@ -68,7 +67,6 @@ context(
|
|||||||
'teardown wallet & drill into a specific validator',
|
'teardown wallet & drill into a specific validator',
|
||||||
function () {
|
function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
waitForSpinner();
|
waitForSpinner();
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
@@ -77,42 +75,26 @@ context(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 1002-STKE-035 1002-STKE-036
|
|
||||||
it('Unable to stake against a validator with less than minimum and more than associated amount', function () {
|
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('3');
|
|
||||||
verifyUnstakedBalance(3.0);
|
|
||||||
verifyEthWalletTotalAssociatedBalance('3.0');
|
|
||||||
verifyEthWalletAssociatedBalance('3.0');
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
|
||||||
clickOnValidatorFromList(0);
|
|
||||||
cy.getByTestId(stakeAddStakeRadioButton, epochTimeout).click({
|
|
||||||
force: true,
|
|
||||||
});
|
|
||||||
cy.getByTestId(stakeTokenAmountInputBox).type('0.001');
|
|
||||||
cy.getByTestId(stakeTokenSubmitButton).should('be.disabled');
|
|
||||||
cy.getByTestId(stakeTokenAmountInputBox).clear().type('4');
|
|
||||||
cy.getByTestId(stakeTokenSubmitButton).should('be.disabled');
|
|
||||||
});
|
|
||||||
it('Able to stake against a validator - using vega from wallet', function () {
|
it('Able to stake against a validator - using vega from wallet', function () {
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('3');
|
ensureSpecifiedUnstakedTokensAreAssociated('3');
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
verifyEthWalletTotalAssociatedBalance('3.0');
|
verifyEthWalletTotalAssociatedBalance('3.0');
|
||||||
verifyEthWalletAssociatedBalance('3.0');
|
verifyEthWalletAssociatedBalance('3.0');
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
// 1002-STKE-031
|
// 2001-STKE-031
|
||||||
clickOnValidatorFromList(0);
|
clickOnValidatorFromList(0);
|
||||||
// 1002-STKE-033, 1002-STKE-034, 1002-STKE-037
|
// 2001-STKE-033, 2001-STKE-034, 2001-STKE-037
|
||||||
stakingValidatorPageAddStake('2');
|
stakingValidatorPageAddStake('2');
|
||||||
verifyUnstakedBalance(1.0);
|
verifyUnstakedBalance(1.0);
|
||||||
// 1002-STKE-039
|
// 2001-STKE-039
|
||||||
verifyStakedBalance(2.0);
|
verifyStakedBalance(2.0);
|
||||||
verifyNextEpochValue(2.0); // 1002-STKE-016 1002-STKE-038
|
verifyNextEpochValue(2.0); // 2001-STKE-016 2001-STKE-038
|
||||||
verifyThisEpochValue(2.0); // 1002-STKE-013
|
verifyThisEpochValue(2.0); // 2001-STKE-013
|
||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
|
|
||||||
// 2002-SINC-007 1002-STKE-015 1002-STKE-017 1002-STKE-052
|
// 2002-SINC-007
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to view validators staked by me', function () {
|
it('Able to view validators staked by me', function () {
|
||||||
@@ -125,7 +107,6 @@ context(
|
|||||||
cy.getByTestId(userStake, epochTimeout)
|
cy.getByTestId(userStake, epochTimeout)
|
||||||
.first()
|
.first()
|
||||||
.should('have.text', '2.00');
|
.should('have.text', '2.00');
|
||||||
waitForBeginningOfEpoch();
|
|
||||||
cy.getByTestId('total-stake').first().realHover();
|
cy.getByTestId('total-stake').first().realHover();
|
||||||
cy.getByTestId('staked-by-user-tooltip')
|
cy.getByTestId('staked-by-user-tooltip')
|
||||||
.first()
|
.first()
|
||||||
@@ -163,7 +144,7 @@ context(
|
|||||||
verifyThisEpochValue(2.0);
|
verifyThisEpochValue(2.0);
|
||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to stake against a validator - using vega from both wallet and vesting contract', function () {
|
it('Able to stake against a validator - using vega from both wallet and vesting contract', function () {
|
||||||
@@ -183,11 +164,10 @@ context(
|
|||||||
verifyThisEpochValue(6.0);
|
verifyThisEpochValue(6.0);
|
||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,006.00', '50.05%');
|
validateValidatorListTotalStakeAndShare('0', '6.00', '100.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to stake against multiple validators', function () {
|
it('Able to stake against multiple validators', function () {
|
||||||
vegaWalletTeardown();
|
|
||||||
stakingPageAssociateTokens('5');
|
stakingPageAssociateTokens('5');
|
||||||
verifyUnstakedBalance(5.0);
|
verifyUnstakedBalance(5.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -215,10 +195,14 @@ context(
|
|||||||
.eq(1)
|
.eq(1)
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(stakeValidatorListTotalStake)
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
.should('have.text', '3,002.00')
|
.should('have.text', '2.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(stakeValidatorListTotalShare)
|
cy.getByTestId(stakeValidatorListTotalShare)
|
||||||
.should('have.text', '50.01%')
|
.should('have.text', '66.67%')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('have.text', '2.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
cy.get(`[row-id="${1}"]`)
|
cy.get(`[row-id="${1}"]`)
|
||||||
@@ -226,15 +210,19 @@ context(
|
|||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(stakeValidatorListTotalStake)
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('have.text', '3,001.00')
|
.should('have.text', '1.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
cy.getByTestId(stakeValidatorListTotalShare)
|
cy.getByTestId(stakeValidatorListTotalShare)
|
||||||
.should('have.text', '49.99%')
|
.should('have.text', '33.33%')
|
||||||
|
.and('be.visible');
|
||||||
|
cy.getByTestId(stakeValidatorListTotalStake)
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('have.text', '1.00')
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 1002-STKE-041 1002-STKE-053
|
// 2001-STKE-041
|
||||||
it(
|
it(
|
||||||
'Able to remove part of a stake against a validator',
|
'Able to remove part of a stake against a validator',
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
@@ -247,11 +235,11 @@ context(
|
|||||||
verifyUnstakedBalance(1.0);
|
verifyUnstakedBalance(1.0);
|
||||||
closeStakingDialog();
|
closeStakingDialog();
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
// 1002-STKE-040
|
// 2001-STKE-040
|
||||||
clickOnValidatorFromList(0);
|
clickOnValidatorFromList(0);
|
||||||
// 1002-STKE-044, 1002-STKE-048
|
// 2001-STKE-044, 2001-STKE-048
|
||||||
stakingValidatorPageRemoveStake('1');
|
stakingValidatorPageRemoveStake('1');
|
||||||
// 1002-STKE-049
|
// 2001-STKE-049
|
||||||
verifyNextEpochValue(2.0);
|
verifyNextEpochValue(2.0);
|
||||||
verifyUnstakedBalance(2.0);
|
verifyUnstakedBalance(2.0);
|
||||||
verifyStakedBalance(2.0);
|
verifyStakedBalance(2.0);
|
||||||
@@ -264,14 +252,14 @@ context(
|
|||||||
waitForBeginningOfEpoch();
|
waitForBeginningOfEpoch();
|
||||||
cy.getByTestId(stakeValidatorListStakePercentage).should(
|
cy.getByTestId(stakeValidatorListStakePercentage).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'50.02%'
|
'100%'
|
||||||
);
|
);
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 1002-STKE-045
|
// 2001-STKE-045
|
||||||
it('Able to remove a full stake against a validator', function () {
|
it('Able to remove a full stake against a validator', function () {
|
||||||
stakingPageAssociateTokens('3');
|
stakingPageAssociateTokens('3');
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
@@ -292,7 +280,7 @@ context(
|
|||||||
txTimeout
|
txTimeout
|
||||||
);
|
);
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,000.00', '50.00%');
|
validateValidatorListTotalStakeAndShare('0', '0.00', '0.00%');
|
||||||
|
|
||||||
cy.getByTestId(userStakeBtn).should('not.exist');
|
cy.getByTestId(userStakeBtn).should('not.exist');
|
||||||
cy.getByTestId(userStake).should('not.exist');
|
cy.getByTestId(userStake).should('not.exist');
|
||||||
@@ -319,7 +307,6 @@ context(
|
|||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
// 1002-STKE-046 1002-STKE-047
|
|
||||||
it('Unable to remove a stake greater than staked amount next epoch for a validator', function () {
|
it('Unable to remove a stake greater than staked amount next epoch for a validator', function () {
|
||||||
stakingPageAssociateTokens('3');
|
stakingPageAssociateTokens('3');
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
@@ -365,7 +352,7 @@ context(
|
|||||||
txTimeout
|
txTimeout
|
||||||
);
|
);
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,000.00', '50.00%');
|
validateValidatorListTotalStakeAndShare('0', '0.00', '0.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Disassociating all vesting contract tokens max - removes all staked tokens', function () {
|
it('Disassociating all vesting contract tokens max - removes all staked tokens', function () {
|
||||||
@@ -393,13 +380,10 @@ context(
|
|||||||
txTimeout
|
txTimeout
|
||||||
);
|
);
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,000.00', '50.00%');
|
validateValidatorListTotalStakeAndShare('0', '0.00', '0.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
|
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
|
||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
|
||||||
cy.reload();
|
|
||||||
ethereumWalletConnect();
|
|
||||||
stakingPageAssociateTokens('3');
|
stakingPageAssociateTokens('3');
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -418,11 +402,11 @@ context(
|
|||||||
});
|
});
|
||||||
verifyStakedBalance(2.0);
|
verifyStakedBalance(2.0);
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
validateValidatorListTotalStakeAndShare('0', '3,002.00', '50.02%');
|
validateValidatorListTotalStakeAndShare('0', '2.00', '100.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Associating wallet tokens - when some already staked - auto stakes tokens to staked validator', function () {
|
it('Associating wallet tokens - when some already staked - auto stakes tokens to staked validator', function () {
|
||||||
// 1002-STKE-004
|
// 2001-STKE-004
|
||||||
stakingPageAssociateTokens('3');
|
stakingPageAssociateTokens('3');
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -436,7 +420,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Associating vesting contract tokens - when some already staked - auto stakes tokens to staked validator', function () {
|
it('Associating vesting contract tokens - when some already staked - auto stakes tokens to staked validator', function () {
|
||||||
// 1002-STKE-004
|
// 2001-STKE-004
|
||||||
stakingPageAssociateTokens('3', { type: 'contract' });
|
stakingPageAssociateTokens('3', { type: 'contract' });
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -450,7 +434,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Associating vesting contract tokens - when wallet tokens already staked - auto stakes tokens to staked validator', function () {
|
it('Associating vesting contract tokens - when wallet tokens already staked - auto stakes tokens to staked validator', function () {
|
||||||
// 1002-STKE-004
|
// 2001-STKE-004
|
||||||
stakingPageAssociateTokens('3', { type: 'wallet' });
|
stakingPageAssociateTokens('3', { type: 'wallet' });
|
||||||
verifyUnstakedBalance(3.0);
|
verifyUnstakedBalance(3.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -464,7 +448,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Associating tokens - with multiple validators already staked - auto stakes to staked validators - abiding by existing stake ratio', function () {
|
it('Associating tokens - with multiple validators already staked - auto stakes to staked validators - abiding by existing stake ratio', function () {
|
||||||
// 1002-STKE-004
|
// 2001-STKE-004
|
||||||
stakingPageAssociateTokens('6');
|
stakingPageAssociateTokens('6');
|
||||||
verifyUnstakedBalance(6.0);
|
verifyUnstakedBalance(6.0);
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
@@ -506,7 +490,6 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach('Teardown Wallet', function () {
|
afterEach('Teardown Wallet', function () {
|
||||||
navigateTo(navigation.home);
|
|
||||||
vegaWalletTeardown();
|
vegaWalletTeardown();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -517,7 +500,7 @@ context(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function verifyThisEpochValue(amount: number) {
|
function verifyThisEpochValue(amount: number) {
|
||||||
cy.getByTestId('stake-this-epoch', epochTimeout) // 1002-STKE-013
|
cy.getByTestId('stake-this-epoch', epochTimeout) // 2001-STKE-013
|
||||||
.contains(amount, epochTimeout)
|
.contains(amount, epochTimeout)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,11 @@ import {
|
|||||||
} from '../../support/staking.functions';
|
} from '../../support/staking.functions';
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import {
|
import {
|
||||||
switchVegaWalletPubKey,
|
|
||||||
vegaWalletAssociate,
|
vegaWalletAssociate,
|
||||||
vegaWalletDisassociate,
|
vegaWalletDisassociate,
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
vegaWalletSetSpecifiedApprovalAmount,
|
||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const ethWalletContainer = '[data-testid="ethereum-wallet"]';
|
const ethWalletContainer = '[data-testid="ethereum-wallet"]';
|
||||||
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
const vegaWalletAssociatedBalance = '[data-testid="currency-value"]';
|
||||||
@@ -39,7 +38,7 @@ const associatedKey = '[data-testid="associated-key"]';
|
|||||||
const associatedAmount = '[data-testid="associated-amount"]';
|
const associatedAmount = '[data-testid="associated-amount"]';
|
||||||
const associateCompleteText = '[data-testid="transaction-complete-body"]';
|
const associateCompleteText = '[data-testid="transaction-complete-body"]';
|
||||||
const disassociationWarning = '[data-testid="disassociation-warning"]';
|
const disassociationWarning = '[data-testid="disassociation-warning"]';
|
||||||
const vegaWallet = 'aside [data-testid="vega-wallet"]';
|
const vegaWallet = '[data-testid="vega-wallet"]';
|
||||||
|
|
||||||
context(
|
context(
|
||||||
'Token association flow - with eth and vega wallets connected',
|
'Token association flow - with eth and vega wallets connected',
|
||||||
@@ -65,38 +64,46 @@ context(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it(
|
it('Able to associate tokens - from wallet', function () {
|
||||||
'Able to associate tokens - from wallet',
|
//1004-ASSO-003
|
||||||
{ tags: '@smoke' },
|
//1004-ASSO-005
|
||||||
function () {
|
//1004-ASSO-009
|
||||||
//1004-ASSO-003
|
//1004-ASSO-030
|
||||||
//1004-ASSO-005
|
//1004-ASSO-012
|
||||||
//1004-ASSO-009
|
//1004-ASSO-013
|
||||||
//1004-ASSO-030
|
//1004-ASSO-014
|
||||||
//1004-ASSO-012
|
//1004-ASSO-015
|
||||||
//1004-ASSO-013
|
//1004-ASSO-030
|
||||||
//1004-ASSO-014
|
//0005-ETXN-006
|
||||||
//1004-ASSO-015
|
//0005-ETXN-003
|
||||||
//1004-ASSO-030
|
//0005-ETXN-005
|
||||||
//0005-ETXN-006
|
stakingPageAssociateTokens('2', { skipConfirmation: true });
|
||||||
//0005-ETXN-003
|
|
||||||
//0005-ETXN-005
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
stakingPageAssociateTokens('2', { skipConfirmation: true });
|
'have.length.above',
|
||||||
validateWalletCurrency('Associated', '0.00');
|
6
|
||||||
validateWalletCurrency('Pending association', '2.00');
|
);
|
||||||
validateWalletCurrency('Total associated after pending', '2.00');
|
validateWalletCurrency('Associated', '0.00');
|
||||||
// 0005-ETXN-002
|
validateWalletCurrency('Pending association', '2.00');
|
||||||
verifyEthWalletAssociatedBalance('2.0');
|
validateWalletCurrency('Total associated after pending', '2.00');
|
||||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
cy.get(vegaWallet).within(() => {
|
|
||||||
|
// 0005-ETXN-002
|
||||||
|
verifyEthWalletAssociatedBalance('2.0');
|
||||||
|
|
||||||
|
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||||
|
|
||||||
|
cy.get(vegaWallet)
|
||||||
|
.first()
|
||||||
|
.within(() => {
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
'contain',
|
'contain',
|
||||||
2.0
|
2.0
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
|
||||||
}
|
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||||
);
|
});
|
||||||
|
|
||||||
it('Able to disassociate all associated tokens - manually', function () {
|
it('Able to disassociate all associated tokens - manually', function () {
|
||||||
// 1004-ASSO-025
|
// 1004-ASSO-025
|
||||||
@@ -104,48 +111,63 @@ context(
|
|||||||
// 1004-ASSO-028
|
// 1004-ASSO-028
|
||||||
// 1004-ASSO-029
|
// 1004-ASSO-029
|
||||||
// 1004-ASSO-031
|
// 1004-ASSO-031
|
||||||
vegaWalletTeardown();
|
|
||||||
stakingPageAssociateTokens('2');
|
stakingPageAssociateTokens('2');
|
||||||
verifyEthWalletAssociatedBalance('2.0');
|
verifyEthWalletAssociatedBalance('2.0');
|
||||||
verifyEthWalletTotalAssociatedBalance('6,002.00');
|
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
|
||||||
stakingPageDisassociateTokens('2');
|
stakingPageDisassociateTokens('2');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
6
|
||||||
|
);
|
||||||
validateWalletCurrency('Associated', '2.00');
|
validateWalletCurrency('Associated', '2.00');
|
||||||
validateWalletCurrency('Pending association', '2.00');
|
validateWalletCurrency('Pending association', '2.00');
|
||||||
validateWalletCurrency('Total associated after pending', '0.00');
|
validateWalletCurrency('Total associated after pending', '0.00');
|
||||||
cy.get(
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
'[data-testid="eth-wallet-associated-balances"]:visible',
|
cy.getByTestId('eth-wallet-associated-balances', txTimeout).should(
|
||||||
txTimeout
|
'not.exist'
|
||||||
).should('have.length', 2);
|
);
|
||||||
verifyEthWalletTotalAssociatedBalance('6,000.00');
|
verifyEthWalletTotalAssociatedBalance('0.00');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to associate more tokens than the approved amount of 1000 - requires re-approval', function () {
|
it('Able to associate more tokens than the approved amount of 1000 - requires re-approval', function () {
|
||||||
//1004-ASSO-011
|
//1004-ASSO-011
|
||||||
stakingPageAssociateTokens('1001', { approve: true });
|
stakingPageAssociateTokens('1001', { approve: true });
|
||||||
verifyEthWalletAssociatedBalance('1,001.00');
|
verifyEthWalletAssociatedBalance('1,001.00');
|
||||||
verifyEthWalletTotalAssociatedBalance('7,001.00');
|
verifyEthWalletTotalAssociatedBalance('1,001.00');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
.last()
|
||||||
'contain',
|
.within(() => {
|
||||||
'1,001.00'
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
);
|
'contain',
|
||||||
});
|
'1,001.00'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to disassociate a partial amount of tokens currently associated', function () {
|
it('Able to disassociate a partial amount of tokens currently associated', function () {
|
||||||
stakingPageAssociateTokens('2');
|
stakingPageAssociateTokens('2');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
2.0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
|
||||||
stakingPageDisassociateTokens('1');
|
stakingPageDisassociateTokens('1');
|
||||||
verifyEthWalletAssociatedBalance('1.0');
|
verifyEthWalletAssociatedBalance('1.0');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 1.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
1.0
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to disassociate all tokens - using max', function () {
|
it('Able to disassociate all tokens - using max', function () {
|
||||||
@@ -153,11 +175,15 @@ context(
|
|||||||
const warningText =
|
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.';
|
'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');
|
stakingPageAssociateTokens('2');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
2.0
|
||||||
|
);
|
||||||
|
});
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
|
||||||
cy.get(ethWalletDissociateButton).click();
|
cy.get(ethWalletDissociateButton).click();
|
||||||
cy.get(disassociationWarning).should('contain', warningText);
|
cy.get(disassociationWarning).should('contain', warningText);
|
||||||
stakingPageDisassociateAllTokens();
|
stakingPageDisassociateAllTokens();
|
||||||
@@ -175,9 +201,14 @@ context(
|
|||||||
'not.exist'
|
'not.exist'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 0.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to associate and disassociate vesting contract tokens', function () {
|
it('Able to associate and disassociate vesting contract tokens', function () {
|
||||||
@@ -192,22 +223,38 @@ context(
|
|||||||
type: 'contract',
|
type: 'contract',
|
||||||
skipConfirmation: true,
|
skipConfirmation: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
6
|
||||||
|
);
|
||||||
validateWalletCurrency('Associated', '0.00');
|
validateWalletCurrency('Associated', '0.00');
|
||||||
validateWalletCurrency('Pending association', '2.00');
|
validateWalletCurrency('Pending association', '2.00');
|
||||||
validateWalletCurrency('Total associated after pending', '2.00');
|
validateWalletCurrency('Total associated after pending', '2.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
verifyEthWalletAssociatedBalance('2.0');
|
verifyEthWalletAssociatedBalance('2.0');
|
||||||
verifyEthWalletTotalAssociatedBalance('2.0');
|
verifyEthWalletTotalAssociatedBalance('2.0');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
2.0
|
||||||
|
);
|
||||||
|
});
|
||||||
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
cy.get(vegaWalletUnstakedBalance, txTimeout).should('contain', 2.0);
|
||||||
stakingPageDisassociateTokens('1', {
|
stakingPageDisassociateTokens('1', {
|
||||||
type: 'contract',
|
type: 'contract',
|
||||||
skipConfirmation: true,
|
skipConfirmation: true,
|
||||||
});
|
});
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
6
|
||||||
|
);
|
||||||
validateWalletCurrency('Associated', '2.00');
|
validateWalletCurrency('Associated', '2.00');
|
||||||
validateWalletCurrency('Pending association', '1.00');
|
validateWalletCurrency('Pending association', '1.00');
|
||||||
validateWalletCurrency('Total associated after pending', '1.00');
|
validateWalletCurrency('Total associated after pending', '1.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
verifyEthWalletAssociatedBalance('1.0');
|
verifyEthWalletAssociatedBalance('1.0');
|
||||||
verifyEthWalletTotalAssociatedBalance('1.0');
|
verifyEthWalletTotalAssociatedBalance('1.0');
|
||||||
});
|
});
|
||||||
@@ -219,7 +266,6 @@ context(
|
|||||||
// 1004-ASSO-022
|
// 1004-ASSO-022
|
||||||
stakingPageAssociateTokens('21', { type: 'wallet' });
|
stakingPageAssociateTokens('21', { type: 'wallet' });
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.getByTestId('epoch-countdown').should('be.visible');
|
|
||||||
stakingPageAssociateTokens('37', { type: 'contract' });
|
stakingPageAssociateTokens('37', { type: 'contract' });
|
||||||
cy.get(vestingContractSection)
|
cy.get(vestingContractSection)
|
||||||
.first()
|
.first()
|
||||||
@@ -239,18 +285,28 @@ context(
|
|||||||
);
|
);
|
||||||
cy.get(associatedAmount, txTimeout).should('contain', 21);
|
cy.get(associatedAmount, txTimeout).should('contain', 21);
|
||||||
});
|
});
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 58);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
58
|
||||||
|
);
|
||||||
|
});
|
||||||
stakingPageDisassociateTokens('6', { type: 'contract' });
|
stakingPageDisassociateTokens('6', { type: 'contract' });
|
||||||
cy.get(vestingContractSection)
|
cy.get(vestingContractSection)
|
||||||
.first()
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(associatedAmount, txTimeout).should('contain', 31);
|
cy.get(associatedAmount, txTimeout).should('contain', 31);
|
||||||
});
|
});
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 52);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
52
|
||||||
|
);
|
||||||
|
});
|
||||||
navigateTo(navigation.validators);
|
navigateTo(navigation.validators);
|
||||||
stakingPageDisassociateTokens('9', { type: 'wallet' });
|
stakingPageDisassociateTokens('9', { type: 'wallet' });
|
||||||
cy.get(vegaInWalletSection)
|
cy.get(vegaInWalletSection)
|
||||||
@@ -258,9 +314,14 @@ context(
|
|||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get(associatedAmount, txTimeout).should('contain', 12);
|
cy.get(associatedAmount, txTimeout).should('contain', 12);
|
||||||
});
|
});
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 43);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
43
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Not able to associate more tokens than owned', function () {
|
it('Not able to associate more tokens than owned', function () {
|
||||||
@@ -277,9 +338,14 @@ context(
|
|||||||
// 1004-ASSO-004
|
// 1004-ASSO-004
|
||||||
it('Pending association outside of app is shown', function () {
|
it('Pending association outside of app is shown', function () {
|
||||||
vegaWalletAssociate('2');
|
vegaWalletAssociate('2');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
6
|
||||||
|
);
|
||||||
validateWalletCurrency('Associated', '0.00');
|
validateWalletCurrency('Associated', '0.00');
|
||||||
validateWalletCurrency('Pending association', '2.00');
|
validateWalletCurrency('Pending association', '2.00');
|
||||||
validateWalletCurrency('Total associated after pending', '2.00');
|
validateWalletCurrency('Total associated after pending', '2.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
validateWalletCurrency('Associated', '2.00');
|
validateWalletCurrency('Associated', '2.00');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -288,9 +354,14 @@ context(
|
|||||||
cy.wrap(validateWalletCurrency('Associated', '2.00')).then(() => {
|
cy.wrap(validateWalletCurrency('Associated', '2.00')).then(() => {
|
||||||
vegaWalletDisassociate('2');
|
vegaWalletDisassociate('2');
|
||||||
});
|
});
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should(
|
||||||
|
'have.length.above',
|
||||||
|
6
|
||||||
|
);
|
||||||
validateWalletCurrency('Associated', '2.00');
|
validateWalletCurrency('Associated', '2.00');
|
||||||
validateWalletCurrency('Pending association', '2.00');
|
validateWalletCurrency('Pending association', '2.00');
|
||||||
validateWalletCurrency('Total associated after pending', '0.00');
|
validateWalletCurrency('Total associated after pending', '0.00');
|
||||||
|
cy.getByTestId('currency-title', txTimeout).should('have.length', 6);
|
||||||
validateWalletCurrency('Associated', '0.00');
|
validateWalletCurrency('Associated', '0.00');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -302,15 +373,21 @@ context(
|
|||||||
Cypress.env('vegaWalletPublicKey')
|
Cypress.env('vegaWalletPublicKey')
|
||||||
);
|
);
|
||||||
|
|
||||||
switchVegaWalletPubKey();
|
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
||||||
|
cy.get('[data-testid="select-keypair-button"]').eq(0).click();
|
||||||
cy.get(connectedVegaKey).should(
|
cy.get(connectedVegaKey).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
Cypress.env('vegaWalletPublicKey2')
|
Cypress.env('vegaWalletPublicKey2')
|
||||||
);
|
);
|
||||||
stakingPageAssociateTokens('2');
|
stakingPageAssociateTokens('2');
|
||||||
cy.get(vegaWallet).within(() => {
|
cy.get(vegaWallet)
|
||||||
cy.get(vegaWalletAssociatedBalance, txTimeout).should('contain', 2.0);
|
.first()
|
||||||
});
|
.within(() => {
|
||||||
|
cy.get(vegaWalletAssociatedBalance, txTimeout).should(
|
||||||
|
'contain',
|
||||||
|
2.0
|
||||||
|
);
|
||||||
|
});
|
||||||
cy.get(associateCompleteText).should(
|
cy.get(associateCompleteText).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
`Vega key ${Cypress.env(
|
`Vega key ${Cypress.env(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
waitForSpinner,
|
waitForSpinner,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import { depositAsset } from '../../support/wallet-functions';
|
import { depositAsset } from '../../support/wallet-teardown.functions';
|
||||||
|
|
||||||
const withdraw = 'withdraw';
|
const withdraw = 'withdraw';
|
||||||
const withdrawalForm = 'withdraw-form';
|
const withdrawalForm = 'withdraw-form';
|
||||||
@@ -15,7 +15,13 @@ const balanceAvailable = 'BALANCE_AVAILABLE_value';
|
|||||||
const withdrawalThreshold = 'WITHDRAWAL_THRESHOLD_value';
|
const withdrawalThreshold = 'WITHDRAWAL_THRESHOLD_value';
|
||||||
const delayTime = 'DELAY_TIME_value';
|
const delayTime = 'DELAY_TIME_value';
|
||||||
const submitWithdrawalButton = 'submit-withdrawal';
|
const submitWithdrawalButton = 'submit-withdrawal';
|
||||||
|
const dialogTitle = 'dialog-title';
|
||||||
const dialogClose = 'dialog-close';
|
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 completeWithdrawalButton = 'complete-withdrawal';
|
||||||
const tableTxHash = '[col-id="txHash"]';
|
const tableTxHash = '[col-id="txHash"]';
|
||||||
const tableAssetSymbol = '[col-id="asset.symbol"]';
|
const tableAssetSymbol = '[col-id="asset.symbol"]';
|
||||||
@@ -24,16 +30,14 @@ const tableReceiverAddress = '[col-id="details.receiverAddress"]';
|
|||||||
const tableWithdrawnTimeStamp = '[col-id="withdrawnTimestamp"]';
|
const tableWithdrawnTimeStamp = '[col-id="withdrawnTimestamp"]';
|
||||||
const tableWithdrawnStatus = '[col-id="status"]';
|
const tableWithdrawnStatus = '[col-id="status"]';
|
||||||
const tableCreatedTimeStamp = '[col-id="createdTimestamp"]';
|
const tableCreatedTimeStamp = '[col-id="createdTimestamp"]';
|
||||||
const toast = 'toast';
|
const toastContent = 'toast-content';
|
||||||
const toastPanel = 'toast-panel';
|
const toastPanel = 'toast-panel';
|
||||||
const toastClose = 'toast-close';
|
|
||||||
const withdrawalDialogContent = 'dialog-content';
|
|
||||||
const toastCompleteWithdrawal = 'toast-complete-withdrawal';
|
|
||||||
const usdtName = 'USDC (local)';
|
const usdtName = 'USDC (local)';
|
||||||
const usdcEthAddress = '0x1b8a1B6CBE5c93609b46D1829Cc7f3Cb8eeE23a0';
|
const usdcEthAddress = '0x1b8a1B6CBE5c93609b46D1829Cc7f3Cb8eeE23a0';
|
||||||
const usdcSymbol = 'tUSDC';
|
const usdcSymbol = 'tUSDC';
|
||||||
const usdtSelectValue =
|
const usdtSelectValue =
|
||||||
'993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede';
|
'993ed98f4f770d91a796faab1738551193ba45c62341d20597df70fea6704ede';
|
||||||
|
const truncatedWithdrawalEthAddress = '0xEe7D…22d94F';
|
||||||
const formValidationError = 'input-error-text';
|
const formValidationError = 'input-error-text';
|
||||||
const txTimeout = Cypress.env('txTimeout');
|
const txTimeout = Cypress.env('txTimeout');
|
||||||
|
|
||||||
@@ -43,8 +47,11 @@ context(
|
|||||||
function () {
|
function () {
|
||||||
before('visit withdrawals and connect vega wallet', function () {
|
before('visit withdrawals and connect vega wallet', function () {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
ethereumWalletConnect();
|
// When running tests locally, will fail if run without restarting capsule
|
||||||
depositAsset(usdcEthAddress, '1000', 5);
|
cy.updateCapsuleMultiSig().then(() => {
|
||||||
|
ethereumWalletConnect();
|
||||||
|
depositAsset(usdcEthAddress, '1000', 5);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach('Navigate to withdrawal page', function () {
|
beforeEach('Navigate to withdrawal page', function () {
|
||||||
@@ -55,10 +62,6 @@ context(
|
|||||||
navigateTo(navigation.withdraw);
|
navigateTo(navigation.withdraw);
|
||||||
cy.connectVegaWallet();
|
cy.connectVegaWallet();
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
cy.getByTestId('currency-title', txTimeout).should(
|
|
||||||
'contain.text',
|
|
||||||
usdtName
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to open withdrawal form with vega wallet connected', function () {
|
it('Able to open withdrawal form with vega wallet connected', function () {
|
||||||
@@ -73,10 +76,7 @@ context(
|
|||||||
it('Unable to submit withdrawal with invalid fields', function () {
|
it('Unable to submit withdrawal with invalid fields', function () {
|
||||||
cy.getByTestId(withdraw).should('be.visible').click();
|
cy.getByTestId(withdraw).should('be.visible').click();
|
||||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||||
cy.getByTestId('select-asset').click();
|
cy.get('select').select(usdtSelectValue, { force: true });
|
||||||
cy.get('select')
|
|
||||||
.select(usdtSelectValue, { force: true })
|
|
||||||
.should('have.value', usdtSelectValue);
|
|
||||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||||
cy.getByTestId(submitWithdrawalButton).click();
|
cy.getByTestId(submitWithdrawalButton).click();
|
||||||
cy.getByTestId(formValidationError).should('have.length', 1);
|
cy.getByTestId(formValidationError).should('have.length', 1);
|
||||||
@@ -96,75 +96,62 @@ context(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('Able to withdraw asset: -eth wallet connected -withdraw funds button', function () {
|
||||||
'Able to withdraw asset: -eth wallet connected -withdraw funds button',
|
// fill in withdrawal form
|
||||||
{ tags: '@smoke' },
|
cy.getByTestId(withdraw).should('be.visible').click();
|
||||||
function () {
|
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||||
// fill in withdrawal form
|
cy.get('select').select(usdtSelectValue, { force: true });
|
||||||
cy.getByTestId(withdraw).should('be.visible').click();
|
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
cy.getByTestId(withdrawalThreshold).should(
|
||||||
cy.getByTestId('select-asset').click();
|
'have.text',
|
||||||
cy.get('select')
|
'100,000.00000T'
|
||||||
.select(usdtSelectValue, { force: true })
|
);
|
||||||
.should('have.value', usdtSelectValue);
|
cy.getByTestId(delayTime).should('have.text', 'None');
|
||||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
cy.getByTestId(amountInput).click().type('120');
|
||||||
cy.getByTestId(withdrawalThreshold).should(
|
cy.getByTestId(submitWithdrawalButton).click();
|
||||||
'have.text',
|
});
|
||||||
'100,000.00000T'
|
|
||||||
);
|
cy.contains('Awaiting network confirmation').should('be.visible');
|
||||||
cy.getByTestId(delayTime).should('have.text', 'None');
|
// assert withdrawal request
|
||||||
cy.getByTestId(amountInput).click().type('120');
|
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||||
cy.getByTestId(submitWithdrawalButton).click();
|
'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();
|
||||||
|
// withdrawal complete
|
||||||
|
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||||
|
'have.text',
|
||||||
|
'Withdraw asset complete'
|
||||||
|
);
|
||||||
|
cy.getByTestId(dialogClose).click();
|
||||||
|
// withdrawal history for complete withdrawal displayed
|
||||||
|
cy.get(tableWithdrawnStatus)
|
||||||
|
.eq(1, txTimeout)
|
||||||
|
.should('have.text', 'Completed')
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.get(tableAssetSymbol).should('have.text', usdcSymbol);
|
||||||
|
cy.get(tableAmount).should('have.text', '120.00');
|
||||||
|
cy.get(tableReceiverAddress)
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('contain', 'https://sepolia.etherscan.io/address/');
|
||||||
|
cy.get(tableWithdrawnTimeStamp).should('not.be.empty');
|
||||||
|
cy.get(tableTxHash)
|
||||||
|
.find('a')
|
||||||
|
.should('have.attr', 'href')
|
||||||
|
.and('contain', 'https://sepolia.etherscan.io/tx/');
|
||||||
});
|
});
|
||||||
// assert withdrawal request
|
});
|
||||||
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(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)
|
|
||||||
.should('have.text', 'Completed')
|
|
||||||
.parent()
|
|
||||||
.within(() => {
|
|
||||||
cy.get(tableAssetSymbol).should('have.text', usdcSymbol);
|
|
||||||
cy.get(tableAmount).should('have.text', '120.00');
|
|
||||||
cy.get(tableReceiverAddress)
|
|
||||||
.find('a')
|
|
||||||
.should('have.attr', 'href')
|
|
||||||
.and('contain', 'https://sepolia.etherscan.io/address/');
|
|
||||||
cy.get(tableWithdrawnTimeStamp).should('not.be.empty');
|
|
||||||
cy.get(tableTxHash)
|
|
||||||
.find('a')
|
|
||||||
.should('have.attr', 'href')
|
|
||||||
.and('contain', 'https://sepolia.etherscan.io/tx/');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it('Able to withdraw asset: -eth wallet not connected', function () {
|
it('Able to withdraw asset: -eth wallet not connected', function () {
|
||||||
const ethWalletAddress = Cypress.env('ethWalletPublicKey');
|
const ethWalletAddress = Cypress.env('ethWalletPublicKey');
|
||||||
@@ -173,10 +160,7 @@ context(
|
|||||||
// fill in withdrawal form
|
// fill in withdrawal form
|
||||||
cy.getByTestId(withdraw).should('be.visible').click();
|
cy.getByTestId(withdraw).should('be.visible').click();
|
||||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||||
cy.getByTestId('select-asset').click();
|
cy.get('select').select(usdtSelectValue, { force: true });
|
||||||
cy.get('select')
|
|
||||||
.select(usdtSelectValue, { force: true })
|
|
||||||
.should('have.value', usdtSelectValue);
|
|
||||||
cy.getByTestId(ethAddressInput).should('be.empty');
|
cy.getByTestId(ethAddressInput).should('be.empty');
|
||||||
cy.getByTestId(amountInput).click().type('110');
|
cy.getByTestId(amountInput).click().type('110');
|
||||||
cy.getByTestId(submitWithdrawalButton).click();
|
cy.getByTestId(submitWithdrawalButton).click();
|
||||||
@@ -187,17 +171,13 @@ context(
|
|||||||
cy.getByTestId(submitWithdrawalButton).click();
|
cy.getByTestId(submitWithdrawalButton).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.getByTestId(toast)
|
cy.contains('Awaiting network confirmation').should('be.visible');
|
||||||
.first(txTimeout)
|
// assert withdrawal request
|
||||||
.should('contain.text', 'Funds unlocked')
|
cy.getByTestId(dialogTitle, txTimeout).should(
|
||||||
.within(() => {
|
'have.text',
|
||||||
cy.getByTestId('external-link').should('exist');
|
'Transaction complete'
|
||||||
cy.getByTestId(toastPanel).should(
|
);
|
||||||
'contain.text',
|
cy.getByTestId(dialogClose).click();
|
||||||
'Withdraw 110.00 tUSDC'
|
|
||||||
);
|
|
||||||
cy.getByTestId(toastClose).click();
|
|
||||||
});
|
|
||||||
cy.get(tableTxHash)
|
cy.get(tableTxHash)
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.should('have.text', 'Complete withdrawal')
|
.should('have.text', 'Complete withdrawal')
|
||||||
@@ -212,78 +192,28 @@ context(
|
|||||||
cy.get(tableCreatedTimeStamp).should('not.be.empty');
|
cy.get(tableCreatedTimeStamp).should('not.be.empty');
|
||||||
});
|
});
|
||||||
ethereumWalletConnect();
|
ethereumWalletConnect();
|
||||||
cy.getByTestId(completeWithdrawalButton).first().click();
|
cy.getByTestId(completeWithdrawalButton).click();
|
||||||
cy.getByTestId(toast)
|
cy.getByTestId(toastContent)
|
||||||
.last(txTimeout)
|
.last()
|
||||||
.should('contain.text', 'Awaiting confirmation')
|
.should('contain.text', 'Awaiting confirmation')
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId('external-link').should('exist');
|
cy.getByTestId('external-link').should('exist');
|
||||||
});
|
});
|
||||||
cy.getByTestId(toast)
|
cy.getByTestId(toastContent)
|
||||||
.first(txTimeout)
|
.first()
|
||||||
.should('contain.text', 'The withdrawal has been approved.')
|
.should('contain.text', 'The withdrawal has been approved.')
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId(toastPanel).should('contain.text', '110.00', 'tUSDC');
|
cy.getByTestId(toastPanel).should('contain.text', '110.00', 'tUSDC');
|
||||||
});
|
});
|
||||||
cy.getByTestId(toast)
|
cy.getByTestId(toastContent)
|
||||||
.last(txTimeout)
|
.last()
|
||||||
.should('contain.text', 'Transaction confirmed')
|
.should('contain.text', 'Transaction confirmed')
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId('external-link').should('exist');
|
cy.getByTestId('external-link').should('exist');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should be able to see withdrawal details from toast', function () {
|
it('Unable to withdraw asset on pub key view', function () {
|
||||||
cy.getByTestId(withdraw).click();
|
|
||||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
|
||||||
cy.getByTestId('select-asset').click();
|
|
||||||
cy.get('select')
|
|
||||||
.select(usdtSelectValue, { force: true })
|
|
||||||
.should('have.value', usdtSelectValue);
|
|
||||||
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 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.`;
|
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.`;
|
||||||
|
|
||||||
@@ -294,17 +224,13 @@ context(
|
|||||||
cy.connectPublicKey(vegaWalletPubKey);
|
cy.connectPublicKey(vegaWalletPubKey);
|
||||||
cy.getByTestId(withdraw).should('be.visible').click();
|
cy.getByTestId(withdraw).should('be.visible').click();
|
||||||
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
cy.getByTestId(withdrawalForm, txTimeout).within(() => {
|
||||||
cy.getByTestId('select-asset').click();
|
cy.get('select').select(usdtSelectValue, { force: true });
|
||||||
cy.get('select')
|
|
||||||
.select(usdtSelectValue, { force: true })
|
|
||||||
.should('have.value', usdtSelectValue);
|
|
||||||
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
cy.getByTestId(balanceAvailable, txTimeout).should('exist');
|
||||||
cy.getByTestId(amountInput).click().type('100');
|
cy.getByTestId(amountInput).click().type('100');
|
||||||
cy.pause();
|
|
||||||
cy.getByTestId(submitWithdrawalButton).click();
|
cy.getByTestId(submitWithdrawalButton).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.getByTestId(withdrawalDialogContent)
|
cy.getByTestId('dialog-content')
|
||||||
.last()
|
.last()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get('h1').should('have.text', 'Transaction failed');
|
cy.get('h1').should('have.text', 'Transaction failed');
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
import { mockNetworkUpgradeProposal } from '../../support/proposal.functions';
|
import { mockNetworkUpgradeProposal } from '../../support/proposal.functions';
|
||||||
|
|
||||||
const proposalDocumentationLink = '[data-testid="proposal-documentation-link"]';
|
const proposalDocumentationLink = '[data-testid="proposal-documentation-link"]';
|
||||||
|
const newProposalLink = '[data-testid="new-proposal-link"]';
|
||||||
const governanceDocsUrl = 'https://vega.xyz/governance';
|
const governanceDocsUrl = 'https://vega.xyz/governance';
|
||||||
const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
const connectToVegaWalletButton = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||||
|
|
||||||
@@ -31,14 +32,6 @@ context(
|
|||||||
verifyPageHeader('Proposals');
|
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 () {
|
it('should be able to see a working link for - find out more about Vega governance', function () {
|
||||||
// 3001-VOTE-001
|
// 3001-VOTE-001
|
||||||
cy.get(proposalDocumentationLink)
|
cy.get(proposalDocumentationLink)
|
||||||
@@ -61,62 +54,17 @@ context(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3007-PNE-021
|
it.skip('should be able to see button for - new proposal', function () {
|
||||||
it('should have documentation links for network parameter proposal', function () {
|
// 3001-VOTE-002
|
||||||
|
cy.get(newProposalLink)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'New proposal')
|
||||||
|
.and('have.attr', 'href')
|
||||||
|
.and('equal', '/proposals/propose');
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
goToMakeNewProposal(governanceProposalType.NETWORK_PARAMETER);
|
||||||
cy.getByTestId('proposal-docs-link')
|
|
||||||
.find('a')
|
|
||||||
.should('have.attr', 'href')
|
|
||||||
.and('contain', '/tutorials/proposals/network-parameter-proposal');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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)
|
cy.get(connectToVegaWalletButton)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Vega wallet');
|
.and('have.text', 'Connect Vega wallet');
|
||||||
@@ -161,7 +109,7 @@ context(
|
|||||||
);
|
);
|
||||||
cy.getByTestId('protocol-upgrade-proposal-status').should(
|
cy.getByTestId('protocol-upgrade-proposal-status').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Approved by validators '
|
'Approved '
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -180,7 +128,6 @@ context(
|
|||||||
.first()
|
.first()
|
||||||
.find('[data-testid="view-proposal-btn"]')
|
.find('[data-testid="view-proposal-btn"]')
|
||||||
.click();
|
.click();
|
||||||
cy.url().should('contain', '/protocol-upgrades/v1');
|
|
||||||
cy.getByTestId('protocol-upgrade-proposal').within(() => {
|
cy.getByTestId('protocol-upgrade-proposal').within(() => {
|
||||||
cy.get('h1').should('have.text', 'Vega Release v1');
|
cy.get('h1').should('have.text', 'Vega Release v1');
|
||||||
cy.getByTestId('protocol-upgrade-block-height').should(
|
cy.getByTestId('protocol-upgrade-block-height').should(
|
||||||
@@ -189,7 +136,7 @@ context(
|
|||||||
);
|
);
|
||||||
cy.getByTestId('protocol-upgrade-state').should(
|
cy.getByTestId('protocol-upgrade-state').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Approved by validators'
|
'Approved'
|
||||||
);
|
);
|
||||||
cy.getByTestId('protocol-upgrade-release-tag').should(
|
cy.getByTestId('protocol-upgrade-release-tag').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
|
|||||||
@@ -9,9 +9,8 @@ import {
|
|||||||
import {
|
import {
|
||||||
enterUniqueFreeFormProposalBody,
|
enterUniqueFreeFormProposalBody,
|
||||||
goToMakeNewProposal,
|
goToMakeNewProposal,
|
||||||
governanceProposalType,
|
|
||||||
} from '../../support/governance.functions';
|
} from '../../support/governance.functions';
|
||||||
import { vegaWalletFaucetAssetsWithoutCheck } from '../../support/wallet-functions';
|
import { vegaWalletFaucetAssetsWithoutCheck } from '../../support/wallet-vega.functions';
|
||||||
|
|
||||||
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey2');
|
const vegaWalletPubKey = Cypress.env('vegaWalletPublicKey2');
|
||||||
const vegaPubkeyTruncated = Cypress.env('vegaWalletPublicKey2Short');
|
const vegaPubkeyTruncated = Cypress.env('vegaWalletPublicKey2Short');
|
||||||
@@ -51,7 +50,7 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
|||||||
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.`;
|
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.`;
|
||||||
|
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
goToMakeNewProposal(governanceProposalType.FREEFORM);
|
goToMakeNewProposal('Freeform');
|
||||||
enterUniqueFreeFormProposalBody('50', 'pub key proposal test');
|
enterUniqueFreeFormProposalBody('50', 'pub key proposal test');
|
||||||
cy.getByTestId('dialog-content')
|
cy.getByTestId('dialog-content')
|
||||||
.first()
|
.first()
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ context(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have option to go to last and newest page', function () {
|
it('should have option to go to last and newest page', function () {
|
||||||
|
waitForBeginningOfEpoch();
|
||||||
cy.getByTestId('goto-last-page').click();
|
cy.getByTestId('goto-last-page').click();
|
||||||
cy.getByTestId('epoch-total-rewards-table')
|
cy.getByTestId('epoch-total-rewards-table')
|
||||||
.last()
|
.last()
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import {
|
|||||||
verifyPageHeader,
|
verifyPageHeader,
|
||||||
verifyTabHighlighted,
|
verifyTabHighlighted,
|
||||||
} from '../../support/common.functions';
|
} from '../../support/common.functions';
|
||||||
import {
|
import { clickOnValidatorFromList } from '../../support/staking.functions';
|
||||||
clickOnValidatorFromList,
|
|
||||||
waitForBeginningOfEpoch,
|
|
||||||
} from '../../support/staking.functions';
|
|
||||||
|
|
||||||
const guideLink = '[data-testid="staking-guide-link"]';
|
const guideLink = '[data-testid="staking-guide-link"]';
|
||||||
const validatorTitle = '[data-testid="validator-node-title"]';
|
const validatorTitle = '[data-testid="validator-node-title"]';
|
||||||
@@ -32,7 +29,7 @@ const performancePenaltyToolTip = '[data-testid="performance-penalty-tooltip"]';
|
|||||||
const overstakedPenaltyToolTip = '[data-testid="overstaked-penalty-tooltip"]';
|
const overstakedPenaltyToolTip = '[data-testid="overstaked-penalty-tooltip"]';
|
||||||
const totalPenaltyToolTip = '[data-testid="total-penalty-tooltip"]';
|
const totalPenaltyToolTip = '[data-testid="total-penalty-tooltip"]';
|
||||||
const epochCountDown = '[data-testid="epoch-countdown"]';
|
const epochCountDown = '[data-testid="epoch-countdown"]';
|
||||||
const stakeNumberRegex = /^\d{1,3}(,\d{3})*(\.\d+)?$/;
|
const stakeNumberRegex = /^\d*\.?\d*$/;
|
||||||
|
|
||||||
context('Validators Page - verify elements on page', function () {
|
context('Validators Page - verify elements on page', function () {
|
||||||
before('navigate to validators page', function () {
|
before('navigate to validators page', function () {
|
||||||
@@ -40,213 +37,206 @@ context('Validators Page - verify elements on page', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
||||||
it('Should have validators tab highlighted', function () {
|
describe('description section', function () {
|
||||||
verifyTabHighlighted(navigation.validators);
|
it('Should have validators tab highlighted', function () {
|
||||||
|
verifyTabHighlighted(navigation.validators);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should have validators ON VEGA header visible', function () {
|
||||||
|
verifyPageHeader('Validators');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should have Staking Guide link visible', function () {
|
||||||
|
// 2001-STKE-003
|
||||||
|
cy.get(guideLink)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Read more about staking on Vega')
|
||||||
|
.and(
|
||||||
|
'have.attr',
|
||||||
|
'href',
|
||||||
|
'https://docs.vega.xyz/mainnet/concepts/vega-chain/#staking-on-vega'
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
describe(
|
||||||
it('Should have validators ON VEGA header visible', function () {
|
'Should be able to see validator list from the staking page',
|
||||||
verifyPageHeader('Validators');
|
{ tags: '@regression' },
|
||||||
});
|
function () {
|
||||||
|
// 2001-STKE-050
|
||||||
it('Should have Staking Guide link visible', function () {
|
it('Should be able to see validator names', function () {
|
||||||
// 1002-STKE-003
|
cy.get('[col-id="validator"] > div > span')
|
||||||
cy.get(guideLink)
|
.should('have.length.at.least', 1)
|
||||||
.should('be.visible')
|
.each(($name) => {
|
||||||
.and('have.text', 'Read more about staking on Vega')
|
cy.wrap($name).should('not.be.empty');
|
||||||
.and(
|
});
|
||||||
'have.attr',
|
|
||||||
'href',
|
|
||||||
'https://docs.vega.xyz/mainnet/concepts/vega-chain/#staking-on-vega'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-032
|
|
||||||
it('Should have button to connect vega wallet in validator page', function () {
|
|
||||||
clickOnValidatorFromList(0);
|
|
||||||
cy.getByTestId('connect-to-vega-wallet-btn').should('be.visible');
|
|
||||||
cy.visit('/validators');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// 1002-STKE-020 1002-STKE-021 1002-STKE-022 1002-STKE-023 1002-STKE-024
|
|
||||||
describe(
|
|
||||||
'Should be able to see validator list from the staking page',
|
|
||||||
{ tags: '@regression' },
|
|
||||||
function () {
|
|
||||||
// 1002-STKE-050
|
|
||||||
it('Should be able to see validator names', function () {
|
|
||||||
cy.get('[col-id="validator"] > div > span')
|
|
||||||
.should('have.length.at.least', 1)
|
|
||||||
.each(($name) => {
|
|
||||||
cy.wrap($name).should('not.be.empty');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator stake', function () {
|
|
||||||
cy.getByTestId('total-stake')
|
|
||||||
.should('have.length.at.least', 1)
|
|
||||||
.each(($stake) => {
|
|
||||||
cy.wrap($stake).should('not.be.empty');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator stake tooltip', function () {
|
|
||||||
waitForBeginningOfEpoch();
|
|
||||||
cy.getByTestId('total-stake').first().realHover();
|
|
||||||
|
|
||||||
cy.get(stakedByOperatorToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Staked by operator: 3,000.00');
|
|
||||||
cy.get(stakedByDelegatesToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Staked by delegates: 0.00');
|
|
||||||
cy.get(totalStakedToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Total stake: 3,000.00');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator normalised voting power', function () {
|
|
||||||
cy.getByTestId('normalised-voting-power')
|
|
||||||
.should('have.length.at.least', 1)
|
|
||||||
.each(($vPower) => {
|
|
||||||
cy.wrap($vPower).should('not.be.empty');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator normalised voting power tooltip', function () {
|
|
||||||
waitForBeginningOfEpoch();
|
|
||||||
cy.getByTestId('normalised-voting-power').first().realHover();
|
|
||||||
|
|
||||||
cy.get(unnormalisedVotingPowerToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Unnormalised voting power: 20.00%');
|
|
||||||
cy.get(normalisedVotingPowerToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Normalised voting power: 50.00%');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2002-SINC-018
|
|
||||||
it('Should be able to see validator total penalties', function () {
|
|
||||||
cy.getByTestId('total-penalty')
|
|
||||||
.should('have.length.at.least', 1)
|
|
||||||
.each(($penalties) => {
|
|
||||||
cy.wrap($penalties).should('contain.text', '0%');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator penalties tooltip', function () {
|
|
||||||
waitForBeginningOfEpoch();
|
|
||||||
cy.getByTestId('total-penalty').realHover();
|
|
||||||
|
|
||||||
cy.get(performancePenaltyToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Performance penalty: 0.00%');
|
|
||||||
cy.get(overstakedPenaltyToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Overstaked penalty: 60.00%'); // value not asserted due to #2886
|
|
||||||
cy.get(totalPenaltyToolTip)
|
|
||||||
.invoke('text')
|
|
||||||
.should('contain', 'Total penalties: 60.00%');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see validator pending stake', function () {
|
|
||||||
cy.getByTestId('total-pending-stake')
|
|
||||||
.should('have.length.at.least', 1)
|
|
||||||
.each(($pendingStake) => {
|
|
||||||
cy.wrap($pendingStake).should('contain.text', '0.00');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 1002-STKE-050
|
|
||||||
describe(
|
|
||||||
'Should be able to see static information about a validator',
|
|
||||||
{ tags: '@smoke' },
|
|
||||||
function () {
|
|
||||||
before('connect wallets and click on validator', function () {
|
|
||||||
cy.connectVegaWallet();
|
|
||||||
clickOnValidatorFromList(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-006
|
|
||||||
it('Should be able to see validator name', function () {
|
|
||||||
cy.get(validatorTitle).should('not.be.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-007
|
|
||||||
it('Should be able to see validator id', function () {
|
|
||||||
cy.get(validatorId).should('not.be.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-008
|
|
||||||
it('Should be able to see validator public key', function () {
|
|
||||||
cy.get(validatorPubKey).should('not.be.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-010
|
|
||||||
it('Should be able to see Ethereum address', function () {
|
|
||||||
cy.get(ethAddressLink).should('not.be.empty').and('have.attr', 'href');
|
|
||||||
});
|
|
||||||
// TODO validators missing url for more information about them 1002-STKE-09
|
|
||||||
|
|
||||||
it('Should be able to see validator status', function () {
|
|
||||||
cy.get(validatorStatus).should('have.text', 'Consensus');
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-012
|
|
||||||
it('Should be able to see total stake', function () {
|
|
||||||
cy.get(totalStake).invoke('text').should('match', stakeNumberRegex);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see pending stake', function () {
|
|
||||||
cy.get(pendingStake).invoke('text').should('match', stakeNumberRegex);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see staked by operator', function () {
|
|
||||||
cy.get(stakedByOperator)
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', stakeNumberRegex);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should be able to see staked by delegates', function () {
|
|
||||||
cy.get(stakedByDelegates)
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', stakeNumberRegex);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-051
|
|
||||||
it('Should be able to see stake share in percentage', function () {
|
|
||||||
cy.get(stakeShare)
|
|
||||||
.invoke('text')
|
|
||||||
.then(($stakePercentage) => {
|
|
||||||
// The pattern must start at a word boundary (\b).
|
|
||||||
// The pattern cannot be immediately preceded by a dot ((?<!\.)).
|
|
||||||
// The pattern can be one of the following:
|
|
||||||
// A percentage value of zero (0%), or
|
|
||||||
// A non-zero percentage value that can be:
|
|
||||||
// A single digit (\d) between 0 and 9, or
|
|
||||||
// A two-digit number between 0 and 99 (\d{1,2}), or
|
|
||||||
// The number 100.
|
|
||||||
// The pattern can optionally include a decimal point and one or more digits after the decimal point ((?:(?<!100)\.\d+)?). However, if the number is 100, it cannot have a decimal point.
|
|
||||||
// The pattern must end with a percentage sign (%).
|
|
||||||
|
|
||||||
cy.wrap($stakePercentage).should(
|
|
||||||
'match',
|
|
||||||
/\b(?<!\.)(?:0+(?:\.0+)?%|(?:\d|\d{1,2}|100)(?:(?<!100)\.\d+)?)%/
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 1002-STKE-011 2002-SINC-001 2002-SINC-002
|
|
||||||
it('Should be able to see epoch information', function () {
|
|
||||||
const epochTitle = 'h3';
|
|
||||||
const nextEpochInfo = 'p';
|
|
||||||
|
|
||||||
cy.get(epochCountDown).within(() => {
|
|
||||||
cy.get(epochTitle).should('not.be.empty');
|
|
||||||
cy.get(nextEpochInfo).should('contain.text', 'Next epoch');
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
it('Should be able to see validator stake', function () {
|
||||||
);
|
cy.getByTestId('total-stake')
|
||||||
|
.should('have.length.at.least', 1)
|
||||||
|
.each(($stake) => {
|
||||||
|
cy.wrap($stake).should('not.be.empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see validator stake tooltip', function () {
|
||||||
|
cy.getByTestId('total-stake').first().realHover();
|
||||||
|
|
||||||
|
cy.get(stakedByOperatorToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Staked by operator: 0.00');
|
||||||
|
cy.get(stakedByDelegatesToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Staked by delegates: 0.00');
|
||||||
|
cy.get(totalStakedToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Total stake: 0.00');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see validator normalised voting power', function () {
|
||||||
|
cy.getByTestId('normalised-voting-power')
|
||||||
|
.should('have.length.at.least', 1)
|
||||||
|
.each(($vPower) => {
|
||||||
|
cy.wrap($vPower).should('not.be.empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see validator normalised voting power tooltip', function () {
|
||||||
|
cy.getByTestId('normalised-voting-power').first().realHover();
|
||||||
|
|
||||||
|
cy.get(unnormalisedVotingPowerToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Unnormalised voting power: 0.00%');
|
||||||
|
cy.get(normalisedVotingPowerToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Normalised voting power: 0.10%');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2002-SINC-018
|
||||||
|
it('Should be able to see validator total penalties', function () {
|
||||||
|
cy.getByTestId('total-penalty')
|
||||||
|
.should('have.length.at.least', 1)
|
||||||
|
.each(($penalties) => {
|
||||||
|
cy.wrap($penalties).should('contain.text', '0%');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see validator penalties tooltip', function () {
|
||||||
|
cy.getByTestId('total-penalty').realHover();
|
||||||
|
|
||||||
|
cy.get(performancePenaltyToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Performance penalty: 100.00%');
|
||||||
|
cy.get(overstakedPenaltyToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Overstaked penalty:'); // value not asserted due to #2886
|
||||||
|
cy.get(totalPenaltyToolTip)
|
||||||
|
.invoke('text')
|
||||||
|
.should('contain', 'Total penalties: 0.00%');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see validator pending stake', function () {
|
||||||
|
cy.getByTestId('total-pending-stake')
|
||||||
|
.should('have.length.at.least', 1)
|
||||||
|
.each(($pendingStake) => {
|
||||||
|
cy.wrap($pendingStake).should('contain.text', '0.00');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2001-STKE-050
|
||||||
|
describe(
|
||||||
|
'Should be able to see static information about a validator',
|
||||||
|
{ tags: '@smoke' },
|
||||||
|
function () {
|
||||||
|
before('connect wallets and click on validator', function () {
|
||||||
|
cy.connectVegaWallet();
|
||||||
|
clickOnValidatorFromList(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-006
|
||||||
|
it('Should be able to see validator name', function () {
|
||||||
|
cy.get(validatorTitle).should('not.be.empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-007
|
||||||
|
it('Should be able to see validator id', function () {
|
||||||
|
cy.get(validatorId).should('not.be.empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-008
|
||||||
|
it('Should be able to see validator public key', function () {
|
||||||
|
cy.get(validatorPubKey).should('not.be.empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-010
|
||||||
|
it('Should be able to see Ethereum address', function () {
|
||||||
|
cy.get(ethAddressLink)
|
||||||
|
.should('not.be.empty')
|
||||||
|
.and('have.attr', 'href');
|
||||||
|
});
|
||||||
|
// TODO validators missing url for more information about them 2001-STKE-09
|
||||||
|
|
||||||
|
it('Should be able to see validator status', function () {
|
||||||
|
cy.get(validatorStatus).should('have.text', 'Consensus');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-012
|
||||||
|
it('Should be able to see total stake', function () {
|
||||||
|
cy.get(totalStake).invoke('text').should('match', stakeNumberRegex);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see pending stake', function () {
|
||||||
|
cy.get(pendingStake).invoke('text').should('match', stakeNumberRegex);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see staked by operator', function () {
|
||||||
|
cy.get(stakedByOperator)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', stakeNumberRegex);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should be able to see staked by delegates', function () {
|
||||||
|
cy.get(stakedByDelegates)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', stakeNumberRegex);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-051
|
||||||
|
it('Should be able to see stake share in percentage', function () {
|
||||||
|
cy.get(stakeShare)
|
||||||
|
.invoke('text')
|
||||||
|
.then(($stakePercentage) => {
|
||||||
|
// The pattern must start at a word boundary (\b).
|
||||||
|
// The pattern cannot be immediately preceded by a dot ((?<!\.)).
|
||||||
|
// The pattern can be one of the following:
|
||||||
|
// A percentage value of zero (0%), or
|
||||||
|
// A non-zero percentage value that can be:
|
||||||
|
// A single digit (\d) between 0 and 9, or
|
||||||
|
// A two-digit number between 0 and 99 (\d{1,2}), or
|
||||||
|
// The number 100.
|
||||||
|
// The pattern can optionally include a decimal point and one or more digits after the decimal point ((?:(?<!100)\.\d+)?). However, if the number is 100, it cannot have a decimal point.
|
||||||
|
// The pattern must end with a percentage sign (%).
|
||||||
|
|
||||||
|
cy.wrap($stakePercentage).should(
|
||||||
|
'match',
|
||||||
|
/\b(?<!\.)(?:0+(?:\.0+)?%|(?:\d|\d{1,2}|100)(?:(?<!100)\.\d+)?)%/
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2001-STKE-011 2002-SINC-001 2002-SINC-002
|
||||||
|
it('Should be able to see epoch information', function () {
|
||||||
|
const epochTitle = 'h3';
|
||||||
|
const nextEpochInfo = 'p';
|
||||||
|
|
||||||
|
cy.get(epochCountDown).within(() => {
|
||||||
|
cy.get(epochTitle).should('not.be.empty');
|
||||||
|
cy.get(nextEpochInfo).should('contain.text', 'Next epoch');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { truncateByChars } from '@vegaprotocol/utils';
|
import { truncateByChars } from '@vegaprotocol/utils';
|
||||||
import { waitForSpinner } from '../../support/common.functions';
|
import { waitForSpinner } from '../../support/common.functions';
|
||||||
import {
|
import { vegaWalletTeardown } from '../../support/wallet-teardown.functions';
|
||||||
vegaWalletFaucetAssetsWithoutCheck,
|
import { vegaWalletFaucetAssetsWithoutCheck } from '../../support/wallet-vega.functions';
|
||||||
vegaWalletTeardown,
|
|
||||||
} from '../../support/wallet-functions';
|
|
||||||
|
|
||||||
const walletContainer = 'aside [data-testid="vega-wallet"]';
|
const walletContainer = 'aside [data-testid="vega-wallet"]';
|
||||||
const walletHeader = '[data-testid="wallet-header"] h1';
|
const walletHeader = '[data-testid="wallet-header"] h1';
|
||||||
@@ -339,7 +337,6 @@ context(
|
|||||||
.parent()
|
.parent()
|
||||||
.siblings()
|
.siblings()
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('have.length.at.least', 4)
|
|
||||||
.then(parseFloat)
|
.then(parseFloat)
|
||||||
.should('be.gte', parseFloat(expectedAmount));
|
.should('be.gte', parseFloat(expectedAmount));
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import { stakingPageDisassociateAllTokens } from './staking.functions';
|
|
||||||
|
|
||||||
const tokenDropDown = 'state-trigger';
|
const tokenDropDown = 'state-trigger';
|
||||||
const txTimeout = Cypress.env('txTimeout');
|
const txTimeout = Cypress.env('txTimeout');
|
||||||
|
|
||||||
export enum navigation {
|
export enum navigation {
|
||||||
section = 'nav',
|
section = 'nav',
|
||||||
home = '[href="/"]',
|
|
||||||
vesting = '[href="/token/redeem"]',
|
vesting = '[href="/token/redeem"]',
|
||||||
validators = '[href="/validators"]',
|
validators = '[href="/validators"]',
|
||||||
rewards = '[href="/rewards"]',
|
rewards = '[href="/rewards"]',
|
||||||
@@ -21,7 +18,6 @@ export function convertTokenValueToNumber(subject: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const topLevelRoutes = [
|
const topLevelRoutes = [
|
||||||
navigation.home,
|
|
||||||
navigation.proposals,
|
navigation.proposals,
|
||||||
navigation.validators,
|
navigation.validators,
|
||||||
navigation.rewards,
|
navigation.rewards,
|
||||||
@@ -101,25 +97,3 @@ export function turnTelemetryOff() {
|
|||||||
win.localStorage.setItem('vega_telemetry_on', 'false')
|
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import {
|
import { closeDialog, navigateTo, navigation } from './common.functions';
|
||||||
closeDialog,
|
|
||||||
navigateTo,
|
|
||||||
navigation,
|
|
||||||
waitForSpinner,
|
|
||||||
} from './common.functions';
|
|
||||||
import { ensureSpecifiedUnstakedTokensAreAssociated } from './staking.functions';
|
import { ensureSpecifiedUnstakedTokensAreAssociated } from './staking.functions';
|
||||||
|
|
||||||
|
const newProposalButton = '[data-testid="new-proposal-link"]';
|
||||||
const proposalInformationTableRows = '[data-testid="key-value-table-row"]';
|
const proposalInformationTableRows = '[data-testid="key-value-table-row"]';
|
||||||
const proposalListItem = '[data-testid="proposals-list-item"]';
|
const proposalListItem = '[data-testid="proposals-list-item"]';
|
||||||
const newProposalTitle = '[data-testid="proposal-title"]';
|
const newProposalTitle = '[data-testid="proposal-title"]';
|
||||||
@@ -50,56 +46,6 @@ export function enterRawProposalBody(timestamp: number) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function submitUniqueRawProposal(proposalFields: {
|
|
||||||
proposalBody?: string;
|
|
||||||
proposalTitle?: string;
|
|
||||||
proposalDescription?: string;
|
|
||||||
closingTimestamp?: number;
|
|
||||||
enactmentTimestamp?: number;
|
|
||||||
submit?: boolean;
|
|
||||||
}) {
|
|
||||||
goToMakeNewProposal(governanceProposalType.RAW);
|
|
||||||
let proposalBodyPath = 'src/fixtures/proposals/raw.json';
|
|
||||||
if (proposalFields.proposalBody) {
|
|
||||||
proposalBodyPath = proposalFields.proposalBody;
|
|
||||||
}
|
|
||||||
cy.readFile(proposalBodyPath).then((rawProposal) => {
|
|
||||||
if (proposalFields.proposalTitle) {
|
|
||||||
rawProposal.rationale.title = proposalFields.proposalTitle;
|
|
||||||
cy.wrap(proposalFields.proposalTitle).as('proposalTitle');
|
|
||||||
}
|
|
||||||
if (proposalFields.proposalDescription) {
|
|
||||||
rawProposal.rationale.description = proposalFields.proposalDescription;
|
|
||||||
}
|
|
||||||
if (proposalFields.closingTimestamp) {
|
|
||||||
rawProposal.terms.closingTimestamp = proposalFields.closingTimestamp;
|
|
||||||
} else if (
|
|
||||||
!proposalFields.closingTimestamp &&
|
|
||||||
!proposalFields.proposalBody
|
|
||||||
) {
|
|
||||||
const minTimeStamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
|
||||||
rawProposal.terms.closingTimestamp = minTimeStamp;
|
|
||||||
}
|
|
||||||
if (proposalFields.enactmentTimestamp) {
|
|
||||||
rawProposal.terms.enactmentTimestamp = proposalFields.enactmentTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
const proposalPayload = JSON.stringify(rawProposal);
|
|
||||||
cy.get(rawProposalData).type(proposalPayload, {
|
|
||||||
parseSpecialCharSequences: false,
|
|
||||||
delay: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (proposalFields.submit !== false) {
|
|
||||||
cy.get(newProposalSubmitButton).should('be.visible').click();
|
|
||||||
cy.wrap(rawProposal).as('rawProposal');
|
|
||||||
waitForProposalSubmitted();
|
|
||||||
waitForProposalSync();
|
|
||||||
navigateTo(navigation.proposals);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function enterUniqueFreeFormProposalBody(
|
export function enterUniqueFreeFormProposalBody(
|
||||||
timestamp: string,
|
timestamp: string,
|
||||||
proposalTitle: string
|
proposalTitle: string
|
||||||
@@ -109,11 +55,7 @@ export function enterUniqueFreeFormProposalBody(
|
|||||||
'this is a e2e freeform proposal description'
|
'this is a e2e freeform proposal description'
|
||||||
);
|
);
|
||||||
cy.get(proposalVoteDeadline).clear().click().type(timestamp);
|
cy.get(proposalVoteDeadline).clear().click().type(timestamp);
|
||||||
cy.getByTestId('proposal-download-json').should('be.visible').click();
|
cy.getByTestId('proposal-submit').should('be.visible').click();
|
||||||
}
|
|
||||||
|
|
||||||
export function getProposalFromTitle(proposalTitle: string) {
|
|
||||||
return cy.contains(proposalTitle).parentsUntil(proposalListItem).last();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getSubmittedProposalFromProposalList(proposalTitle: string) {
|
export function getSubmittedProposalFromProposalList(proposalTitle: string) {
|
||||||
@@ -178,20 +120,15 @@ export function waitForProposalSync() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function goToMakeNewProposal(proposalType: governanceProposalType) {
|
export function goToMakeNewProposal(proposalType: string) {
|
||||||
cy.visit('/proposals/propose');
|
navigateTo(navigation.proposals);
|
||||||
waitForSpinner();
|
cy.get(newProposalButton).should('be.visible').click();
|
||||||
cy.url().should('include', '/proposals/propose');
|
cy.url().should('include', '/proposals/propose');
|
||||||
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
|
cy.get(navigation.pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||||
if (proposalType == governanceProposalType.RAW) {
|
cy.get('li').should('contain.text', proposalType).and('be.visible');
|
||||||
cy.get('[href="/proposals/propose/raw"]').click();
|
cy.get('li').contains(proposalType).click();
|
||||||
} else {
|
|
||||||
cy.get('li').should('contain.text', proposalType).and('be.visible');
|
|
||||||
cy.get('li').contains(proposalType).click();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3001-VOTE-013 3001-VOTE-014
|
|
||||||
export function waitForProposalSubmitted() {
|
export function waitForProposalSubmitted() {
|
||||||
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
cy.contains('Awaiting network confirmation', epochTimeout).should(
|
||||||
'be.visible'
|
'be.visible'
|
||||||
@@ -226,29 +163,11 @@ export function createFreeformProposal(proposalTitle: string) {
|
|||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDownloadedProposalJsonPath(proposalType: string) {
|
export const governanceProposalType = {
|
||||||
const downloadPath = './cypress/downloads/';
|
NETWORK_PARAMETER: 'Network parameter',
|
||||||
const filepath = downloadPath + proposalType + getFormattedTime() + '.json';
|
NEW_MARKET: 'New market',
|
||||||
return filepath;
|
UPDATE_MARKET: 'Update market',
|
||||||
}
|
NEW_ASSET: 'New asset',
|
||||||
|
FREEFORM: 'Freeform',
|
||||||
function getFormattedTime() {
|
RAW: 'raw proposal',
|
||||||
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',
|
|
||||||
UPDATE_MARKET = 'Update market',
|
|
||||||
NEW_ASSET = 'New asset',
|
|
||||||
UPDATE_ASSET = 'Update asset',
|
|
||||||
FREEFORM = 'Freeform',
|
|
||||||
RAW = 'raw proposal',
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import './common.functions.ts';
|
|||||||
import './staking.functions.ts';
|
import './staking.functions.ts';
|
||||||
import './governance.functions.ts';
|
import './governance.functions.ts';
|
||||||
import './wallet-eth.functions.ts';
|
import './wallet-eth.functions.ts';
|
||||||
import './wallet-functions.ts';
|
import './wallet-teardown.functions.ts';
|
||||||
|
import './wallet-vega.functions.ts';
|
||||||
import './proposal.functions.ts';
|
import './proposal.functions.ts';
|
||||||
import 'cypress-mochawesome-reporter/register';
|
|
||||||
import registerCypressGrep from '@cypress/grep';
|
import registerCypressGrep from '@cypress/grep';
|
||||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||||
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
import { chainIdQuery, statisticsQuery } from '@vegaprotocol/mock';
|
||||||
@@ -33,6 +33,4 @@ before(() => {
|
|||||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||||
});
|
});
|
||||||
// Self stake validators so they are displayed
|
|
||||||
cy.validatorsSelfDelegate();
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -85,132 +85,6 @@ export function createFreeFormProposalTxBody(): ProposalSubmissionBody {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createNewMarketProposalTxBody(): ProposalSubmissionBody {
|
|
||||||
const MIN_CLOSE_SEC = 5;
|
|
||||||
const MIN_ENACT_SEC = 7;
|
|
||||||
|
|
||||||
const closingDate = addSeconds(new Date(), MIN_CLOSE_SEC);
|
|
||||||
const enactmentDate = addSeconds(closingDate, MIN_ENACT_SEC);
|
|
||||||
const closingTimestamp = millisecondsToSeconds(closingDate.getTime());
|
|
||||||
const enactmentTimestamp = millisecondsToSeconds(enactmentDate.getTime());
|
|
||||||
return {
|
|
||||||
proposalSubmission: {
|
|
||||||
rationale: {
|
|
||||||
title: 'New Market Proposal E2E submission',
|
|
||||||
description: 'E2E new market proposal',
|
|
||||||
},
|
|
||||||
terms: {
|
|
||||||
newMarket: {
|
|
||||||
changes: {
|
|
||||||
decimalPlaces: '5',
|
|
||||||
positionDecimalPlaces: '5',
|
|
||||||
linearSlippageFactor: '0.001',
|
|
||||||
quadraticSlippageFactor: '0',
|
|
||||||
lpPriceRange: '10',
|
|
||||||
instrument: {
|
|
||||||
name: 'Token test market',
|
|
||||||
code: 'TEST.24h',
|
|
||||||
future: {
|
|
||||||
settlementAsset:
|
|
||||||
'73174a6fb1d5802ba0ac7bd7ab79e0a3a4837b262de0a4e80815a55442692bd0',
|
|
||||||
quoteName: 'fBTC',
|
|
||||||
dataSourceSpecForSettlementData: {
|
|
||||||
external: {
|
|
||||||
oracle: {
|
|
||||||
signers: [
|
|
||||||
{
|
|
||||||
pubKey: {
|
|
||||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
key: {
|
|
||||||
name: 'prices.ETH.value',
|
|
||||||
type: 'TYPE_INTEGER' as const,
|
|
||||||
numberDecimalPlaces: '0',
|
|
||||||
},
|
|
||||||
conditions: [
|
|
||||||
{
|
|
||||||
operator: 'OPERATOR_GREATER_THAN' as const,
|
|
||||||
value: '0',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dataSourceSpecForTradingTermination: {
|
|
||||||
external: {
|
|
||||||
oracle: {
|
|
||||||
signers: [
|
|
||||||
{
|
|
||||||
pubKey: {
|
|
||||||
key: '70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
key: {
|
|
||||||
name: 'trading.terminated.ETH5',
|
|
||||||
type: 'TYPE_BOOLEAN' as const,
|
|
||||||
},
|
|
||||||
conditions: [
|
|
||||||
{
|
|
||||||
operator: 'OPERATOR_EQUALS' as const,
|
|
||||||
value: 'true',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dataSourceSpecBinding: {
|
|
||||||
settlementDataProperty: 'prices.ETH.value',
|
|
||||||
tradingTerminationProperty: 'trading.terminated.ETH5',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
metadata: ['sector:energy', 'sector:tech', 'source:docs.vega.xyz'],
|
|
||||||
priceMonitoringParameters: {
|
|
||||||
triggers: [
|
|
||||||
{
|
|
||||||
horizon: '43200',
|
|
||||||
probability: '0.9999999',
|
|
||||||
auctionExtension: '600',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
liquidityMonitoringParameters: {
|
|
||||||
targetStakeParameters: {
|
|
||||||
timeWindow: '3600',
|
|
||||||
scalingFactor: 10,
|
|
||||||
},
|
|
||||||
triggeringRatio: '0.7',
|
|
||||||
auctionExtension: '1',
|
|
||||||
},
|
|
||||||
logNormal: {
|
|
||||||
tau: 0.0001140771161,
|
|
||||||
riskAversionParameter: 0.01,
|
|
||||||
params: {
|
|
||||||
mu: 0,
|
|
||||||
r: 0.016,
|
|
||||||
sigma: 0.5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
closingTimestamp,
|
|
||||||
enactmentTimestamp,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mockNetworkUpgradeProposal() {
|
export function mockNetworkUpgradeProposal() {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasGQLQuery(req, 'Nodes', nodeData);
|
aliasGQLQuery(req, 'Nodes', nodeData);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { closeDialog } from './common.functions';
|
import { closeDialog } from './common.functions';
|
||||||
import { vegaWalletTeardown } from './wallet-functions';
|
import { vegaWalletTeardown } from './wallet-teardown.functions';
|
||||||
|
|
||||||
const tokenAmountInputBox = '[data-testid="token-amount-input"]';
|
const tokenAmountInputBox = '[data-testid="token-amount-input"]';
|
||||||
const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
||||||
@@ -221,7 +221,7 @@ export function ensureSpecifiedUnstakedTokensAreAssociated(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function closeStakingDialog() {
|
export function closeStakingDialog() {
|
||||||
cy.getByTestId('dialog-title', txTimeout).should(
|
cy.getByTestId('dialog-title').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'At the beginning of the next epoch'
|
'At the beginning of the next epoch'
|
||||||
);
|
);
|
||||||
@@ -236,8 +236,8 @@ export function validateWalletCurrency(
|
|||||||
currencyTitle: string,
|
currencyTitle: string,
|
||||||
expectedAmount: string
|
expectedAmount: string
|
||||||
) {
|
) {
|
||||||
cy.get("[data-testid='currency-title']", txTimeout)
|
cy.get("[data-testid='currency-title']")
|
||||||
.contains(currencyTitle, txTimeout)
|
.contains(currencyTitle)
|
||||||
.parent()
|
.parent()
|
||||||
.parent()
|
.parent()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const capsuleWalletConnectButton = '[data-testid="web3-connector-Unknown"]';
|
|||||||
|
|
||||||
export function ethereumWalletConnect() {
|
export function ethereumWalletConnect() {
|
||||||
cy.highlight('Connecting Eth Wallet');
|
cy.highlight('Connecting Eth Wallet');
|
||||||
cy.get(connectToEthButton, { timeout: 60000 }).within(() => {
|
cy.get(connectToEthButton).within(() => {
|
||||||
cy.contains('Connect Ethereum wallet to associate $VEGA')
|
cy.contains('Connect Ethereum wallet to associate $VEGA')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
|||||||
+36
-51
@@ -3,6 +3,7 @@ import {
|
|||||||
StakingBridge,
|
StakingBridge,
|
||||||
Token,
|
Token,
|
||||||
TokenVesting,
|
TokenVesting,
|
||||||
|
TokenFaucetable,
|
||||||
CollateralBridge,
|
CollateralBridge,
|
||||||
} from '@vegaprotocol/smart-contracts';
|
} from '@vegaprotocol/smart-contracts';
|
||||||
import { ethers, Wallet } from 'ethers';
|
import { ethers, Wallet } from 'ethers';
|
||||||
@@ -19,7 +20,7 @@ const ethStakingBridgeContractAddress = Cypress.env(
|
|||||||
);
|
);
|
||||||
const ethProviderUrl = Cypress.env('ethProviderUrl');
|
const ethProviderUrl = Cypress.env('ethProviderUrl');
|
||||||
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
||||||
const transactionTimeout = { timeout: 100000, log: false };
|
const transactionTimeout = 100000;
|
||||||
const Erc20BridgeAddress = '0x9708FF7510D4A7B9541e1699d15b53Ecb1AFDc54';
|
const Erc20BridgeAddress = '0x9708FF7510D4A7B9541e1699d15b53Ecb1AFDc54';
|
||||||
|
|
||||||
const provider = new ethers.providers.JsonRpcProvider({ url: ethProviderUrl });
|
const provider = new ethers.providers.JsonRpcProvider({ url: ethProviderUrl });
|
||||||
@@ -40,10 +41,13 @@ export async function depositAsset(
|
|||||||
decimalPlaces: number
|
decimalPlaces: number
|
||||||
) {
|
) {
|
||||||
// Approve asset
|
// Approve asset
|
||||||
const faucet = new Token(assetEthAddress, signer);
|
const faucet = new TokenFaucetable(assetEthAddress, signer);
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(decimalPlaces + 1)),
|
faucet.approve(Erc20BridgeAddress, amount + '0'.repeat(decimalPlaces + 1)),
|
||||||
transactionTimeout
|
{
|
||||||
|
timeout: transactionTimeout,
|
||||||
|
log: false,
|
||||||
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
const collateralBridge = new CollateralBridge(Erc20BridgeAddress, signer);
|
const collateralBridge = new CollateralBridge(Erc20BridgeAddress, signer);
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
@@ -52,18 +56,19 @@ export async function depositAsset(
|
|||||||
amount + '0'.repeat(decimalPlaces),
|
amount + '0'.repeat(decimalPlaces),
|
||||||
'0x' + vegaWalletPubKey
|
'0x' + vegaWalletPubKey
|
||||||
),
|
),
|
||||||
transactionTimeout
|
{ timeout: transactionTimeout, log: false }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function faucetAsset(assetEthAddress: string) {
|
export async function faucetAsset(assetEthAddress: string) {
|
||||||
const faucet = new Token(assetEthAddress, signer);
|
const faucet = new TokenFaucetable(assetEthAddress, signer);
|
||||||
await promiseWithTimeout(faucet.faucet(), 10 * 60 * 1000, 'faucet asset');
|
await promiseWithTimeout(faucet.faucet(), 10 * 60 * 1000, 'faucet asset');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function vegaWalletTeardown() {
|
export async function vegaWalletTeardown() {
|
||||||
cy.get(associatedAmountInWallet)
|
cy.get(associatedAmountInWallet)
|
||||||
|
.should('be.visible')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((associatedAmount) => {
|
.then((associatedAmount) => {
|
||||||
cy.get('body').then(($body) => {
|
cy.get('body').then(($body) => {
|
||||||
@@ -76,13 +81,11 @@ export async function vegaWalletTeardown() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
cy.get(vegaWalletContainer).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.get(associatedAmountInWallet, transactionTimeout).should(
|
cy.get(associatedAmountInWallet, {
|
||||||
'have.length',
|
timeout: transactionTimeout,
|
||||||
1
|
}).contains('0.00', {
|
||||||
);
|
timeout: transactionTimeout,
|
||||||
cy.get(associatedAmountInWallet)
|
});
|
||||||
.first(transactionTimeout)
|
|
||||||
.should('have.text', '0.00');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -106,7 +109,7 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
|||||||
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
stakingBridgeContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
stakingBridgeContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||||
transactionTimeout
|
{ timeout: transactionTimeout }
|
||||||
).then((stakeBalance) => {
|
).then((stakeBalance) => {
|
||||||
if (Number(stakeBalance) != 0) {
|
if (Number(stakeBalance) != 0) {
|
||||||
cy.get(vegaWalletContainer).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
@@ -119,25 +122,31 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
|||||||
String(stakeBalance),
|
String(stakeBalance),
|
||||||
vegaWalletPubKey
|
vegaWalletPubKey
|
||||||
),
|
),
|
||||||
transactionTimeout
|
{ timeout: transactionTimeout }
|
||||||
);
|
);
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
||||||
transactionTimeout
|
{
|
||||||
|
timeout: transactionTimeout,
|
||||||
|
log: false,
|
||||||
|
}
|
||||||
).then((vestingAmount) => {
|
).then((vestingAmount) => {
|
||||||
if (Number(vestingAmount) != 0) {
|
if (Number(vestingAmount) != 0) {
|
||||||
cy.contains('Associated', transactionTimeout)
|
cy.contains('Associated', {
|
||||||
|
timeout: transactionTimeout,
|
||||||
|
})
|
||||||
.parent()
|
.parent()
|
||||||
.parent()
|
.parent()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId('currency-value', transactionTimeout)
|
cy.getByTestId('currency-value', {
|
||||||
.first()
|
timeout: transactionTimeout,
|
||||||
|
})
|
||||||
|
.should('have.length', 1)
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.as('displayedAmount');
|
.as('displayedAmount');
|
||||||
cy.get('@displayedAmount', transactionTimeout).should(
|
cy.get('@displayedAmount', {
|
||||||
'not.eq',
|
timeout: transactionTimeout,
|
||||||
$associatedAmount
|
}).should('not.eq', $associatedAmount);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -149,14 +158,14 @@ async function vegaWalletTeardownStaking(stakingBridgeContract: StakingBridge) {
|
|||||||
|
|
||||||
async function vegaWalletTeardownVesting(vestingContract: TokenVesting) {
|
async function vegaWalletTeardownVesting(vestingContract: TokenVesting) {
|
||||||
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
||||||
cy.wrap(
|
cy.wrap(vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey), {
|
||||||
vestingContract.stake_balance(ethWalletPubKey, vegaWalletPubKey),
|
timeout: transactionTimeout,
|
||||||
transactionTimeout
|
log: false,
|
||||||
).then((vestingAmount) => {
|
}).then((vestingAmount) => {
|
||||||
if (Number(vestingAmount) != 0) {
|
if (Number(vestingAmount) != 0) {
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
vestingContract.remove_stake(String(vestingAmount), vegaWalletPubKey),
|
vestingContract.remove_stake(String(vestingAmount), vegaWalletPubKey),
|
||||||
transactionTimeout
|
{ timeout: transactionTimeout }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -173,27 +182,3 @@ export async function vegaWalletDisassociate(amount: string) {
|
|||||||
amount = amount + '0'.repeat(18);
|
amount = amount + '0'.repeat(18);
|
||||||
stakingBridgeContract.remove_stake(amount, vegaWalletPubKey);
|
stakingBridgeContract.remove_stake(amount, vegaWalletPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function vegaWalletFaucetAssetsWithoutCheck(
|
|
||||||
asset: string,
|
|
||||||
amount: string,
|
|
||||||
vegaWalletPublicKey: string
|
|
||||||
) {
|
|
||||||
cy.highlight(`Topping up vega wallet with ${asset}, amount: ${amount}`);
|
|
||||||
cy.exec(
|
|
||||||
`curl -X POST -d '{"amount": "${amount}", "asset": "${asset}", "party": "${vegaWalletPublicKey}"}' http://localhost:1790/api/v1/mint`
|
|
||||||
)
|
|
||||||
.its('stdout')
|
|
||||||
.then((response) => {
|
|
||||||
assert.include(
|
|
||||||
response,
|
|
||||||
`"success":true`,
|
|
||||||
'Ensuring curl command was successfully undertaken'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function switchVegaWalletPubKey() {
|
|
||||||
cy.get('[data-testid="manage-vega-wallet"]:visible').click();
|
|
||||||
cy.get('[data-testid="select-keypair-button"]').eq(0).click();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
export function vegaWalletFaucetAssetsWithoutCheck(
|
||||||
|
asset: string,
|
||||||
|
amount: string,
|
||||||
|
vegaWalletPublicKey: string
|
||||||
|
) {
|
||||||
|
cy.highlight(`Topping up vega wallet with ${asset}, amount: ${amount}`);
|
||||||
|
cy.exec(
|
||||||
|
`curl -X POST -d '{"amount": "${amount}", "asset": "${asset}", "party": "${vegaWalletPublicKey}"}' http://localhost:1790/api/v1/mint`
|
||||||
|
)
|
||||||
|
.its('stdout')
|
||||||
|
.then((response) => {
|
||||||
|
assert.include(
|
||||||
|
response,
|
||||||
|
`"success":true`,
|
||||||
|
'Ensuring curl command was successfully undertaken'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -5,18 +5,16 @@ NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
|||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_FAIRGROUND=false
|
NX_FAIRGROUND=false
|
||||||
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_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://stagnet1.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||||
|
|
||||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
|
||||||
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
|
||||||
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
|
||||||
|
|
||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ NX_VEGA_WALLET_URL=http://localhost:1789
|
|||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||||
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
|
|
||||||
|
|
||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https:/
|
|||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_VEGA_EXPLORER_URL=#
|
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_VEGA_REST_URL=https://api.n00.devnet1.vega.xyz/api/v2/
|
|
||||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ NX_VEGA_ENV=MAINNET
|
|||||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||||
NX_VEGA_URL=https://api.vega.community/graphql
|
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_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/3ba145ccc2884bcd91213d8dc989ca76
|
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://etherscan.io
|
NX_ETHERSCAN_URL=https://etherscan.io
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40:87edc2605e544f888305d7fc4a9141bd@o286262.ingest.sentry.io/5882996
|
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40:87edc2605e544f888305d7fc4a9141bd@o286262.ingest.sentry.io/5882996
|
||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-k8s.ops.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||||
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||||
NX_VEGA_ENV=STAGNET1
|
NX_VEGA_ENV=STAGNET1
|
||||||
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_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_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||||
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
|
|
||||||
|
|||||||
@@ -12,5 +12,3 @@ NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
|||||||
NX_DELEGATIONS_PAGINATION=50
|
NX_DELEGATIONS_PAGINATION=50
|
||||||
NX_TRANCHES_SERVICE_URL=https://tranches-testnet-k8s.ops.vega.xyz
|
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_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
|
|
||||||
|
|||||||
@@ -7,7 +7,5 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https:/
|
|||||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
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
|
|
||||||
-6
@@ -1,6 +0,0 @@
|
|||||||
function ReactMarkdown({ children }) {
|
|
||||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
||||||
return <>{children}</>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ReactMarkdown;
|
|
||||||
+15
-57
@@ -2,6 +2,7 @@ import './i18n';
|
|||||||
|
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
|
import { Integrations } from '@sentry/tracing';
|
||||||
import { BrowserRouter as Router, useLocation } from 'react-router-dom';
|
import { BrowserRouter as Router, useLocation } from 'react-router-dom';
|
||||||
import { AppLoader } from './app-loader';
|
import { AppLoader } from './app-loader';
|
||||||
import { NetworkInfo } from '@vegaprotocol/network-info';
|
import { NetworkInfo } from '@vegaprotocol/network-info';
|
||||||
@@ -16,7 +17,6 @@ import { AppStateProvider } from './contexts/app-state/app-state-provider';
|
|||||||
import { ContractsProvider } from './contexts/contracts/contracts-provider';
|
import { ContractsProvider } from './contexts/contracts/contracts-provider';
|
||||||
import { AppRouter } from './routes';
|
import { AppRouter } from './routes';
|
||||||
import type { EthereumConfig } from '@vegaprotocol/web3';
|
import type { EthereumConfig } from '@vegaprotocol/web3';
|
||||||
import { WithdrawalApprovalDialogContainer } from '@vegaprotocol/web3';
|
|
||||||
import {
|
import {
|
||||||
createConnectors,
|
createConnectors,
|
||||||
useEthTransactionManager,
|
useEthTransactionManager,
|
||||||
@@ -44,7 +44,7 @@ import {
|
|||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import { ENV } from './config';
|
import { ENV } from './config';
|
||||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||||
import { CreateWithdrawalDialog } from '@vegaprotocol/withdraws';
|
import { WithdrawalDialog } from '@vegaprotocol/withdraws';
|
||||||
import { SplashLoader } from './components/splash-loader';
|
import { SplashLoader } from './components/splash-loader';
|
||||||
import { ToastsManager } from './toasts-manager';
|
import { ToastsManager } from './toasts-manager';
|
||||||
import {
|
import {
|
||||||
@@ -53,7 +53,6 @@ import {
|
|||||||
} from './components/telemetry-dialog/telemetry-dialog';
|
} from './components/telemetry-dialog/telemetry-dialog';
|
||||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { isPartyNotFoundError } from './lib/party';
|
|
||||||
|
|
||||||
const cache: InMemoryCacheConfig = {
|
const cache: InMemoryCacheConfig = {
|
||||||
typePolicies: {
|
typePolicies: {
|
||||||
@@ -159,8 +158,7 @@ const Web3Container = ({
|
|||||||
<InitializeHandlers />
|
<InitializeHandlers />
|
||||||
<VegaWalletDialogs />
|
<VegaWalletDialogs />
|
||||||
<TransactionModal />
|
<TransactionModal />
|
||||||
<CreateWithdrawalDialog />
|
<WithdrawalDialog />
|
||||||
<WithdrawalApprovalDialogContainer />
|
|
||||||
<TelemetryDialog />
|
<TelemetryDialog />
|
||||||
</>
|
</>
|
||||||
</BalanceManager>
|
</BalanceManager>
|
||||||
@@ -186,10 +184,6 @@ const ScrollToTop = () => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeQueryParams = (url: string) => {
|
|
||||||
return url.split('?')[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
const AppContainer = () => {
|
const AppContainer = () => {
|
||||||
const { config, loading, error } = useEthereumConfig();
|
const { config, loading, error } = useEthereumConfig();
|
||||||
const {
|
const {
|
||||||
@@ -207,61 +201,25 @@ const AppContainer = () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ENV.dsn && telemetryOn === 'true') {
|
if (ENV.dsn && telemetryOn) {
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: ENV.dsn,
|
dsn: ENV.dsn,
|
||||||
|
integrations: [new Integrations.BrowserTracing()],
|
||||||
tracesSampleRate: 0.1,
|
tracesSampleRate: 0.1,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
environment: VEGA_ENV,
|
environment: VEGA_ENV,
|
||||||
release: GIT_COMMIT_HASH,
|
release: GIT_COMMIT_HASH,
|
||||||
beforeSend(event, hint) {
|
beforeSend(event) {
|
||||||
const error = hint?.originalException;
|
if (event.request?.url?.includes('/claim?')) {
|
||||||
const errorIsString = typeof error === 'string';
|
return {
|
||||||
const errorIsObject = error instanceof Error;
|
...event,
|
||||||
const requestUrl = event.request?.url;
|
request: {
|
||||||
const transaction = event.transaction;
|
...event.request,
|
||||||
|
url: event.request?.url.split('?')[0],
|
||||||
if (
|
},
|
||||||
(errorIsString && isPartyNotFoundError({ message: error })) ||
|
};
|
||||||
(errorIsObject && isPartyNotFoundError(error))
|
|
||||||
) {
|
|
||||||
// This error is caused by a pubkey making an API request before
|
|
||||||
// it has interacted with the chain. This isn't needed in Sentry.
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return event;
|
||||||
const updatedRequest =
|
|
||||||
requestUrl && requestUrl.includes('/claim?')
|
|
||||||
? { ...event.request, url: removeQueryParams(requestUrl) }
|
|
||||||
: event.request;
|
|
||||||
|
|
||||||
const updatedTransaction =
|
|
||||||
transaction && transaction.includes('/claim?')
|
|
||||||
? removeQueryParams(transaction)
|
|
||||||
: transaction;
|
|
||||||
|
|
||||||
const updatedBreadcrumbs = event.breadcrumbs?.map((breadcrumb) => {
|
|
||||||
if (
|
|
||||||
breadcrumb.type === 'navigation' &&
|
|
||||||
breadcrumb.data?.to?.includes('/claim?')
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
...breadcrumb,
|
|
||||||
data: {
|
|
||||||
...breadcrumb.data,
|
|
||||||
to: removeQueryParams(breadcrumb.data.to),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return breadcrumb;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...event,
|
|
||||||
request: updatedRequest,
|
|
||||||
transaction: updatedTransaction,
|
|
||||||
breadcrumbs: updatedBreadcrumbs ?? event.breadcrumbs,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Sentry.setTag('branch', GIT_BRANCH);
|
Sentry.setTag('branch', GIT_BRANCH);
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useWeb3ConnectStore } from '@vegaprotocol/web3';
|
|
||||||
|
import {
|
||||||
|
AppStateActionType,
|
||||||
|
useAppState,
|
||||||
|
} from '../../contexts/app-state/app-state-context';
|
||||||
|
|
||||||
export const EthConnectPrompt = () => {
|
export const EthConnectPrompt = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { open } = useWeb3ConnectStore();
|
const { appDispatch } = useAppState();
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
variant="default"
|
variant="default"
|
||||||
onClick={open}
|
onClick={() =>
|
||||||
|
appDispatch({
|
||||||
|
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
|
||||||
|
isOpen: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
fill={true}
|
fill={true}
|
||||||
data-testid="connect-to-eth-btn"
|
data-testid="connect-to-eth-btn"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import { Button } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { useWeb3React } from '@web3-react/core';
|
import { useWeb3React } from '@web3-react/core';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useWeb3ConnectStore } from '@vegaprotocol/web3';
|
import {
|
||||||
|
AppStateActionType,
|
||||||
|
useAppState,
|
||||||
|
} from '../../contexts/app-state/app-state-context';
|
||||||
|
|
||||||
export const EthWalletContainer = ({
|
export const EthWalletContainer = ({
|
||||||
children,
|
children,
|
||||||
@@ -11,12 +14,21 @@ export const EthWalletContainer = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { account } = useWeb3React();
|
const { account } = useWeb3React();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { open } = useWeb3ConnectStore();
|
const { appDispatch } = useAppState();
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full text-center">
|
<div className="w-full text-center">
|
||||||
<Button onClick={open}>{t('connectEthWallet')}</Button>
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
appDispatch({
|
||||||
|
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
|
||||||
|
isOpen: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t('connectEthWallet')}
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,11 +27,7 @@ import {
|
|||||||
import { Loader } from '@vegaprotocol/ui-toolkit';
|
import { Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import colors from 'tailwindcss/colors';
|
import colors from 'tailwindcss/colors';
|
||||||
import { useBalances } from '../../lib/balances/balances-store';
|
import { useBalances } from '../../lib/balances/balances-store';
|
||||||
import {
|
import { useEthereumConfig, useWeb3Disconnect } from '@vegaprotocol/web3';
|
||||||
useEthereumConfig,
|
|
||||||
useWeb3ConnectStore,
|
|
||||||
useWeb3Disconnect,
|
|
||||||
} from '@vegaprotocol/web3';
|
|
||||||
import { getChainName } from '@vegaprotocol/web3';
|
import { getChainName } from '@vegaprotocol/web3';
|
||||||
|
|
||||||
const removeLeadingAddressSymbol = (key: string) => {
|
const removeLeadingAddressSymbol = (key: string) => {
|
||||||
@@ -193,7 +189,6 @@ export const EthWallet = () => {
|
|||||||
const pendingTxs = usePendingTransactions();
|
const pendingTxs = usePendingTransactions();
|
||||||
const disconnect = useWeb3Disconnect(connector);
|
const disconnect = useWeb3Disconnect(connector);
|
||||||
const { config } = useEthereumConfig();
|
const { config } = useEthereumConfig();
|
||||||
const { open } = useWeb3ConnectStore();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WalletCard>
|
<WalletCard>
|
||||||
@@ -238,7 +233,12 @@ export const EthWallet = () => {
|
|||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
fill={true}
|
fill={true}
|
||||||
onClick={open}
|
onClick={() =>
|
||||||
|
appDispatch({
|
||||||
|
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
|
||||||
|
isOpen: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
data-testid="connect-to-eth-wallet-button"
|
data-testid="connect-to-eth-wallet-button"
|
||||||
>
|
>
|
||||||
{t('connectEthWalletToAssociate')}
|
{t('connectEthWalletToAssociate')}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
export * from './multisig-incorrect-notice';
|
|
||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
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
@@ -1,49 +0,0 @@
|
|||||||
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>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
|
||||||
import {
|
|
||||||
ExternalLink,
|
|
||||||
VegaIcon,
|
|
||||||
VegaIconNames,
|
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
|
||||||
import Routes from '../../routes/routes';
|
|
||||||
|
|
||||||
export const RiskMessage = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="bg-vega-light-100 dark:bg-vega-dark-100 p-6 mb-6">
|
|
||||||
<ul className="list-[square] ml-4">
|
|
||||||
<li>
|
|
||||||
{t(
|
|
||||||
'You may encounter bugs, loss of functionality or loss of assets using the App.'
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{t(
|
|
||||||
'No party accepts any liability for any losses whatsoever related to its use.'
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<p className="mb-8">
|
|
||||||
{t(
|
|
||||||
'By using the Vega Governance App, you acknowledge that you have read and understood the'
|
|
||||||
)}{' '}
|
|
||||||
<ExternalLink href={Routes.DISCLAIMER} className="underline">
|
|
||||||
<span className="flex items-center gap-1">
|
|
||||||
<span>{t('Vega Governance Disclaimer')}</span>
|
|
||||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
|
||||||
</span>
|
|
||||||
</ExternalLink>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -4,11 +4,9 @@ import {
|
|||||||
useAppState,
|
useAppState,
|
||||||
} from '../../contexts/app-state/app-state-context';
|
} from '../../contexts/app-state/app-state-context';
|
||||||
import { Connectors } from '../../lib/vega-connectors';
|
import { Connectors } from '../../lib/vega-connectors';
|
||||||
import { RiskMessage } from './risk-message';
|
|
||||||
|
|
||||||
export const VegaWalletDialogs = () => {
|
export const VegaWalletDialogs = () => {
|
||||||
const { appState, appDispatch } = useAppState();
|
const { appState, appDispatch } = useAppState();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<VegaConnectDialog
|
<VegaConnectDialog
|
||||||
@@ -19,7 +17,6 @@ export const VegaWalletDialogs = () => {
|
|||||||
isOpen: open,
|
isOpen: open,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
riskMessage={<RiskMessage />}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<VegaManageDialog
|
<VegaManageDialog
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Link } from '@vegaprotocol/ui-toolkit';
|
import { Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ExternalLinks } from '@vegaprotocol/environment';
|
import { ExternalLinks } from '@vegaprotocol/utils';
|
||||||
|
|
||||||
export const DownloadWalletPrompt = () => {
|
export const DownloadWalletPrompt = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import type {
|
|||||||
WalletDelegationFieldsFragment,
|
WalletDelegationFieldsFragment,
|
||||||
} from './__generated__/Delegations';
|
} from './__generated__/Delegations';
|
||||||
import { DelegationsDocument } from './__generated__/Delegations';
|
import { DelegationsDocument } from './__generated__/Delegations';
|
||||||
import { isPartyNotFoundError } from '../../lib/party';
|
|
||||||
|
|
||||||
export const usePollForDelegations = () => {
|
export const usePollForDelegations = () => {
|
||||||
const { token: vegaToken } = useContracts();
|
const { token: vegaToken } = useContracts();
|
||||||
@@ -76,7 +75,6 @@ export const usePollForDelegations = () => {
|
|||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
const canonisedDelegations = removePaginationWrapper(
|
const canonisedDelegations = removePaginationWrapper(
|
||||||
res.data.party?.delegationsConnection?.edges
|
res.data.party?.delegationsConnection?.edges
|
||||||
);
|
);
|
||||||
@@ -205,15 +203,6 @@ export const usePollForDelegations = () => {
|
|||||||
setDelegatedNodes(delegatedAmounts);
|
setDelegatedNodes(delegatedAmounts);
|
||||||
})
|
})
|
||||||
.catch((err: Error) => {
|
.catch((err: Error) => {
|
||||||
// if party isn't found, dont log to Sentry, just clear state as, user
|
|
||||||
// will not have any delagations or accounts
|
|
||||||
if (isPartyNotFoundError(err)) {
|
|
||||||
setDelegations([]);
|
|
||||||
setAccounts([]);
|
|
||||||
setDelegatedNodes([]);
|
|
||||||
setCurrentStakeAvailable(new BigNumber(0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
// If query fails stop interval. Its almost certain that the query
|
// If query fails stop interval. Its almost certain that the query
|
||||||
// will just continue to fail
|
// will just continue to fail
|
||||||
|
|||||||
@@ -25,26 +25,20 @@ export function Web3Connector({
|
|||||||
connectors,
|
connectors,
|
||||||
chainId,
|
chainId,
|
||||||
}: Web3ConnectorProps) {
|
}: Web3ConnectorProps) {
|
||||||
const { open, close, isOpen } = useWeb3ConnectStore();
|
const { appState, appDispatch } = useAppState();
|
||||||
|
|
||||||
const setDialogOpen = useCallback(
|
const setDialogOpen = useCallback(
|
||||||
(isOpen: boolean) => {
|
(isOpen: boolean) => {
|
||||||
if (isOpen) {
|
appDispatch({ type: AppStateActionType.SET_ETH_WALLET_OVERLAY, isOpen });
|
||||||
open();
|
|
||||||
} else {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[open, close]
|
[appDispatch]
|
||||||
);
|
);
|
||||||
|
|
||||||
const appChainId = Number(chainId);
|
const appChainId = Number(chainId);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Web3Content appChainId={appChainId}>{children}</Web3Content>
|
<Web3Content appChainId={appChainId}>{children}</Web3Content>
|
||||||
<Web3ConnectDialog
|
<Web3ConnectDialog
|
||||||
connectors={connectors}
|
connectors={connectors}
|
||||||
dialogOpen={isOpen}
|
dialogOpen={appState.ethConnectOverlay}
|
||||||
setDialogOpen={setDialogOpen}
|
setDialogOpen={setDialogOpen}
|
||||||
desiredChainId={appChainId}
|
desiredChainId={appChainId}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ export const ENV = {
|
|||||||
ethWalletMnemonic: windowOrDefault('NX_ETH_WALLET_MNEMONIC'),
|
ethWalletMnemonic: windowOrDefault('NX_ETH_WALLET_MNEMONIC'),
|
||||||
localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'),
|
localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'),
|
||||||
delegationsPagination: windowOrDefault('NX_DELEGATIONS_PAGINATION'),
|
delegationsPagination: windowOrDefault('NX_DELEGATIONS_PAGINATION'),
|
||||||
rest: windowOrDefault('NX_VEGA_REST_URL'),
|
|
||||||
flags: {
|
flags: {
|
||||||
NETWORK_DOWN: TRUTHY.includes(windowOrDefault('NX_NETWORK_DOWN')),
|
NETWORK_DOWN: TRUTHY.includes(windowOrDefault('NX_NETWORK_DOWN')),
|
||||||
MOCK: TRUTHY.includes(windowOrDefault('NX_MOCKED')),
|
MOCK: TRUTHY.includes(windowOrDefault('NX_MOCKED')),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user