From 205f4124f1e02087b6e1bd64e1aa767810ee71da Mon Sep 17 00:00:00 2001 From: Joe Tsang <30622993+jtsang586@users.noreply.github.com> Date: Mon, 4 Apr 2022 16:11:27 +0100 Subject: [PATCH] Test/deal ticket tests (#161) * scaffold dealticket package, remove trading views from react-helpers * add deal ticket component, add intent utils, expand dialog and form group styles * add splash component, show market not found message if market doesnt exist * tidy up error handling * add handleError method for vega tx hook * add better testname for provider test, flesh out tests a bit more for deal ticket * Add unit tests for useVegaTransaction and useOrderSubmit hooks * add wrapper component for order dialog styles * add vega styled loader to ui toolkit and use in order dialog * add title prop to order dialog * split limit and market tickets into own files * add button radio component * revert dialog styles * move splash component to ui-toolkit, add story * convert intent to enum * Make button always type=button unless type prop is passed * inline filter logic for tif selector * add date-fns, add datetime to helpers * add order types to wallet package, make price undefined if order type is market * use enums in deal ticket logic * tidy up order state by moving submit and transaction hooks out of deal ticket * add comment for dialog styles * remove decimal from price input * add types package, delete old generated types from trading project * rename types package to graphql * update generate command to point to correct locations * fix use order submit test * BDD and navigation tests passing * Remove commented steps * Steps up to placing order * Date picker and date-fns update * Vega connector wallet tests * Passing up to request sent, updated date picker * Tests for sell orders and errors * Update market feature * Fix failing tests * Update wallet login * Readded tx hash assertion and remaining tests * Add CI wallet import * Update .github/workflows/cypress.yml Co-authored-by: Dexter Edwards * Resolved PR comments * Fix yaml error * Attempt to fix failing tests in CI * Run Cypress in Chrome * Add reload if public key error displayed * Fix wallet name * Add force click and waits * Increase timeout for deal ticket page * Removed network list from yaml and using input error id * Increase timeout to 8 seconds * Re add deleted test id Co-authored-by: Matthew Russell Co-authored-by: Dexter Edwards --- .github/workflows/cypress.yml | 51 +++++++- apps/explorer-e2e/cypress.json | 3 +- .../.cypress-cucumber-preprocessorrc | 3 + apps/trading-e2e/cypress.json | 13 +- apps/trading-e2e/src/integration/app.spec.ts | 13 -- .../src/integration/home-page.feature | 18 +++ .../src/integration/market-order.feature | 98 +++++++++++++++ apps/trading-e2e/src/plugins/index.js | 75 ++++++++++++ apps/trading-e2e/src/support/commands.ts | 4 + .../src/support/pages/base-page.js | 56 +++++++++ .../src/support/pages/deal-ticket-page.js | 114 ++++++++++++++++++ .../src/support/pages/markets-page.js | 54 +++++++++ .../support/step_definitions/common-step.js | 27 +++++ .../step_definitions/home-page.step.js | 22 ++++ .../step_definitions/market-order.step.js | 65 ++++++++++ .../vega-wallet-connect-button.tsx | 1 + apps/trading/pages/markets/grid-tabs.tsx | 6 +- apps/trading/pages/markets/trade-grid.tsx | 1 + libs/deal-ticket/src/expiry-selector.tsx | 1 + libs/deal-ticket/src/order-dialog.tsx | 14 ++- libs/deal-ticket/src/submit-button.tsx | 1 + .../components/input-error/input-error.tsx | 6 +- libs/wallet/src/rest-connector-form.tsx | 6 +- 23 files changed, 626 insertions(+), 26 deletions(-) create mode 100644 apps/trading-e2e/.cypress-cucumber-preprocessorrc delete mode 100644 apps/trading-e2e/src/integration/app.spec.ts create mode 100644 apps/trading-e2e/src/integration/home-page.feature create mode 100644 apps/trading-e2e/src/integration/market-order.feature create mode 100644 apps/trading-e2e/src/plugins/index.js create mode 100644 apps/trading-e2e/src/support/pages/base-page.js create mode 100644 apps/trading-e2e/src/support/pages/deal-ticket-page.js create mode 100644 apps/trading-e2e/src/support/pages/markets-page.js create mode 100644 apps/trading-e2e/src/support/step_definitions/common-step.js create mode 100644 apps/trading-e2e/src/support/step_definitions/home-page.step.js create mode 100644 apps/trading-e2e/src/support/step_definitions/market-order.step.js diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 0f159e8ca..c02b2fdba 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -11,7 +11,13 @@ jobs: master: name: Run end-to-end tests - main runs-on: ubuntu-latest + strategy: + matrix: + vegawallet-version: + - '0.13.2' + if: ${{ github.event_name != 'pull_request' }} + steps: - name: Checkout uses: actions/checkout@v2 @@ -28,11 +34,34 @@ jobs: node-version: 16.14.0 - name: Install root dependencies run: yarn install + + - name: Download and unzip wallet + run: curl -L https://github.com/vegaprotocol/vegawallet/releases/download/v${{ matrix.vegawallet-version }}/vegawallet-linux-amd64.zip -O + - name: Unzip wallet + run: unzip ./vegawallet-linux-amd64.zip + - name: Create passphrase + run: echo "${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}" > ./passphrase + - name: Create recovery + run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery + + - name: Initialize wallet + run: ./vegawallet init -f + - name: Import wallet + run: ./vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase + - name: Import config + run: ./vegawallet network import --from-url https://raw.githubusercontent.com/vegaprotocol/networks/master/fairground/fairground.toml + - name: Start service + run: ./vegawallet service run --network fairground & + - name: Run Cypress tests - run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} + run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.tradingWalletPassphrase=${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }} --browser chrome pr: name: Run end-to-end tests - PR runs-on: ubuntu-latest + strategy: + matrix: + vegawallet-version: + - '0.13.2' if: ${{ github.event_name == 'pull_request' }} steps: - name: Checkout @@ -51,5 +80,23 @@ jobs: node-version: 16.14.0 - name: Install root dependencies run: yarn install + - name: Download and unzip wallet + run: curl -L https://github.com/vegaprotocol/vegawallet/releases/download/v${{ matrix.vegawallet-version }}/vegawallet-linux-amd64.zip -O + - name: Unzip wallet + run: unzip ./vegawallet-linux-amd64.zip + - name: Create passphrase + run: echo "${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}" > ./passphrase + - name: Create recovery + run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery + + - name: Initialize wallet + run: ./vegawallet init -f + - name: Import wallet + run: ./vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase + - name: Import config + run: ./vegawallet network import --from-url https://raw.githubusercontent.com/vegaprotocol/networks/master/fairground/fairground.toml + - name: Start service + run: ./vegawallet service run --network fairground & + - name: Run Cypress tests - run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} + run: npx nx affected:e2e --parallel=5 --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.tradingWalletPassphrase=${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }} --browser chrome diff --git a/apps/explorer-e2e/cypress.json b/apps/explorer-e2e/cypress.json index 6f4e8dcc8..49b856f52 100644 --- a/apps/explorer-e2e/cypress.json +++ b/apps/explorer-e2e/cypress.json @@ -14,6 +14,7 @@ "screenshotsFolder": "../../dist/cypress/apps/explorer-e2e/screenshots", "chromeWebSecurity": false, "env": { - "tsConfig": "tsconfig.json" + "tsConfig": "tsconfig.json", + "TAGS": "not @todo and not @ignore and not @manual" } } diff --git a/apps/trading-e2e/.cypress-cucumber-preprocessorrc b/apps/trading-e2e/.cypress-cucumber-preprocessorrc new file mode 100644 index 000000000..dc930805e --- /dev/null +++ b/apps/trading-e2e/.cypress-cucumber-preprocessorrc @@ -0,0 +1,3 @@ +{ + "stepDefinitions": "src/support/step_definitions" +} diff --git a/apps/trading-e2e/cypress.json b/apps/trading-e2e/cypress.json index 9a4375883..00b9154dd 100644 --- a/apps/trading-e2e/cypress.json +++ b/apps/trading-e2e/cypress.json @@ -1,13 +1,20 @@ { + "baseUrl": "http://localhost:4200", "fileServerFolder": ".", - "fixturesFolder": "./src/fixtures", + "fixturesFolder": false, + "pluginsFile": "./src/plugins/index.js", + "testFiles": "*.{ts,feature,features}", + "ignoreTestFiles": "**/*.js", "integrationFolder": "./src/integration", "modifyObstructiveCode": false, "supportFile": "./src/support/index.ts", - "pluginsFile": false, "video": true, "videosFolder": "../../dist/cypress/apps/trading-e2e/videos", "screenshotsFolder": "../../dist/cypress/apps/trading-e2e/screenshots", "chromeWebSecurity": false, - "projectId": "et4snf" + "projectId": "et4snf", + "env": { + "tsConfig": "tsconfig.json", + "TAGS": "not @todo and not @ignore and not @manual" + } } diff --git a/apps/trading-e2e/src/integration/app.spec.ts b/apps/trading-e2e/src/integration/app.spec.ts deleted file mode 100644 index f39e79816..000000000 --- a/apps/trading-e2e/src/integration/app.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getGreeting } from '../support/app.po'; - -describe('trading', () => { - beforeEach(() => cy.visit('/')); - - it('should display welcome message', () => { - // Custom command example, see `../support/commands.ts` file - cy.login('my-email@something.com', 'myPassword'); - - // Function helper example, see `../support/app.po.ts` file - getGreeting().contains('Welcome to Vega Trading App'); - }); -}); diff --git a/apps/trading-e2e/src/integration/home-page.feature b/apps/trading-e2e/src/integration/home-page.feature new file mode 100644 index 000000000..e76dad29a --- /dev/null +++ b/apps/trading-e2e/src/integration/home-page.feature @@ -0,0 +1,18 @@ +Feature: Home page + + Scenario: Visit Home page + Given I am on the homepage + + Scenario: Visit Portfolio page + Given I am on the homepage + And I navigate to portfolio page + + Scenario: Unable to connect Vega wallet with incorrect credentials + Given I am on the homepage + When I try to connect Vega wallet with incorrect details + Then wallet not running error message is displayed + + Scenario: Unable to connect Vega wallet with blank fields + Given I am on the homepage + When I try to connect Vega wallet with blank fields + Then wallet field validation errors are shown diff --git a/apps/trading-e2e/src/integration/market-order.feature b/apps/trading-e2e/src/integration/market-order.feature new file mode 100644 index 000000000..a73435a22 --- /dev/null +++ b/apps/trading-e2e/src/integration/market-order.feature @@ -0,0 +1,98 @@ +Feature: Market orders + + Scenario Outline: Successfull market buy orders + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a buy '' market order + Then order request is sent + + Examples: + | marketOrderType | + | FOK | + | IOC | + + Scenario Outline: Successfull Limit buy orders + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a buy '' limit order + Then order request is sent + + Examples: + | limitOrderType | + | IOC | + | FOK | + | GTT | + # | GFA | Requires market to be in auction + | GFN | + + Scenario Outline: Successfull market sell order + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a sell '' market order + Then order request is sent + + Examples: + | marketOrderType | + | FOK | + | IOC | + + Scenario Outline: Successfull limit sell order + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a sell '' limit order + + Examples: + | limitOrderType | + | IOC | + | FOK | + | GTT | + # | GFA | Requires market to be in auction + | GFN | + + Scenario: Unsuccessfull order because lack of funds + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a buy 'FOK' market order + Then error message for insufficient funds is displayed + + Scenario: Unable to order because market is suspended + Given I am on the homepage + And I navigate to markets page + When I click on suspended market + And I connect to Vega Wallet + Then place order button is disabled + And "Market is currently suspended" error is shown + + Scenario: Unable to order because wallet is not connected + Given I am on the homepage + And I navigate to markets page + When I click on active market + Then place order button is disabled + And "No public key selected" error is shown + + Scenario: Unsuccessfull because quantity is 0 + Given I am on the homepage + And I navigate to markets page + When I click on active market + And I connect to Vega Wallet + And place a buy 'FOK' market order with amount of 0 + Then Order rejected by wallet error shown containing text "must be positive" + + @manual + Scenario: GTT order failed because invalid date + + @manual + Scenario: GTT order failed because date in the past + + @manual + Scenario: GTT order failed because date over allowed period diff --git a/apps/trading-e2e/src/plugins/index.js b/apps/trading-e2e/src/plugins/index.js new file mode 100644 index 000000000..97abe0be2 --- /dev/null +++ b/apps/trading-e2e/src/plugins/index.js @@ -0,0 +1,75 @@ +/// + +const webpackPreprocessor = require('@cypress/webpack-preprocessor'); +const webpack = require('webpack'); +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); +const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); +const nodeExternals = require('webpack-node-externals'); + +/** + * @type {Cypress.PluginConfig} + */ +module.exports = (on, config) => { + on( + 'file:preprocessor', + webpackPreprocessor({ + webpackOptions: { + resolve: { + extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], + plugins: [ + new TsconfigPathsPlugin({ + configFile: config.env.tsConfig, + extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], + }), + ], + fallback: { + path: require.resolve('path-browserify'), + }, + }, + module: { + rules: [ + { + test: /\.([jt])sx?$/, + loader: 'ts-loader', + exclude: [/node_modules/], + options: { + configFile: config.env.tsConfig, + // https://github.com/TypeStrong/ts-loader/pull/685 + experimentalWatchApi: true, + transpileOnly: true, + }, + }, + { + test: /\.feature$/, + use: [ + { + loader: 'cypress-cucumber-preprocessor/loader', + }, + ], + }, + { + test: /\.features$/, + use: [ + { + loader: 'cypress-cucumber-preprocessor/lib/featuresLoader', + }, + ], + }, + ], + }, + plugins: [ + new ForkTsCheckerWebpackPlugin({ + typescript: { + enabled: true, + configFile: config.env.tsConfig, + }, + }), + new webpack.ProvidePlugin({ + process: 'process/browser', + }), + ], + externals: [nodeExternals()], + }, + }) + ); +}; diff --git a/apps/trading-e2e/src/support/commands.ts b/apps/trading-e2e/src/support/commands.ts index 310f1fa0e..c6a821e12 100644 --- a/apps/trading-e2e/src/support/commands.ts +++ b/apps/trading-e2e/src/support/commands.ts @@ -13,6 +13,7 @@ declare namespace Cypress { // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Chainable { login(email: string, password: string): void; + getByTestId(selector: string): Chainable>; } } // @@ -31,3 +32,6 @@ Cypress.Commands.add('login', (email, password) => { // // -- This will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) +Cypress.Commands.add('getByTestId', (selector, ...args) => { + return cy.get(`[data-testid=${selector}]`, ...args); +}); diff --git a/apps/trading-e2e/src/support/pages/base-page.js b/apps/trading-e2e/src/support/pages/base-page.js new file mode 100644 index 000000000..0fb7a8b25 --- /dev/null +++ b/apps/trading-e2e/src/support/pages/base-page.js @@ -0,0 +1,56 @@ +export default class BasePage { + porfolioUrl = '/portfolio'; + marketsUrl = '/markets'; + connectVegaBtn = 'connect-vega-wallet'; + walletConnectors = 'connectors-list'; + walletForm = 'rest-connector-form'; + walletInputError = 'input-wallet-error'; + walletFormError = 'form-error'; + inputError = 'input-error-text'; + + navigateToPortfolio() { + cy.get(`a[href='${this.porfolioUrl}']`).click(); + } + + navigateToMarkets() { + cy.get(`a[href='${this.marketsUrl}']`) + .should('be.visible') + .click({ force: true }); + cy.url().should('include', '/markets'); + } + + navigateToConnectVegaWallet() { + cy.getByTestId(this.connectVegaBtn).click(); + cy.contains('Connects using REST to a running Vega wallet service'); + cy.getByTestId(this.walletConnectors).find('button').click(); + } + + fillInWalletForm(walletName, walletPassphrase) { + cy.getByTestId(this.walletForm) + .find('#wallet') + .click({ force: true }) + .type(walletName); + cy.getByTestId(this.walletForm) + .find('#passphrase') + .click({ force: true }) + .type(walletPassphrase); + } + + clickConnectVegaWallet() { + cy.getByTestId(this.walletForm) + .find('button[type=submit]') + .click({ force: true }); + } + + validateWalletNotRunningError() { + cy.getByTestId(this.walletFormError).should( + 'have.text', + 'Authentication failed' + ); + } + + validateWalletErrorFieldsDisplayed() { + cy.getByTestId(this.walletInputError).should('have.text', 'Required'); + cy.getByTestId(this.inputError).should('have.text', 'Required'); + } +} diff --git a/apps/trading-e2e/src/support/pages/deal-ticket-page.js b/apps/trading-e2e/src/support/pages/deal-ticket-page.js new file mode 100644 index 000000000..57a744094 --- /dev/null +++ b/apps/trading-e2e/src/support/pages/deal-ticket-page.js @@ -0,0 +1,114 @@ +import BasePage from './base-page'; +export default class DealTicketPage extends BasePage { + marketOrderType = 'order-type-TYPE_MARKET'; + limitOrderType = 'order-type-TYPE_LIMIT'; + buyOrder = 'order-side-SIDE_BUY'; + sellOrder = 'order-side-SIDE_SELL'; + orderSizeField = 'order-size'; + orderPriceField = 'order-price'; + orderTypeDropDown = 'order-tif'; + datePickerField = 'date-picker-field'; + placeOrderBtn = 'place-order'; + orderDialog = 'order-wrapper'; + orderStatusHeader = 'order-status-header'; + orderTransactionHash = 'tx-hash'; + orderErrorTxt = 'error-reason'; + + placeMarketOrder(isBuy, orderSize, orderType) { + cy.get(`[data-testid=${this.placeOrderBtn}]`, { timeout: 8000 }).should( + 'be.visible' + ); + + if (isBuy == false) { + cy.getByTestId(this.sellOrder).click(); + } + + cy.getByTestId(this.orderSizeField).clear().type(orderSize); + cy.getByTestId(this.orderTypeDropDown).select(orderType); + } + + placeLimitOrder(isBuy, orderSize, orderPrice, orderType) { + cy.getByTestId(this.limitOrderType).click(); + + if (isBuy == false) { + cy.getByTestId(this.sellOrder).click(); + } + + cy.getByTestId(this.orderSizeField).clear().type(orderSize); + cy.getByTestId(this.orderPriceField).clear().type(orderPrice); + cy.getByTestId(this.orderTypeDropDown).select(orderType); + + if (orderType == 'GTT') { + const today = new Date(new Date().setSeconds(0)); + const futureDate = new Date(today.setMonth(today.getMonth() + 1)); // set expiry to one month from now + const formattedDate = this.formatDate(futureDate); + cy.getByTestId(this.datePickerField).click().type(formattedDate); + } + } + + verifyOrderRequestSent() { + cy.getByTestId(this.orderStatusHeader).should( + 'have.text', + 'Awaiting network confirmation' + ); + cy.getByTestId(this.orderTransactionHash) + .invoke('text') + .should('contain', 'Tx hash: ') + .and('have.length.above', 64); + } + + verifyOrderFailedInsufficientFunds() { + cy.get(`[data-testid=${this.orderErrorTxt}]`, { timeout: 8000 }).should( + 'have.text', + 'Reason: InsufficientAssetBalance' + ); + } + + clickPlaceOrder() { + cy.getByTestId(this.placeOrderBtn).click(); + } + + verifyPlaceOrderBtnDisabled() { + cy.getByTestId(this.placeOrderBtn).should('be.disabled'); + } + + verifySubmitBtnErrorText(expectedText) { + cy.getByTestId(this.inputError).should('have.text', expectedText); + } + + verifyOrderRejected(errorMsg) { + cy.getByTestId(this.orderStatusHeader).should( + 'have.text', + 'Order rejected by wallet' + ); + cy.getByTestId(this.orderDialog) + .find('pre') + .should('contain.text', errorMsg); + } + + reloadPageIfPublicKeyErrorDisplayed() { + cy.get('body').then(($body) => { + if ($body.find(`[data-testid=${this.inputError}]`).length) { + cy.getByTestId(this.inputError) + .invoke('text') + .then(($errorText) => { + if ($errorText == 'No public key selected') { + cy.reload; + } + }); + } + }); + } + + formatDate(date) { + const padZero = (num) => num.toString().padStart(2, '0'); + + const year = date.getFullYear(); + const month = padZero(date.getMonth() + 1); + const day = padZero(date.getDate()); + const hours = padZero(date.getHours()); + const minutes = padZero(date.getMinutes()); + + return `${year}-${month}-${day}T${hours}:${minutes}`; + } +} diff --git a/apps/trading-e2e/src/support/pages/markets-page.js b/apps/trading-e2e/src/support/pages/markets-page.js new file mode 100644 index 000000000..300178ce3 --- /dev/null +++ b/apps/trading-e2e/src/support/pages/markets-page.js @@ -0,0 +1,54 @@ +import BasePage from './base-page'; + +export default class MarketPage extends BasePage { + marketRow = 'market-row'; + chartTab = 'chart'; + ticketTab = 'ticket'; + orderbookTab = 'orderbook'; + ordersTab = 'orders'; + positionsTab = 'positions'; + collateralTab = 'collateral'; + tradesTab = 'trades'; + completedTrades = 'market-trades'; + orderBookTab = 'orderbook'; + + validateMarketsAreDisplayed() { + cy.getByTestId(this.marketRow).should('have.length.above', 0); + } + + validateCompletedTradesDisplayed() { + cy.getByTestId(this.completedTrades).should('not.be.empty'); + } + + clickOnMarket(marketText) { + cy.contains(marketText).click(); + } + + clickOnActiveMarket() { + cy.contains('Active', { timeout: 8000 }).click({ force: true }); + } + + clickOnTopMarketRow() { + cy.getByTestId(this.marketRow).first().click(); + } + + clickOnOrdersTab() { + cy.getByTestId(this.ordersTab).click(); + } + + clickOnTicketTab() { + cy.getByTestId(this.ticketTab).click(); + } + + clickOnCollateralTab() { + cy.getByTestId(this.collateralTab).click(); + } + + clickOnTradesTab() { + cy.getByTestId(this.tradesTab).click(); + } + + clickOrderBookTab() { + cy.getByTestId(this.orderBookTab).click(); + } +} diff --git a/apps/trading-e2e/src/support/step_definitions/common-step.js b/apps/trading-e2e/src/support/step_definitions/common-step.js new file mode 100644 index 000000000..280125a20 --- /dev/null +++ b/apps/trading-e2e/src/support/step_definitions/common-step.js @@ -0,0 +1,27 @@ +import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps'; +import MarketsPage from '../pages/markets-page'; +import DealTicketPage from '../pages/deal-ticket-page'; +const marketsPage = new MarketsPage(); +const dealTicketPage = new DealTicketPage(); + +Given('I am on the homepage', () => { + cy.visit('/'); +}); + +Given('I navigate to markets page', () => { + marketsPage.navigateToMarkets(); +}); + +Given('I navigate to portfolio page', () => { + marketsPage.navigateToPortfolio(); +}); + +When('I connect to Vega Wallet', () => { + marketsPage.navigateToConnectVegaWallet(); + marketsPage.fillInWalletForm( + 'UI_Trading_Test', + Cypress.env('tradingWalletPassphrase') + ); + marketsPage.clickConnectVegaWallet(); + dealTicketPage.reloadPageIfPublicKeyErrorDisplayed(); +}); diff --git a/apps/trading-e2e/src/support/step_definitions/home-page.step.js b/apps/trading-e2e/src/support/step_definitions/home-page.step.js new file mode 100644 index 000000000..a03ed11b0 --- /dev/null +++ b/apps/trading-e2e/src/support/step_definitions/home-page.step.js @@ -0,0 +1,22 @@ +import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps'; +import MarketsPage from '../pages/markets-page'; +const marketsPage = new MarketsPage(); + +When('I try to connect Vega wallet with incorrect details', () => { + marketsPage.navigateToConnectVegaWallet(); + marketsPage.fillInWalletForm('name', 'wrong passphrase'); + marketsPage.clickConnectVegaWallet(); +}); + +When('I try to connect Vega wallet with blank fields', () => { + marketsPage.navigateToConnectVegaWallet(); + marketsPage.clickConnectVegaWallet(); +}); + +Then('wallet not running error message is displayed', () => { + marketsPage.validateWalletNotRunningError(); +}); + +Then('wallet field validation errors are shown', () => { + marketsPage.validateWalletErrorFieldsDisplayed(); +}); diff --git a/apps/trading-e2e/src/support/step_definitions/market-order.step.js b/apps/trading-e2e/src/support/step_definitions/market-order.step.js new file mode 100644 index 000000000..10f56bc2c --- /dev/null +++ b/apps/trading-e2e/src/support/step_definitions/market-order.step.js @@ -0,0 +1,65 @@ +import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps'; +import MarketsPage from '../pages/markets-page'; +import DealTicketPage from '../pages/deal-ticket-page'; +const marketsPage = new MarketsPage(); +const dealTicketPage = new DealTicketPage(); + +When('I click on market for {string}', (marketText) => { + marketsPage.clickOnMarket(marketText); +}); + +When('I click on active market', () => { + marketsPage.clickOnMarket('Active'); +}); + +When('place a buy {string} market order', (orderType) => { + dealTicketPage.placeMarketOrder(true, 100, orderType); + dealTicketPage.clickPlaceOrder(); +}); + +When('place a sell {string} market order', (orderType) => { + dealTicketPage.placeMarketOrder(false, 100, orderType); + dealTicketPage.clickPlaceOrder(); +}); + +When('place a buy {string} limit order', (limitOrderType) => { + dealTicketPage.placeLimitOrder(true, 100, 2000, limitOrderType); + dealTicketPage.clickPlaceOrder(); +}); + +When('place a sell {string} limit order', (limitOrderType) => { + dealTicketPage.placeLimitOrder(false, 100, 2000, limitOrderType); + dealTicketPage.clickPlaceOrder(); +}); + +When('place a buy {string} market order with amount of 0', (orderType) => { + dealTicketPage.placeMarketOrder(true, 0, orderType); + dealTicketPage.clickPlaceOrder(); +}); + +When('I click on suspended market', () => { + marketsPage.clickOnMarket('Suspended'); +}); + +Then('order request is sent', () => { + dealTicketPage.verifyOrderRequestSent(); +}); + +Then('error message for insufficient funds is displayed', () => { + dealTicketPage.verifyOrderFailedInsufficientFunds(); +}); + +Then('place order button is disabled', () => { + dealTicketPage.verifyPlaceOrderBtnDisabled(); +}); + +Then('{string} error is shown', (errorMsg) => { + dealTicketPage.verifySubmitBtnErrorText(errorMsg); +}); + +Then( + 'Order rejected by wallet error shown containing text {string}', + (expectedError) => { + dealTicketPage.verifyOrderRejected(expectedError); + } +); diff --git a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx index b32435324..7f3be067c 100644 --- a/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx +++ b/apps/trading/components/vega-wallet-connect-button/vega-wallet-connect-button.tsx @@ -27,6 +27,7 @@ export const VegaWalletConnectButton = ({ Vega key: )} diff --git a/libs/ui-toolkit/src/components/input-error/input-error.tsx b/libs/ui-toolkit/src/components/input-error/input-error.tsx index 6f7837ae8..b456049df 100644 --- a/libs/ui-toolkit/src/components/input-error/input-error.tsx +++ b/libs/ui-toolkit/src/components/input-error/input-error.tsx @@ -35,7 +35,11 @@ export const InputError = ({ 'fill-intent-warning': intent === 'warning', }); return ( -
+
{children}
diff --git a/libs/wallet/src/rest-connector-form.tsx b/libs/wallet/src/rest-connector-form.tsx index 6173a55a5..c51887d0f 100644 --- a/libs/wallet/src/rest-connector-form.tsx +++ b/libs/wallet/src/rest-connector-form.tsx @@ -60,7 +60,11 @@ export function RestConnectorForm({ autoFocus={true} /> {errors.wallet?.message && ( - + {errors.wallet.message} )}