From 822f9e5fe2641e8ca79037a22e218c0031e6c767 Mon Sep 17 00:00:00 2001 From: Moody Salem Date: Wed, 13 May 2020 08:29:54 -0400 Subject: [PATCH] Connect integration tests (#757) * Connect a testing wallet * Replace with a funded address * Fix the balance checking and adding logging --- cypress.json | 6 +- cypress/integration/landing.test.ts | 8 +- cypress/integration/swap.test.ts | 8 + cypress/plugins/index.js | 21 - cypress/support/commands.d.ts | 8 + cypress/support/commands.js | 80 ++++ cypress/support/commands.ts | 27 -- cypress/support/index.js | 9 + cypress/support/index.ts | 20 - package.json | 3 + src/components/AccountDetails/index.tsx | 2 +- src/components/WalletModal/Option.tsx | 16 +- src/components/WalletModal/PendingView.tsx | 1 + src/components/WalletModal/index.tsx | 3 + src/components/Web3Status/index.tsx | 4 +- yarn.lock | 458 ++++++++++++++++++++- 16 files changed, 594 insertions(+), 80 deletions(-) delete mode 100644 cypress/plugins/index.js create mode 100644 cypress/support/commands.d.ts create mode 100644 cypress/support/commands.js delete mode 100644 cypress/support/commands.ts create mode 100644 cypress/support/index.js delete mode 100644 cypress/support/index.ts diff --git a/cypress.json b/cypress.json index 17ef242e71..cb2f5cd868 100644 --- a/cypress.json +++ b/cypress.json @@ -1,3 +1,7 @@ { - "baseUrl": "http://localhost:3000" + "baseUrl": "http://localhost:3000", + "pluginsFile": false, + "fixturesFolder": false, + "supportFile": "cypress/support/index.js", + "video": false } diff --git a/cypress/integration/landing.test.ts b/cypress/integration/landing.test.ts index dd382be571..057f325f89 100644 --- a/cypress/integration/landing.test.ts +++ b/cypress/integration/landing.test.ts @@ -1,6 +1,7 @@ +import { TEST_ADDRESS_NEVER_USE } from '../support/commands' + describe('Landing Page', () => { beforeEach(() => cy.visit('/')) - it('loads exchange page', () => { cy.get('#exchangePage') }) @@ -18,4 +19,9 @@ describe('Landing Page', () => { cy.get('#pool-navLink').click() cy.url().should('include', '/pool') }) + + it('is connected', () => { + cy.get('#web3-status-connected').click() + cy.get('#web3-account-identifier-row').contains(TEST_ADDRESS_NEVER_USE) + }) }) diff --git a/cypress/integration/swap.test.ts b/cypress/integration/swap.test.ts index 3470def466..97533d3221 100644 --- a/cypress/integration/swap.test.ts +++ b/cypress/integration/swap.test.ts @@ -4,7 +4,15 @@ describe('Swap', () => { cy.get('#swapInputField').type('0.001') }) + it('zero swap amount', () => { + cy.get('#swapInputField').type('0.0') + }) + it('can enter an amount into output', () => { cy.get('#swapOutputField').type('0.001') }) + + it('zero output amount', () => { + cy.get('#swapOutputField').type('0.0') + }) }) diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index 00420d1601..0000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,21 +0,0 @@ -/// -// *********************************************************** -// This example plugins/index.tsx can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -/** - * @type {Cypress.PluginConfig} - */ -module.exports = () => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/cypress/support/commands.d.ts b/cypress/support/commands.d.ts new file mode 100644 index 0000000000..6513582576 --- /dev/null +++ b/cypress/support/commands.d.ts @@ -0,0 +1,8 @@ +export const TEST_ADDRESS_NEVER_USE: string + +// declare namespace Cypress { +// // eslint-disable-next-line @typescript-eslint/class-name-casing +// interface cy { +// additionalCommands(): void +// } +// } diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 0000000000..0dae605e40 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,80 @@ +// *********************************************** +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +import { JsonRpcProvider } from '@ethersproject/providers' +import { Wallet } from '@ethersproject/wallet' +import { _Eip1193Bridge } from '@ethersproject/experimental/lib/eip1193-bridge' + +// never send real ether to this, obviously +const PRIVATE_KEY_TEST_NEVER_USE = '0xad20c82497421e9784f18460ad2fe84f73569068e98e270b3e63743268af5763' + +// address of the above key +export const TEST_ADDRESS_NEVER_USE = '0x0fF2D1eFd7A57B7562b2bf27F3f37899dB27F4a5' + +class CustomizedBridge extends _Eip1193Bridge { + async sendAsync(...args) { + console.debug('sendAsync called', ...args) + return this.send(...args) + } + async send(...args) { + console.debug('send called', ...args) + const isCallbackForm = typeof args[0] === 'object' && typeof args[1] === 'function' + let callback + let method + let params + if (isCallbackForm) { + callback = args[1] + method = args[0].method + params = args[0].params + } else { + method = args[0] + params = args[1] + } + if (method === 'eth_requestAccounts' || method === 'eth_accounts') { + if (isCallbackForm) { + callback({ result: [TEST_ADDRESS_NEVER_USE] }) + } else { + return Promise.resolve([TEST_ADDRESS_NEVER_USE]) + } + } + if (method === 'eth_chainId') { + if (isCallbackForm) { + callback(null, { result: '0x4' }) + } else { + return Promise.resolve('0x4') + } + } + try { + const result = await super.send(method, params) + console.debug('result received', method, params, result) + if (isCallbackForm) { + callback(null, { result }) + } else { + return result + } + } catch (error) { + if (isCallbackForm) { + callback(error, null) + } else { + throw error + } + } + } +} + +// sets up the injected provider to be a mock ethereum provider with the given mnemonic/index +Cypress.Commands.overwrite('visit', (original, url, options) => { + return original(url, { + ...options, + onBeforeLoad(win) { + options && options.onBeforeLoad && options.onBeforeLoad(win) + const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/b8800ce81b8c451698081d269b86692b', 4) + const signer = new Wallet(PRIVATE_KEY_TEST_NEVER_USE, provider) + const bridge = new CustomizedBridge(signer, provider) + win.ethereum = bridge + } + }) +}) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts deleted file mode 100644 index b017ed26f5..0000000000 --- a/cypress/support/commands.ts +++ /dev/null @@ -1,27 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) - -// TODO(moodysalem): commands for connecting a mock ethereum provider. diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 0000000000..3d834ebd4a --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,9 @@ +// *********************************************************** +// This file is processed and loaded automatically before your test files. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.ts using ES2015 syntax: +import './commands' diff --git a/cypress/support/index.ts b/cypress/support/index.ts deleted file mode 100644 index 41f56c72d0..0000000000 --- a/cypress/support/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.ts is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.ts using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/package.json b/package.json index c63a218c2f..c0cfabc464 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,8 @@ "use-media": "^1.4.0" }, "devDependencies": { + "@ethersproject/experimental": "^5.0.0-beta.141", + "@ethersproject/wallet": "^5.0.0-beta.141", "@types/jest": "^25.2.1", "@types/node": "^13.13.5", "@types/react": "^16.9.34", @@ -62,6 +64,7 @@ "@types/react-router-dom": "^5.0.0", "@types/rebass": "^4.0.5", "@types/styled-components": "^4.2.0", + "@types/testing-library__cypress": "^5.0.5", "@typescript-eslint/eslint-plugin": "^2.31.0", "@typescript-eslint/parser": "^2.31.0", "cypress": "^4.5.0", diff --git a/src/components/AccountDetails/index.tsx b/src/components/AccountDetails/index.tsx index 8922d6c75d..04e0c34960 100644 --- a/src/components/AccountDetails/index.tsx +++ b/src/components/AccountDetails/index.tsx @@ -325,7 +325,7 @@ export default function AccountDetails({ - + {ENSName ? ( <> diff --git a/src/components/WalletModal/Option.tsx b/src/components/WalletModal/Option.tsx index 720e9f0b18..1263fa0c45 100644 --- a/src/components/WalletModal/Option.tsx +++ b/src/components/WalletModal/Option.tsx @@ -96,10 +96,22 @@ export default function Option({ header, subheader = null, icon, - active = false + active = false, + id +}: { + link?: string | null + clickable?: boolean + size?: number | null + onClick?: null | (() => void) + color: string + header: React.ReactNode + subheader: React.ReactNode | null + icon: string + active?: boolean + id: string }) { const content = ( - + {' '} diff --git a/src/components/WalletModal/PendingView.tsx b/src/components/WalletModal/PendingView.tsx index 034d10a0af..465ee07839 100644 --- a/src/components/WalletModal/PendingView.tsx +++ b/src/components/WalletModal/PendingView.tsx @@ -126,6 +126,7 @@ export default function PendingView({ } return (