* feat: improve proposal types, add faucet for trading asset * chore: yarn lock update * fix: capsule tests to avoid jsx import * chore: throw error so that ethereum setup failure is caught * chore: org files and add logging * chore: revert current trading-e2e .env file * chore: add .env.capsule for trading tests on capsule * chore: remove unused nx command * chore: remove try catchs and allow errors to be caught by cypress * chore: add slow tag for capsule test * feat: move create market setup to libs/cypress * chore: clearly separate vars meant for capsule with vars meant for non-capsule * feat: remove hardcoded urls and use config obj * chore: fix missing comma in genesis.tmpl * chore: added limit order edit price test * chore: remove encoding of transaction, update proposal tx trigger ratio to string * chore: fix date and add date verification for update order * chore: formatting fix * chore: adjust trading app tests and workflows to be run in capsule in ci (#2574) * chore: adjust trading app tests and workflows to be run in capsule in ci * chore: fix token tests * chore: increase timeout as it fails in ci * chore: move market check to before function * chore: add capsule logs to trading * chore: increase proposal close time, also break up script for better debugging * chore: bump up ethereum account setup timeout * chore: suppress fetch logs to help with debugging * chore: revert cy wraps now with suppressed logging * chore: decrease tick amount * chore: promise with timeout for better debugging * chore: bump individual timeouts * chore: bump timeout for tx wait promises * chore: minor fix * fix: leave Promise<any> * fix: leave Promise<any> * chore: fix home fail Co-authored-by: Joe <joe@vega.xyz> Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com> Co-authored-by: Radosław Szpiech <szpiechrados@gmail.com> Co-authored-by: Madalina Raicu <madalina@raygroup.uk>
This commit is contained in:
parent
b96e6ee9ce
commit
2c3c685522
@ -1,6 +1,3 @@
|
|||||||
inputs:
|
|
||||||
passphrase:
|
|
||||||
description: 'Wallet password'
|
|
||||||
outputs:
|
outputs:
|
||||||
token:
|
token:
|
||||||
description: 'api-token of wallet'
|
description: 'api-token of wallet'
|
||||||
|
12
.github/workflows/cypress-console-lite-e2e.yml
vendored
12
.github/workflows/cypress-console-lite-e2e.yml
vendored
@ -42,17 +42,16 @@ jobs:
|
|||||||
- name: Install root dependencies
|
- name: Install root dependencies
|
||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
######
|
######
|
||||||
## Setup a Vega wallet for our user
|
## Setup a Vega wallet for our user
|
||||||
######
|
######
|
||||||
|
|
||||||
- name: Set up Vegawallet
|
- name: Run Vegacapsule network
|
||||||
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
|
||||||
|
- name: Set up Vegawallet for capsule
|
||||||
id: setup-vega
|
id: setup-vega
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
|
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||||
with:
|
|
||||||
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
# To make sure that all Cypress binaries are installed properly
|
||||||
- name: Install cypress bins
|
- name: Install cypress bins
|
||||||
@ -63,7 +62,6 @@ jobs:
|
|||||||
run: npx nx run console-lite-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
run: npx nx run console-lite-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||||
|
15
.github/workflows/cypress-explorer-e2e.yml
vendored
15
.github/workflows/cypress-explorer-e2e.yml
vendored
@ -51,22 +51,16 @@ jobs:
|
|||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Build and run Vegacapsule network
|
|
||||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Setup a Vega wallet for our user
|
## Setup a Vega wallet for our user
|
||||||
######
|
######
|
||||||
|
|
||||||
- name: Set up Vegawallet for docker
|
- name: Run Vegacapsule network
|
||||||
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
|
||||||
|
- name: Set up Vegawallet for capsule
|
||||||
id: setup-vega
|
id: setup-vega
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||||
with:
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Run some tests
|
## Run some tests
|
||||||
@ -81,7 +75,6 @@ jobs:
|
|||||||
run: npx nx run explorer-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
run: npx nx run explorer-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||||
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
|
CYPRESS_NIGHTLY_RUN: ${{ inputs.night-run }}
|
||||||
|
15
.github/workflows/cypress-token-e2e.yml
vendored
15
.github/workflows/cypress-token-e2e.yml
vendored
@ -47,22 +47,16 @@ jobs:
|
|||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
|
|
||||||
#######
|
|
||||||
## Build and run Vegacapsule network
|
|
||||||
#######
|
|
||||||
|
|
||||||
- name: Build and run Vegacapsule network
|
|
||||||
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Setup a Vega wallet for our user
|
## Setup a Vega wallet for our user
|
||||||
######
|
######
|
||||||
|
|
||||||
- name: Set up Vegawallet for docker
|
- name: Run Vegacapsule network
|
||||||
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
|
||||||
|
- name: Set up Vegawallet for capsule
|
||||||
id: setup-vega
|
id: setup-vega
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||||
with:
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
######
|
######
|
||||||
## Run some tests
|
## Run some tests
|
||||||
@ -77,7 +71,6 @@ jobs:
|
|||||||
run: npx nx run token-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
run: npx nx run token-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||||
|
28
.github/workflows/cypress-trading-e2e.yml
vendored
28
.github/workflows/cypress-trading-e2e.yml
vendored
@ -48,12 +48,12 @@ jobs:
|
|||||||
## Setup a Vega wallet for our user
|
## Setup a Vega wallet for our user
|
||||||
######
|
######
|
||||||
|
|
||||||
- name: Set up Vegawallet
|
- name: Run Vegacapsule network
|
||||||
|
uses: ./frontend-monorepo/.github/actions/run-vegacapsule
|
||||||
|
|
||||||
|
- name: Set up Vegawallet for capsule
|
||||||
id: setup-vega
|
id: setup-vega
|
||||||
uses: ./frontend-monorepo/.github/actions/setup-vegawallet
|
uses: ./frontend-monorepo/.github/actions/setup-vegawallet-docker
|
||||||
with:
|
|
||||||
recovery: ${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}
|
|
||||||
passphrase: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
|
|
||||||
# To make sure that all Cypress binaries are installed properly
|
# To make sure that all Cypress binaries are installed properly
|
||||||
- name: Install cypress bins
|
- name: Install cypress bins
|
||||||
@ -64,7 +64,23 @@ jobs:
|
|||||||
run: npx nx run trading-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
run: npx nx run trading-e2e:e2e ${{ inputs.skip-cache }} --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome ${{ inputs.tags }}
|
||||||
working-directory: frontend-monorepo
|
working-directory: frontend-monorepo
|
||||||
env:
|
env:
|
||||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
|
||||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||||
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPRESS_ETH_WALLET_MNEMONIC }}
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
CYPRESS_VEGA_WALLET_API_TOKEN: ${{ steps.setup-vega.outputs.token }}
|
||||||
|
|
||||||
|
######
|
||||||
|
## Upload logs
|
||||||
|
######
|
||||||
|
|
||||||
|
- name: Rename files to allow archive
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
while read -r file; do
|
||||||
|
mv "${file}" "$(echo ${file} | sed 's|:|-|g')"
|
||||||
|
done< <(find /home/runner/.vegacapsule/testnet/logs -type f)
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
name: logs
|
||||||
|
path: /home/runner/.vegacapsule/testnet/logs
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
# App configuration variables
|
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
|
||||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
|
||||||
NX_VEGA_ENV=STAGNET3
|
|
||||||
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_VEGA_CONFIG_URL=''
|
||||||
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
CYPRESS_VEGA_ENV=STAGNET3
|
|
||||||
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
11
apps/console-lite-e2e/.env.capsule
Normal file
11
apps/console-lite-e2e/.env.capsule
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_VEGA_CONFIG_URL=''
|
||||||
|
NX_VEGA_ENV=CUSTOM
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
|
||||||
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
11
apps/console-lite-e2e/.env.stagnet3
Normal file
11
apps/console-lite-e2e/.env.stagnet3
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||||
|
NX_VEGA_ENV=STAGNET3
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
|
||||||
|
CYPRESS_VEGA_ENV=STAGNET3
|
||||||
|
CYPRESS_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
@ -1,7 +1,6 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
projectId: 'et4snf',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents(on, config) {
|
setupNodeEvents(on, config) {
|
||||||
require('@cypress/grep/src/plugin')(config);
|
require('@cypress/grep/src/plugin')(config);
|
||||||
@ -23,21 +22,6 @@ module.exports = defineConfig({
|
|||||||
viewportHeight: 900,
|
viewportHeight: 900,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
ETHEREUM_PROVIDER_URL:
|
|
||||||
'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
|
||||||
VEGA_PUBLIC_KEY:
|
|
||||||
'47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278',
|
|
||||||
VEGA_PUBLIC_KEY2:
|
|
||||||
'1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4',
|
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY: '47836c…c7d278',
|
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY2: '1a18cd…0cf2e4',
|
|
||||||
ETHEREUM_WALLET_ADDRESS: '0x265Cc6d39a1B53d0d92068443009eE7410807158',
|
|
||||||
ETHERSCAN_URL: 'https://sepolia.etherscan.io',
|
|
||||||
tsConfig: 'tsconfig.json',
|
|
||||||
TAGS: 'not @todo and not @ignore and not @manual',
|
|
||||||
TRADING_TEST_VEGA_WALLET_PASSPHRASE: '123',
|
|
||||||
ETH_WALLET_MNEMONIC:
|
|
||||||
'ugly gallery notice network true range brave clarify flat logic someone chunk',
|
|
||||||
grepTags: '@regression @smoke @slow',
|
grepTags: '@regression @smoke @slow',
|
||||||
grepFilterSpecs: true,
|
grepFilterSpecs: true,
|
||||||
grepOmitFiltered: true,
|
grepOmitFiltered: true,
|
||||||
|
@ -18,3 +18,4 @@ NX_EXPLORER_PARTIES=1
|
|||||||
NX_EXPLORER_VALIDATORS=1
|
NX_EXPLORER_VALIDATORS=1
|
||||||
|
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
@ -15,4 +15,5 @@ NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
|||||||
|
|
||||||
#Test configuration variables
|
#Test configuration variables
|
||||||
CYPRESS_FAIRGROUND=false
|
CYPRESS_FAIRGROUND=false
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
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_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
NX_VEGA_CONFIG_URL=''
|
||||||
NX_VEGA_ENV=STAGNET3
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_ENV=CUSTOM
|
||||||
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||||
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
|
||||||
CYPRESS_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
# Expose some env vars to cypress environment for market setup
|
||||||
|
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||||
|
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
CYPRESS_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
CYPRESS_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
CYPRESS_VEGA_ENV=STAGNET3
|
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
||||||
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
|
||||||
|
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
||||||
CYPRESS_VEGA_WALLET_API_TOKEN=
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
||||||
|
26
apps/trading-e2e/.env.capsule
Normal file
26
apps/trading-e2e/.env.capsule
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_VEGA_CONFIG_URL=''
|
||||||
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_ENV=CUSTOM
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||||
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
|
||||||
|
# Expose some env vars to cypress environment for market setup
|
||||||
|
CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit supply green clown session
|
||||||
|
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||||
|
CYPRESS_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
||||||
|
CYPRESS_VEGA_ENV=CUSTOM
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY=02eceaba4df2bef76ea10caf728d8a099a2aa846cced25737cccaa9812342f65
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY2=7f9cf07d3a9905b1a61a1069f7a758855da428bc0f4a97de87f48644bfc25535
|
||||||
|
CYPRESS_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
CYPRESS_VEGA_URL=http://localhost:3028/query
|
||||||
|
CYPRESS_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
22
apps/trading-e2e/.env.stagnet3
Normal file
22
apps/trading-e2e/.env.stagnet3
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||||
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||||
|
NX_VEGA_ENV=STAGNET3
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||||
|
NX_VEGA_TOKEN_URL=https://stagnet3.token.vega.xyz
|
||||||
|
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
|
||||||
|
CYPRESS_ETH_WALLET_MNEMONIC=ugly gallery notice network true range brave clarify flat logic someone chunk
|
||||||
|
CYPRESS_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=1a18cd…0cf2e4
|
||||||
|
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=47836c…c7d278
|
||||||
|
CYPRESS_VEGA_ENV=STAGNET3
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY=1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4
|
||||||
|
CYPRESS_VEGA_PUBLIC_KEY2=47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278
|
||||||
|
CYPRESS_VEGA_TOKEN_URL=https://stagnet3.token.vega.xyz
|
||||||
|
CYPRESS_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
|
||||||
|
CYPRESS_VEGA_WALLET_API_TOKEN=
|
@ -24,20 +24,17 @@ module.exports = defineConfig({
|
|||||||
requestTimeout: 20000,
|
requestTimeout: 20000,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
ETHEREUM_PROVIDER_URL:
|
|
||||||
'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
|
||||||
VEGA_PUBLIC_KEY:
|
VEGA_PUBLIC_KEY:
|
||||||
'47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278',
|
'47836c253520d2661bf5bed6339c0de08fd02cf5d4db0efee3b4373f20c7d278',
|
||||||
VEGA_PUBLIC_KEY2:
|
VEGA_PUBLIC_KEY2:
|
||||||
'1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4',
|
'1a18cdcaaa4f44a57b35a4e9b77e0701c17a476f2b407620f8c17371740cf2e4',
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY: '47836c…c7d278',
|
TRUNCATED_VEGA_PUBLIC_KEY: '47836c…c7d278',
|
||||||
TRUNCATED_VEGA_PUBLIC_KEY2: '1a18cd…0cf2e4',
|
TRUNCATED_VEGA_PUBLIC_KEY2: '1a18cd…0cf2e4',
|
||||||
|
ETHEREUM_PROVIDER_URL:
|
||||||
|
'https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8',
|
||||||
ETHEREUM_WALLET_ADDRESS: '0x265Cc6d39a1B53d0d92068443009eE7410807158',
|
ETHEREUM_WALLET_ADDRESS: '0x265Cc6d39a1B53d0d92068443009eE7410807158',
|
||||||
ETHERSCAN_URL: 'https://sepolia.etherscan.io',
|
ETHERSCAN_URL: 'https://sepolia.etherscan.io',
|
||||||
ETHEREUM_CHAIN_ID: 11155111,
|
ETHEREUM_CHAIN_ID: 11155111,
|
||||||
tsConfig: 'tsconfig.json',
|
|
||||||
TAGS: 'not @todo and not @ignore and not @manual',
|
|
||||||
TRADING_TEST_VEGA_WALLET_PASSPHRASE: '123',
|
|
||||||
ETH_WALLET_MNEMONIC:
|
ETH_WALLET_MNEMONIC:
|
||||||
'ugly gallery notice network true range brave clarify flat logic someone chunk',
|
'ugly gallery notice network true range brave clarify flat logic someone chunk',
|
||||||
TRADING_MODE_LINK:
|
TRADING_MODE_LINK:
|
||||||
|
152
apps/trading-e2e/src/integration/capsule.cy.ts
Normal file
152
apps/trading-e2e/src/integration/capsule.cy.ts
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { removeDecimal } from '@vegaprotocol/cypress';
|
||||||
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import {
|
||||||
|
OrderStatusMapping,
|
||||||
|
OrderTimeInForceMapping,
|
||||||
|
OrderTypeMapping,
|
||||||
|
Side,
|
||||||
|
} from '@vegaprotocol/types';
|
||||||
|
import { isBefore, isAfter, addSeconds, subSeconds } from 'date-fns';
|
||||||
|
import { createOrder } from '../support/create-order';
|
||||||
|
|
||||||
|
const orderSize = 'size';
|
||||||
|
const orderType = 'type';
|
||||||
|
const orderStatus = 'status';
|
||||||
|
const orderRemaining = 'remaining';
|
||||||
|
const orderPrice = 'price';
|
||||||
|
const orderTimeInForce = 'timeInForce';
|
||||||
|
const orderCreatedAt = 'createdAt';
|
||||||
|
const orderUpdatedAt = 'updatedAt';
|
||||||
|
|
||||||
|
// TODO: ensure this test runs only if capsule is running via workflow
|
||||||
|
describe('capsule', { tags: '@slow' }, () => {
|
||||||
|
before(() => {
|
||||||
|
cy.createMarket();
|
||||||
|
cy.get('@markets').then((markets) => {
|
||||||
|
cy.wrap(markets[0]).as('market');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.setVegaWallet();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can place and receive an order', function () {
|
||||||
|
const market = this.market;
|
||||||
|
cy.visit(`/#/markets/${market.id}`);
|
||||||
|
const order = {
|
||||||
|
marketId: market.id,
|
||||||
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
|
side: Schema.Side.SIDE_BUY,
|
||||||
|
size: '0.0005',
|
||||||
|
price: '390',
|
||||||
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
|
};
|
||||||
|
const rawPrice = removeDecimal(order.price, market.decimalPlaces);
|
||||||
|
const rawSize = removeDecimal(order.size, market.positionDecimalPlaces);
|
||||||
|
|
||||||
|
createOrder(order);
|
||||||
|
|
||||||
|
cy.getByTestId('dialog-title').should(
|
||||||
|
'contain.text',
|
||||||
|
'Awaiting network confirmation'
|
||||||
|
);
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Order submitted');
|
||||||
|
cy.getByTestId('dialog-close').click();
|
||||||
|
|
||||||
|
// orderbook cells are keyed by price level
|
||||||
|
cy.getByTestId('tab-orderbook')
|
||||||
|
.get(`[data-testid="price-${rawPrice}"]`)
|
||||||
|
.should('contain.text', order.price)
|
||||||
|
.get(`[data-testid="bid-vol-${rawPrice}"]`)
|
||||||
|
.should('contain.text', rawSize);
|
||||||
|
|
||||||
|
cy.getByTestId('Orders').click();
|
||||||
|
cy.getByTestId('tab-orders').within(() => {
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id='${orderSize}']`).should(
|
||||||
|
'contain.text',
|
||||||
|
order.side === Side.SIDE_BUY ? '+' : '-' + order.size
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get(`[col-id='${orderType}']`).should(
|
||||||
|
'contain.text',
|
||||||
|
OrderTypeMapping[order.type]
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get(`[col-id='${orderStatus}']`).should(
|
||||||
|
'contain.text',
|
||||||
|
OrderStatusMapping.STATUS_ACTIVE
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get(`[col-id='${orderRemaining}']`).should(
|
||||||
|
'contain.text',
|
||||||
|
`0.00/${order.size}`
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get(`[col-id='${orderPrice}']`).then(($price) => {
|
||||||
|
expect(parseFloat($price.text())).to.equal(parseFloat(order.price));
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get(`[col-id='${orderTimeInForce}']`).should(
|
||||||
|
'contain.text',
|
||||||
|
OrderTimeInForceMapping[order.timeInForce]
|
||||||
|
);
|
||||||
|
|
||||||
|
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderCreatedAt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('edit').first().click();
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Edit order');
|
||||||
|
cy.get('#limitPrice').focus().clear().type('200');
|
||||||
|
cy.getByTestId('edit-order').find('[type="submit"]').click();
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Order updated');
|
||||||
|
cy.getByTestId('dialog-close').click();
|
||||||
|
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id='${orderPrice}']`).then(($price) => {
|
||||||
|
expect(parseFloat($price.text())).to.equal(parseFloat('200'));
|
||||||
|
});
|
||||||
|
checkIfDataAndTimeOfCreationAndUpdateIsEqual(orderUpdatedAt);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.getByTestId('cancel').first().click();
|
||||||
|
|
||||||
|
cy.getByTestId('dialog-title').should(
|
||||||
|
'contain.text',
|
||||||
|
'Awaiting network confirmation'
|
||||||
|
);
|
||||||
|
cy.getByTestId('dialog-title').should('contain.text', 'Order cancelled');
|
||||||
|
cy.getByTestId('dialog-close').click();
|
||||||
|
|
||||||
|
cy.getByTestId('tab-orders')
|
||||||
|
.get('.ag-center-cols-container')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.get(`[col-id='${orderStatus}']`)
|
||||||
|
.should('contain.text', OrderStatusMapping.STATUS_CANCELLED);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
function checkIfDataAndTimeOfCreationAndUpdateIsEqual(date: string) {
|
||||||
|
cy.get(`[col-id='${date}']`)
|
||||||
|
.children('span')
|
||||||
|
.invoke('data', 'value')
|
||||||
|
.then(($dateTime) => {
|
||||||
|
// allow a date 5 seconds either side to allow for
|
||||||
|
// unexpected latency
|
||||||
|
const minBefore = subSeconds(new Date(), 5);
|
||||||
|
const maxAfter = addSeconds(new Date(), 5);
|
||||||
|
console.log(maxAfter);
|
||||||
|
const date = new Date($dateTime.toString());
|
||||||
|
expect(isAfter(date, minBefore) && isBefore(date, maxAfter)).to.equal(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
@ -96,11 +96,11 @@ describe('ethereum wallet', { tags: '@smoke' }, () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockWeb3Provider();
|
cy.mockWeb3Provider();
|
||||||
// Using portfolio withdrawals tab is it requires Ethereum wallet connection
|
// Using portfolio withdrawals tab is it requires Ethereum wallet connection
|
||||||
cy.visit('/#/portfolio');
|
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
|
cy.setVegaWallet();
|
||||||
|
cy.visit('/#/portfolio');
|
||||||
cy.get('main[data-testid="/portfolio"]').should('exist');
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
cy.connectVegaWallet();
|
|
||||||
cy.getByTestId('Withdrawals').click();
|
cy.getByTestId('Withdrawals').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('no markets found', () => {
|
describe('no markets found', () => {
|
||||||
it('redirects to a the empty market page and displays welcome notice', () => {
|
beforeEach(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
const data = {
|
const data = {
|
||||||
marketsConnection: {
|
marketsConnection: {
|
||||||
@ -159,6 +159,8 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Markets');
|
cy.wait('@Markets');
|
||||||
cy.wait('@MarketsData');
|
cy.wait('@MarketsData');
|
||||||
|
});
|
||||||
|
it('redirects to a the empty market page and displays welcome notice', () => {
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets`);
|
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets`);
|
||||||
cy.getByTestId('welcome-notice-title').should(
|
cy.getByTestId('welcome-notice-title').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
|
@ -49,7 +49,7 @@ describe('Market proposal notification', { tags: '@smoke' }, () => {
|
|||||||
cy.getByTestId('external-link').should(
|
cy.getByTestId('external-link').should(
|
||||||
'have.attr',
|
'have.attr',
|
||||||
'href',
|
'href',
|
||||||
'https://stagnet3.token.vega.xyz/proposals/123'
|
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/123`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -108,7 +108,7 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
.and(
|
.and(
|
||||||
'have.attr',
|
'have.attr',
|
||||||
'href',
|
'href',
|
||||||
'https://stagnet3.token.vega.xyz/proposals/propose/new-market'
|
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@ import { aliasGQLQuery, mockConnectWallet } from '@vegaprotocol/cypress';
|
|||||||
import { testOrderSubmission } from '../support/order-validation';
|
import { testOrderSubmission } from '../support/order-validation';
|
||||||
import type { OrderSubmission } from '@vegaprotocol/wallet';
|
import type { OrderSubmission } from '@vegaprotocol/wallet';
|
||||||
import { accountsQuery, estimateOrderQuery } from '@vegaprotocol/mock';
|
import { accountsQuery, estimateOrderQuery } from '@vegaprotocol/mock';
|
||||||
|
import { createOrder } from '../support/create-order';
|
||||||
|
|
||||||
const orderSizeField = 'order-size';
|
const orderSizeField = 'order-size';
|
||||||
const orderPriceField = 'order-price';
|
const orderPriceField = 'order-price';
|
||||||
@ -717,22 +718,3 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const createOrder = (order: OrderSubmission): void => {
|
|
||||||
const { type, side, size, price, timeInForce, expiresAt } = order;
|
|
||||||
|
|
||||||
cy.getByTestId(`order-type-${type}`).click();
|
|
||||||
cy.getByTestId(`order-side-${side}`).click();
|
|
||||||
cy.getByTestId(orderSizeField).clear().type(size);
|
|
||||||
if (price) {
|
|
||||||
cy.getByTestId(orderPriceField).clear().type(price);
|
|
||||||
}
|
|
||||||
cy.getByTestId(orderTIFDropDown).select(timeInForce);
|
|
||||||
if (timeInForce === 'TIME_IN_FORCE_GTT') {
|
|
||||||
if (!expiresAt) {
|
|
||||||
throw new Error('Specify expiresAt if using GTT');
|
|
||||||
}
|
|
||||||
cy.getByTestId('date-picker-field').type(expiresAt);
|
|
||||||
}
|
|
||||||
cy.getByTestId(placeOrderBtn).click();
|
|
||||||
};
|
|
||||||
|
@ -35,6 +35,7 @@ describe('orders list', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
cy.wait('@Markets');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders orders', () => {
|
it('renders orders', () => {
|
||||||
cy.getByTestId('tab-orders').should('be.visible');
|
cy.getByTestId('tab-orders').should('be.visible');
|
||||||
cy.getByTestId(cancelAllOrdersBtn).should('be.visible');
|
cy.getByTestId(cancelAllOrdersBtn).should('be.visible');
|
||||||
|
@ -66,6 +66,9 @@ describe('withdraw form validation', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('withdraw actions', { tags: '@regression' }, () => {
|
describe('withdraw actions', { tags: '@regression' }, () => {
|
||||||
|
// this is extremely ugly hack, but setting it properly in contract is too much effort for such simple validation
|
||||||
|
const withdrawalThreshold =
|
||||||
|
Cypress.env('VEGA_ENV') === 'CUSTOM' ? '0.00' : '100.00';
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.mockWeb3Provider();
|
cy.mockWeb3Provider();
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
@ -96,7 +99,7 @@ describe('withdraw actions', { tags: '@regression' }, () => {
|
|||||||
);
|
);
|
||||||
cy.getByTestId('WITHDRAWAL_THRESHOLD_value').should(
|
cy.getByTestId('WITHDRAWAL_THRESHOLD_value').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'100.00'
|
withdrawalThreshold
|
||||||
);
|
);
|
||||||
cy.getByTestId('DELAY_TIME_label').should('contain.text', 'Delay time');
|
cy.getByTestId('DELAY_TIME_label').should('contain.text', 'Delay time');
|
||||||
cy.getByTestId('DELAY_TIME_value').should('have.text', 'None');
|
cy.getByTestId('DELAY_TIME_value').should('have.text', 'None');
|
||||||
|
26
apps/trading-e2e/src/support/create-order.ts
Normal file
26
apps/trading-e2e/src/support/create-order.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import type { OrderSubmission } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
|
const orderSizeField = 'order-size';
|
||||||
|
const orderPriceField = 'order-price';
|
||||||
|
const orderTIFDropDown = 'order-tif';
|
||||||
|
const placeOrderBtn = 'place-order';
|
||||||
|
|
||||||
|
export const createOrder = (order: OrderSubmission): void => {
|
||||||
|
cy.log('Placing order', order);
|
||||||
|
const { type, side, size, price, timeInForce, expiresAt } = order;
|
||||||
|
|
||||||
|
cy.getByTestId(`order-type-${type}`).click();
|
||||||
|
cy.getByTestId(`order-side-${side}`).click();
|
||||||
|
cy.getByTestId(orderSizeField).clear().type(size);
|
||||||
|
if (price) {
|
||||||
|
cy.getByTestId(orderPriceField).clear().type(price);
|
||||||
|
}
|
||||||
|
cy.getByTestId(orderTIFDropDown).select(timeInForce);
|
||||||
|
if (timeInForce === 'TIME_IN_FORCE_GTT') {
|
||||||
|
if (!expiresAt) {
|
||||||
|
throw new Error('Specify expiresAt if using GTT');
|
||||||
|
}
|
||||||
|
cy.getByTestId('date-picker-field').type(expiresAt);
|
||||||
|
}
|
||||||
|
cy.getByTestId(placeOrderBtn).click();
|
||||||
|
};
|
@ -2,5 +2,6 @@ import '@vegaprotocol/cypress';
|
|||||||
import 'cypress-real-events/support';
|
import 'cypress-real-events/support';
|
||||||
import registerCypressGrep from '@cypress/grep';
|
import registerCypressGrep from '@cypress/grep';
|
||||||
import { addMockTradingPage } from './trading';
|
import { addMockTradingPage } from './trading';
|
||||||
|
|
||||||
registerCypressGrep();
|
registerCypressGrep();
|
||||||
addMockTradingPage();
|
addMockTradingPage();
|
||||||
|
@ -61,7 +61,7 @@ const vegaWalletTransaction = (transaction: Transaction) => {
|
|||||||
.should('deep.equal', {
|
.should('deep.equal', {
|
||||||
token: JSON.parse(localStorage.getItem('vega_wallet_config') || '{}')
|
token: JSON.parse(localStorage.getItem('vega_wallet_config') || '{}')
|
||||||
?.token,
|
?.token,
|
||||||
publicKey: Cypress.env('VEGA_PUBLIC_KEY2'),
|
publicKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||||
sendingMode: 'TYPE_SYNC',
|
sendingMode: 'TYPE_SYNC',
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
|
11
apps/trading/.env.capsule
Normal file
11
apps/trading/.env.capsule
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||||
|
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||||
|
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||||
|
NX_VEGA_CONFIG_URL=''
|
||||||
|
NX_VEGA_ENV=CUSTOM
|
||||||
|
NX_VEGA_EXPLORER_URL=https://stagnet3.explorer.vega.xyz
|
||||||
|
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"STAGNET3\":\"https://stagnet3.console.vega.xyz\"}
|
||||||
|
NX_VEGA_TOKEN_URL=https://token.fairground.wtf
|
||||||
|
NX_VEGA_URL=http://localhost:3028/query
|
||||||
|
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||||
|
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
@ -15,6 +15,7 @@ import {
|
|||||||
addSetVegaWallet,
|
addSetVegaWallet,
|
||||||
} from './lib/commands/vega-wallet-connect';
|
} from './lib/commands/vega-wallet-connect';
|
||||||
import { addMockTransactionResponse } from './lib/commands/mock-transaction-response';
|
import { addMockTransactionResponse } from './lib/commands/mock-transaction-response';
|
||||||
|
import { addCreateMarket } from './lib/commands/create-market';
|
||||||
|
|
||||||
addGetTestIdcommand();
|
addGetTestIdcommand();
|
||||||
addSlackCommand();
|
addSlackCommand();
|
||||||
@ -31,11 +32,13 @@ addUpdateCapsuleMultiSig();
|
|||||||
addVegaWalletConnect();
|
addVegaWalletConnect();
|
||||||
addSetVegaWallet();
|
addSetVegaWallet();
|
||||||
addMockTransactionResponse();
|
addMockTransactionResponse();
|
||||||
|
addCreateMarket();
|
||||||
|
|
||||||
export { mockConnectWallet } from './lib/commands/vega-wallet-connect';
|
export { mockConnectWallet } from './lib/commands/vega-wallet-connect';
|
||||||
export type { onMessage } from './lib/mock-ws';
|
export type { onMessage } from './lib/mock-ws';
|
||||||
export { aliasGQLQuery } from './lib/mock-gql';
|
export { aliasGQLQuery } from './lib/mock-gql';
|
||||||
export { aliasWalletQuery } from './lib/mock-rest';
|
export { aliasWalletQuery } from './lib/mock-rest';
|
||||||
|
export * from './lib/utils';
|
||||||
|
|
||||||
Cypress.on(
|
Cypress.on(
|
||||||
'uncaught:exception',
|
'uncaught:exception',
|
||||||
|
137
libs/cypress/src/lib/capsule/create-market.ts
Normal file
137
libs/cypress/src/lib/capsule/create-market.ts
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { determineId } from '../utils';
|
||||||
|
import { requestGQL, setEndpoints } from './request';
|
||||||
|
import { vote } from './vote';
|
||||||
|
import { setupEthereumAccount } from './ethereum-setup';
|
||||||
|
import { faucetAsset } from './faucet-asset';
|
||||||
|
import {
|
||||||
|
proposeMarket,
|
||||||
|
waitForEnactment,
|
||||||
|
waitForProposal,
|
||||||
|
} from './propose-market';
|
||||||
|
import { createLog } from './logging';
|
||||||
|
|
||||||
|
const log = createLog('create-market');
|
||||||
|
|
||||||
|
export async function createMarket(cfg: {
|
||||||
|
vegaPubKey: string;
|
||||||
|
token: string;
|
||||||
|
ethWalletMnemonic: string;
|
||||||
|
ethereumProviderUrl: string;
|
||||||
|
vegaWalletUrl: string;
|
||||||
|
vegaUrl: string;
|
||||||
|
faucetUrl: string;
|
||||||
|
}) {
|
||||||
|
// set and store request endpoints
|
||||||
|
setEndpoints(cfg.vegaWalletUrl, cfg.vegaUrl);
|
||||||
|
|
||||||
|
const markets = await getMarkets();
|
||||||
|
|
||||||
|
if (markets.length) {
|
||||||
|
log(
|
||||||
|
`${markets.length} market${
|
||||||
|
markets.length > 1 ? 's' : ''
|
||||||
|
} found, skipping market creation`
|
||||||
|
);
|
||||||
|
return markets;
|
||||||
|
}
|
||||||
|
|
||||||
|
await setupEthereumAccount(
|
||||||
|
cfg.vegaPubKey,
|
||||||
|
cfg.ethWalletMnemonic,
|
||||||
|
cfg.ethereumProviderUrl
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await faucetAsset(cfg.faucetUrl, 'fUSDC', cfg.vegaPubKey);
|
||||||
|
if (!result.success) {
|
||||||
|
throw new Error('faucet failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// propose and vote on a market
|
||||||
|
const proposalTxResult = await proposeMarket(cfg.vegaPubKey, cfg.token);
|
||||||
|
const proposalId = determineId(proposalTxResult.transaction.signature.value);
|
||||||
|
log(`proposal created (id: ${proposalId})`);
|
||||||
|
const proposal = await waitForProposal(proposalId);
|
||||||
|
await vote(
|
||||||
|
proposal.id,
|
||||||
|
Schema.VoteValue.VALUE_YES,
|
||||||
|
cfg.vegaPubKey,
|
||||||
|
cfg.token
|
||||||
|
);
|
||||||
|
await waitForEnactment();
|
||||||
|
|
||||||
|
// fetch and return created market
|
||||||
|
const newMarkets = await getMarkets();
|
||||||
|
return newMarkets;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMarkets() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
marketsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
|
state
|
||||||
|
tradableInstrument {
|
||||||
|
instrument {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
code
|
||||||
|
metadata {
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
product {
|
||||||
|
... on Future {
|
||||||
|
settlementAsset {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
decimals
|
||||||
|
}
|
||||||
|
quoteName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
marketsConnection: {
|
||||||
|
edges: Array<{
|
||||||
|
node: {
|
||||||
|
id: string;
|
||||||
|
decimalPlaces: number;
|
||||||
|
positionDecimalPlaces: number;
|
||||||
|
state: string;
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
metadata: {
|
||||||
|
tags: string[];
|
||||||
|
};
|
||||||
|
product: {
|
||||||
|
settlementAssset: {
|
||||||
|
id: string;
|
||||||
|
symbol: string;
|
||||||
|
decimals: number;
|
||||||
|
};
|
||||||
|
quoteName: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
return res.marketsConnection.edges.map((e) => e.node);
|
||||||
|
}
|
191
libs/cypress/src/lib/capsule/ethereum-setup.ts
Normal file
191
libs/cypress/src/lib/capsule/ethereum-setup.ts
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
import { ethers, Wallet } from 'ethers';
|
||||||
|
import { StakingBridge, Token } from '@vegaprotocol/smart-contracts';
|
||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
import { createLog } from './logging';
|
||||||
|
|
||||||
|
const log = createLog('ethereum-setup');
|
||||||
|
|
||||||
|
export async function setupEthereumAccount(
|
||||||
|
vegaPublicKey: string,
|
||||||
|
ethWalletMnemonic: string,
|
||||||
|
ethereumProviderUrl: string
|
||||||
|
) {
|
||||||
|
// create provider/wallet
|
||||||
|
const provider = new ethers.providers.JsonRpcProvider({
|
||||||
|
url: ethereumProviderUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
const privateKey = Wallet.fromMnemonic(
|
||||||
|
ethWalletMnemonic,
|
||||||
|
getAccount()
|
||||||
|
).privateKey;
|
||||||
|
|
||||||
|
// this wallet (ozone access etc) is already set up with 6 million vega (eth)
|
||||||
|
const wallet = new Wallet(privateKey, provider);
|
||||||
|
|
||||||
|
const vegaAsset = await getVegaAsset();
|
||||||
|
if (!vegaAsset) {
|
||||||
|
throw new Error('could not fetch asset');
|
||||||
|
}
|
||||||
|
|
||||||
|
const ethereumConfig = await getEthereumConfig();
|
||||||
|
if (!ethereumConfig) {
|
||||||
|
throw new Error('could not not fetch ethereum config');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokenContract = new Token(vegaAsset.source.contractAddress, wallet);
|
||||||
|
|
||||||
|
log('sending approve tx');
|
||||||
|
const approveTx = await promiseWithTimeout(
|
||||||
|
tokenContract.approve(
|
||||||
|
ethereumConfig.staking_bridge_contract.address,
|
||||||
|
'100000' + '0'.repeat(18)
|
||||||
|
),
|
||||||
|
1000,
|
||||||
|
'tokenContract.approve'
|
||||||
|
);
|
||||||
|
|
||||||
|
await promiseWithTimeout(
|
||||||
|
approveTx.wait(1),
|
||||||
|
10 * 60 * 1000,
|
||||||
|
'approveTx.wait(1)'
|
||||||
|
);
|
||||||
|
log('sending approve tx: success');
|
||||||
|
|
||||||
|
const stakingContract = new StakingBridge(
|
||||||
|
ethereumConfig.staking_bridge_contract.address,
|
||||||
|
wallet
|
||||||
|
);
|
||||||
|
|
||||||
|
const amount = '10000' + '0'.repeat(18);
|
||||||
|
log(`sending stake tx of ${amount} to ${vegaPublicKey}`);
|
||||||
|
const stakeTx = await promiseWithTimeout(
|
||||||
|
stakingContract.stake(amount, vegaPublicKey),
|
||||||
|
14000,
|
||||||
|
'stakingContract.stake(amount, vegaPublicKey)'
|
||||||
|
);
|
||||||
|
await promiseWithTimeout(stakeTx.wait(3), 10 * 60 * 1000, 'stakeTx.wait(3)');
|
||||||
|
await waitForStake(vegaPublicKey);
|
||||||
|
log(`sending stake tx: success`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeout(time = 0, id: string) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(() => reject(new Error(`${id}: timeout triggered`)), time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promiseWithTimeout(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
promise: Promise<any>,
|
||||||
|
time: number,
|
||||||
|
id: string
|
||||||
|
) {
|
||||||
|
return await Promise.race([promise, timeout(time, id)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getVegaAsset() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
assetsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
source {
|
||||||
|
... on ERC20 {
|
||||||
|
contractAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
assetsConnection: {
|
||||||
|
edges: Array<{
|
||||||
|
node: {
|
||||||
|
id: string;
|
||||||
|
symbol: string;
|
||||||
|
source: {
|
||||||
|
contractAddress: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
return res.assetsConnection.edges
|
||||||
|
.map((e) => e.node)
|
||||||
|
.find((a) => a.symbol === 'VEGA');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getEthereumConfig() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
networkParameter(key: "blockchains.ethereumConfig") {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
networkParameter: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
return JSON.parse(res.networkParameter.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitForStake(vegaPublicKey: string) {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
party(id:"${vegaPublicKey}") {
|
||||||
|
stakingSummary {
|
||||||
|
currentStakeAvailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let tick = 1;
|
||||||
|
const interval = setInterval(async () => {
|
||||||
|
log(`confirming stake (attempt: ${tick})`);
|
||||||
|
if (tick >= 10) {
|
||||||
|
clearInterval(interval);
|
||||||
|
reject(new Error('stake link never seen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await requestGQL<{
|
||||||
|
party: {
|
||||||
|
stakingSummary: {
|
||||||
|
currentStakeAvailable: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
if (
|
||||||
|
res.party?.stakingSummary?.currentStakeAvailable !== null &&
|
||||||
|
parseInt(res.party.stakingSummary.currentStakeAvailable) > 0
|
||||||
|
) {
|
||||||
|
log(
|
||||||
|
`stake confirmed (amount: ${res.party.stakingSummary.currentStakeAvailable})`
|
||||||
|
);
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve(res.party.stakingSummary.currentStakeAvailable);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// no op, query will error until party is created
|
||||||
|
}
|
||||||
|
|
||||||
|
tick++;
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// derivation path
|
||||||
|
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
23
libs/cypress/src/lib/capsule/faucet-asset.ts
Normal file
23
libs/cypress/src/lib/capsule/faucet-asset.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { createLog } from './logging';
|
||||||
|
|
||||||
|
const log = createLog('faucet-asset');
|
||||||
|
|
||||||
|
export async function faucetAsset(
|
||||||
|
url: string,
|
||||||
|
asset: string,
|
||||||
|
party: string,
|
||||||
|
amount = '10000'
|
||||||
|
) {
|
||||||
|
log(`sending ${amount} ${asset} to ${party}`);
|
||||||
|
const res = await fetch(url, {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify({
|
||||||
|
amount,
|
||||||
|
asset,
|
||||||
|
party,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const json = await res.json();
|
||||||
|
|
||||||
|
return json;
|
||||||
|
}
|
5
libs/cypress/src/lib/capsule/logging.ts
Normal file
5
libs/cypress/src/lib/capsule/logging.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function createLog(name: string) {
|
||||||
|
return (message: string) => {
|
||||||
|
console.log(`[${name}]: ${message}`);
|
||||||
|
};
|
||||||
|
}
|
192
libs/cypress/src/lib/capsule/propose-market.ts
Normal file
192
libs/cypress/src/lib/capsule/propose-market.ts
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import { addSeconds, millisecondsToSeconds } from 'date-fns';
|
||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { request, requestGQL } from './request';
|
||||||
|
import { createLog } from './logging';
|
||||||
|
import type { ProposalSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
|
const log = createLog('propose-market');
|
||||||
|
|
||||||
|
const MIN_CLOSE_SEC = 5;
|
||||||
|
const MIN_ENACT_SEC = 3;
|
||||||
|
|
||||||
|
export async function proposeMarket(publicKey: string, token: string) {
|
||||||
|
log('sending proposal tx');
|
||||||
|
const proposalTx = createNewMarketProposal();
|
||||||
|
const result = await request('client.send_transaction', {
|
||||||
|
token,
|
||||||
|
publicKey,
|
||||||
|
sendingMode: 'TYPE_SYNC',
|
||||||
|
transaction: proposalTx,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNewMarketProposal(): ProposalSubmissionBody {
|
||||||
|
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: 'Add Lorem Ipsum market',
|
||||||
|
description: 'An example proposal to add Lorem Ipsum market',
|
||||||
|
},
|
||||||
|
terms: {
|
||||||
|
newMarket: {
|
||||||
|
changes: {
|
||||||
|
decimalPlaces: '5',
|
||||||
|
positionDecimalPlaces: '5',
|
||||||
|
lpPriceRange: '10',
|
||||||
|
instrument: {
|
||||||
|
name: 'Test market 1',
|
||||||
|
code: 'TEST.24h',
|
||||||
|
future: {
|
||||||
|
settlementAsset: 'fUSDC',
|
||||||
|
quoteName: 'fUSDC',
|
||||||
|
dataSourceSpecForSettlementData: {
|
||||||
|
external: {
|
||||||
|
oracle: {
|
||||||
|
signers: [
|
||||||
|
{
|
||||||
|
pubKey: {
|
||||||
|
key: '0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
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 waitForProposal(id: string): Promise<{ id: string }> {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
proposal(id: "${id}") {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let tick = 0;
|
||||||
|
const interval = setInterval(async () => {
|
||||||
|
if (tick >= 60) {
|
||||||
|
clearInterval(interval);
|
||||||
|
reject(new Error('proposal never seen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await requestGQL<{
|
||||||
|
proposal: {
|
||||||
|
id: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
if (
|
||||||
|
res.proposal !== null &&
|
||||||
|
res.proposal.state === Schema.ProposalState.STATE_OPEN
|
||||||
|
) {
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve(res.proposal);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
tick++;
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function waitForEnactment() {
|
||||||
|
const timeout = MIN_CLOSE_SEC * 1000 + MIN_ENACT_SEC * 1000;
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, timeout + 2000);
|
||||||
|
});
|
||||||
|
}
|
39
libs/cypress/src/lib/capsule/request.ts
Normal file
39
libs/cypress/src/lib/capsule/request.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { request as gqlRequest } from 'graphql-request';
|
||||||
|
|
||||||
|
let walletEndpoint = '';
|
||||||
|
let gqlEndpoint = '';
|
||||||
|
|
||||||
|
export function setEndpoints(walletUrl: string, gqlUrl: string) {
|
||||||
|
walletEndpoint = walletUrl + '/api/v2/requests';
|
||||||
|
gqlEndpoint = gqlUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function request(method: string, params: object) {
|
||||||
|
if (!walletEndpoint) {
|
||||||
|
throw new Error('gqlEndpoint not set');
|
||||||
|
}
|
||||||
|
const body = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
id: Math.random().toString(),
|
||||||
|
};
|
||||||
|
return fetch(walletEndpoint, {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Origin: 'market-setup',
|
||||||
|
Referer: 'market-setup',
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
return res.json();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requestGQL<T>(query: string): Promise<T> {
|
||||||
|
if (!gqlEndpoint) {
|
||||||
|
throw new Error('gqlEndpoint not set');
|
||||||
|
}
|
||||||
|
return gqlRequest(gqlEndpoint, query);
|
||||||
|
}
|
33
libs/cypress/src/lib/capsule/vote.ts
Normal file
33
libs/cypress/src/lib/capsule/vote.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type * as Schema from '@vegaprotocol/types';
|
||||||
|
import { request } from './request';
|
||||||
|
import { createLog } from './logging';
|
||||||
|
|
||||||
|
const log = createLog('vote');
|
||||||
|
|
||||||
|
export async function vote(
|
||||||
|
proposalId: string,
|
||||||
|
voteValue: Schema.VoteValue,
|
||||||
|
publicKey: string,
|
||||||
|
token: string
|
||||||
|
) {
|
||||||
|
log(`voting ${voteValue} on ${proposalId}`);
|
||||||
|
|
||||||
|
const voteTx = createVote(proposalId, voteValue);
|
||||||
|
const voteResult = await request('client.send_transaction', {
|
||||||
|
token,
|
||||||
|
publicKey,
|
||||||
|
sendingMode: 'TYPE_SYNC',
|
||||||
|
transaction: voteTx,
|
||||||
|
});
|
||||||
|
|
||||||
|
return voteResult.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createVote(proposalId: string, value: Schema.VoteValue) {
|
||||||
|
return {
|
||||||
|
voteSubmission: {
|
||||||
|
value,
|
||||||
|
proposalId,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
50
libs/cypress/src/lib/commands/create-market.ts
Normal file
50
libs/cypress/src/lib/commands/create-market.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { createMarket } from '../capsule/create-market';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||||
|
namespace Cypress {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface Chainable<Subject> {
|
||||||
|
createMarket(): void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// suppress fetch and xhr logs
|
||||||
|
const originalLog = Cypress.log;
|
||||||
|
// @ts-ignore fuck with log to help with debug
|
||||||
|
Cypress.log = function (options, ...rest) {
|
||||||
|
// @ts-ignore fuck with log to help with debug
|
||||||
|
const isRequest = ['fetch', 'xhr'].includes(options.displayName);
|
||||||
|
if (isRequest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalLog(options, ...rest);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const addCreateMarket = () => {
|
||||||
|
Cypress.Commands.add('createMarket', () => {
|
||||||
|
const config = {
|
||||||
|
vegaPubKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||||
|
token: Cypress.env('VEGA_WALLET_API_TOKEN'),
|
||||||
|
ethWalletMnemonic: Cypress.env('ETH_WALLET_MNEMONIC'),
|
||||||
|
ethereumProviderUrl: Cypress.env('ETHEREUM_PROVIDER_URL'),
|
||||||
|
vegaWalletUrl: Cypress.env('VEGA_WALLET_URL'),
|
||||||
|
vegaUrl: Cypress.env('VEGA_URL'),
|
||||||
|
faucetUrl: Cypress.env('FAUCET_URL'),
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.highlight('creating market on capsule environment');
|
||||||
|
|
||||||
|
cy.wrap(createMarket(config), {
|
||||||
|
timeout: 5 * 60 * 1000,
|
||||||
|
})
|
||||||
|
// register market list result so it can be retrieved in tests later
|
||||||
|
.as('markets');
|
||||||
|
|
||||||
|
// make sure we have a market to test against, createMarket will
|
||||||
|
// return an array of markets or false if setup failed
|
||||||
|
cy.get('@markets').should('not.equal', false);
|
||||||
|
});
|
||||||
|
};
|
@ -21,7 +21,7 @@ const hasOperationName = (
|
|||||||
|
|
||||||
export function addMockGQLCommand() {
|
export function addMockGQLCommand() {
|
||||||
Cypress.Commands.add('mockGQL', (handler: RouteHandler) => {
|
Cypress.Commands.add('mockGQL', (handler: RouteHandler) => {
|
||||||
cy.intercept('POST', '**/graphql', handler).as('GQL');
|
cy.intercept('POST', Cypress.env('VEGA_URL'), handler).as('GQL');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
libs/cypress/src/lib/utils.ts
Normal file
20
libs/cypress/src/lib/utils.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { ethers } from 'ethers';
|
||||||
|
import sha3 from 'js-sha3';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy of determineId in libs/wallet/src/utils.ts
|
||||||
|
* to avoid pulling in any jsx files which will cypress is not set up to compile
|
||||||
|
*/
|
||||||
|
export function determineId(sig: string) {
|
||||||
|
return sha3.sha3_256(ethers.utils.arrayify('0x' + sig));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy of removeDecimal from libs/react-helpers/src/lib/format/number.tsx
|
||||||
|
* to avoid pulling in any jsx files which will cypress is not set up to compile
|
||||||
|
*/
|
||||||
|
export function removeDecimal(value: string, decimals: number): string {
|
||||||
|
if (!decimals) return value;
|
||||||
|
return new BigNumber(value || 0).times(Math.pow(10, decimals)).toFixed(0);
|
||||||
|
}
|
@ -47,6 +47,16 @@ export const MarketListTable = forwardRef<
|
|||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
headerName={t('Market')}
|
headerName={t('Market')}
|
||||||
field="tradableInstrument.instrument.code"
|
field="tradableInstrument.instrument.code"
|
||||||
|
cellRenderer={({
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
}: VegaICellRendererParams<
|
||||||
|
MarketWithData,
|
||||||
|
'tradableInstrument.instrument.code'
|
||||||
|
>) => {
|
||||||
|
if (!data) return null;
|
||||||
|
return <span data-testid={`market-${data.id}`}>{value}</span>;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
headerName={t('Description')}
|
headerName={t('Description')}
|
||||||
|
@ -209,20 +209,29 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
|||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
field="createdAt"
|
field="createdAt"
|
||||||
valueFormatter={({
|
cellRenderer={({
|
||||||
|
data,
|
||||||
value,
|
value,
|
||||||
}: VegaValueFormatterParams<Order, 'createdAt'>) => {
|
}: VegaICellRendererParams<Order, 'createdAt'>) => {
|
||||||
return value ? getDateTimeFormat().format(new Date(value)) : value;
|
return (
|
||||||
|
<span data-value={value}>
|
||||||
|
{value ? getDateTimeFormat().format(new Date(value)) : value}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
field="updatedAt"
|
field="updatedAt"
|
||||||
filter={DateRangeFilter}
|
filter={DateRangeFilter}
|
||||||
valueFormatter={({
|
cellRenderer={({
|
||||||
|
data,
|
||||||
value,
|
value,
|
||||||
node,
|
}: VegaICellRendererParams<Order, 'updatedAt'>) => {
|
||||||
}: VegaValueFormatterParams<Order, 'updatedAt'>) => {
|
return (
|
||||||
return value ? getDateTimeFormat().format(new Date(value)) : '-';
|
<span data-value={value}>
|
||||||
|
{value ? getDateTimeFormat().format(new Date(value)) : '-'}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
"env-cmd": "^10.1.0",
|
"env-cmd": "^10.1.0",
|
||||||
"ethers": "^5.6.0",
|
"ethers": "^5.6.0",
|
||||||
"graphql": "^15.7.2",
|
"graphql": "^15.7.2",
|
||||||
|
"graphql-request": "^5.0.0",
|
||||||
"graphql-ws": "^5.6.3",
|
"graphql-ws": "^5.6.3",
|
||||||
"i18next": "^20.3.5",
|
"i18next": "^20.3.5",
|
||||||
"i18next-browser-languagedetector": "^6.1.2",
|
"i18next-browser-languagedetector": "^6.1.2",
|
||||||
|
@ -181,6 +181,7 @@
|
|||||||
"governance.proposal.market.minClose": "2s",
|
"governance.proposal.market.minClose": "2s",
|
||||||
"governance.proposal.market.minEnact": "2s",
|
"governance.proposal.market.minEnact": "2s",
|
||||||
"governance.proposal.market.requiredParticipation": "0.00000000000000000000000015",
|
"governance.proposal.market.requiredParticipation": "0.00000000000000000000000015",
|
||||||
|
"governance.proposal.market.requiredMajority": "0.00000000000000000000000015",
|
||||||
"governance.proposal.updateMarket.minClose": "2s",
|
"governance.proposal.updateMarket.minClose": "2s",
|
||||||
"governance.proposal.updateMarket.minEnact": "2s",
|
"governance.proposal.updateMarket.minEnact": "2s",
|
||||||
"governance.proposal.updateMarket.requiredParticipation": "0.00000000000000000000000015",
|
"governance.proposal.updateMarket.requiredParticipation": "0.00000000000000000000000015",
|
||||||
|
Loading…
Reference in New Issue
Block a user