Skip to content

Commit

Permalink
Merge pull request #456 from soroswap/CI/CD-workflow
Browse files Browse the repository at this point in the history
👷‍♂️Create tests workflow
  • Loading branch information
chopan123 authored Jun 10, 2024
2 parents 2faa418 + c08b4a6 commit 487a0e6
Show file tree
Hide file tree
Showing 33 changed files with 1,913 additions and 2,596 deletions.
6 changes: 4 additions & 2 deletions .env.production.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
NEXT_PUBLIC_BACKEND_URL=https://api.soroswap.finance
NEXT_PUBLIC_DEFAULT_NETWORK=testnet
NEXT_PUBLIC_SOROSWAP_BACKEND_URL=https://backend.soroswap.finance
NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY=
NEXT_PUBLIC_SOROSWAP_BACKEND_ENABLED=false
NEXT_PUBLIC_SOROSWAP_BACKEND_URL=https://backend.soroswap.finance
NEXT_PUBLIC_TAG_ID=
NEXT_PUBLIC_TEST_TOKENS_ADMIN_SECRET_KEY=
NEXT_PUBLIC_TAG_ID=
NEXT_PUBLIC_TRUSTLINE_WALLET_PUBLIC_KEY=
42 changes: 42 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Run tests

on: push
permissions:
contents: write
pull-requests: write
issues: read
packages: none

jobs:
run-tests:
env:
NEXT_PUBLIC_BACKEND_URL: ${{vars.NEXT_PUBLIC_BACKEND_URL}}
NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY: ${{secrets.NEXT_PUBLIC_SOROSWAP_BACKEND_API_KEY}}
NEXT_PUBLIC_SOROSWAP_BACKEND_URL: ${{vars.NEXT_PUBLIC_SOROSWAP_BACKEND_URL}}
NEXT_PUBLIC_SOROSWAP_BACKEND_ENABLED: ${{vars.NEXT_PUBLIC_SOROSWAP_BACKEND_ENABLED}}
NEXT_PUBLIC_DEFAULT_NETWORK: ${{vars.NEXT_PUBLIC_DEFAULT_NETWORK}}
NEXT_PUBLIC_TRUSTLINE_WALLET_PUBLIC_KEY: ${{vars.NEXT_PUBLIC_TRUSTLINE_WALLET_PUBLIC_KEY}}
NEXT_PUBLIC_TEST_TOKENS_ADMIN_SECRET_KEY: ${{secrets.NEXT_PUBLIC_TEST_TOKENS_ADMIN_SECRET_KEY}}
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]

- name: Set up Node.js
uses: actions/[email protected]
with:
node-version: '20.10.0'

- name: Install dependencies
run: yarn install

- name: Install cypress
run: yarn cypress install

- name: Build app
run: yarn build

- name: Run app
run: yarn pm2 start next

- name: Run test
run: yarn cy:run
12 changes: 9 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Cypress
cypress/screenshots
cypress/videos
cypress/reports
cypress/fixtures
cypress/plugins
cypress/.cache
cypress/logs

.soroban
contracts/target/
front-end/node_modules
Expand Down Expand Up @@ -106,6 +115,3 @@ dist

# TernJS port file
.tern-port

#wdio browser data
test/user_data/**
53 changes: 0 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,59 +151,6 @@ For more information on Vitest, please see the Vitest documentation: https://vit

For more information on Testing Library, please see the Testing Library documentation: https://testing-library.com/docs/react-testing-library/intro/

## 🔧🧪 E2E - Integration test environment setup 🔧🧪
**1. Set up the development environment:**
>[!TIP]
>Instructions can be found in the "[🛠 Setting Up Soroswap 🛠](#-setting-up-soroswap-)" section from step 1 to 4, located at the beginning of the document.
**2. Install the new dependencies:**
```
yarn install
```
**3. Configure Freigther wallet:**

1. Start the test browser for the first time:**
```
yarn wdio
```
> [!IMPORTANT]
>(This will take a moment and all tests will fail. This is normal because the wallet is not yet configured and the application is not running yet.)
2. Create a wallet or import an existing one:

In a new tab, go to:
> chrome-extension://bcacfldlkkdogcmkkibnjlakofdplcbk/index.html#
and create/import a wallet, configure a password, and save it in the file ./test/specs/e2e.test.ts within the variable "walletPassword".

3. Configure the network for testing:
>[!TIP]
>To configure the network, you can review step 6 of "[🛠 Setting Up Soroswap 🛠](#-setting-up-soroswap-)" and configure the network of your choice.
4. Fund the wallet with firendbot

**4. Run the development instance:**

In the terminal opened in step 1 (Which runs the development container), run the command:
```
yarn dev
```

**5. Restart the tests:**
1. Press **Ctrl**+**C** in the tests terminal to kill the test process.
>[!TIP]
>If after shutting down wdio your terminal seems to be stucked, press intro to refresh it
2. Run the following command to restart the tests:
```
yarn wdio
```

**6. Evaluate the test results:**

After the tests have been executed, you will find the output in the terminal detailing which tests passed and which did not, as well as the reason for the failure in these.


## Contributing

If you find a bug or have a feature request, please create an issue or submit a pull request. Contributions are always welcome!
Expand Down
23 changes: 23 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { defineConfig } from 'cypress';

export default defineConfig({
projectId: 'fabfoi',
defaultCommandTimeout: 24000, // 2x average block time
chromeWebSecurity: false,
experimentalMemoryManagement: true, // better memory management, see https://github.com/cypress-io/cypress/pull/25462
retries: { runMode: process.env.CYPRESS_RETRIES ? +process.env.CYPRESS_RETRIES : 1 },
video: false, // GH provides 2 CPUs, and cypress video eats one up, see https://github.com/cypress-io/cypress/issues/20468#issuecomment-1307608025
e2e: {
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/{e2e,staging}/**/*.test.{ts,tsx}',
},
component: {
devServer: {
framework: 'next',
bundler: 'webpack',
},
specPattern: 'cypress/component/**/*.test.{ts,tsx}',
viewportHeight: 768,
viewportWidth: 1366,
},
});
82 changes: 82 additions & 0 deletions cypress/component/liquidity.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import '../../styles/globals.css';
import MockRouter from '../utils/router';
import Providers from 'components/Providers';
import AddLiquidityComponent from 'components/Liquidity/Add/AddLiquidityComponent';
import { mockedFreighterConnector, sleep, testnetXLM } from '../utils/utils';
import { useApiTokens } from 'hooks/tokens/useApiTokens';

interface MockedAddLiquidityProps {
handleAddLiquidity?: ({
setAttemptingTxn,
setTxHash,
setTxError,
}: {
setAttemptingTxn: (value: boolean) => void;
setTxHash: (value: string | undefined) => void;
setTxError: (value: boolean) => void;
}) => void;
}

const MockedAddLiquidityComponent = ({ handleAddLiquidity }: MockedAddLiquidityProps) => {
const { tokens, isLoading } = useApiTokens();

const USDC = tokens.find((token) => token.code === 'USDC');

if (isLoading) return <div>Loading...</div>;

return (
<AddLiquidityComponent
currencyIdA={testnetXLM!}
currencyIdB={USDC?.contract}
handleAddLiquidity={handleAddLiquidity}
/>
);
};

const MockedAddLiquidityPage = ({ handleAddLiquidity }: MockedAddLiquidityProps) => {
return (
<MockRouter>
<Providers
sorobanReactProviderProps={{
connectors: [mockedFreighterConnector],
}}
>
<MockedAddLiquidityComponent handleAddLiquidity={handleAddLiquidity} />
</Providers>
</MockRouter>
);
};

describe('Swap Page', () => {
it('Should able to add liquidity', async () => {
cy.mount(
<MockedAddLiquidityPage
handleAddLiquidity={async ({ setAttemptingTxn, setTxHash }) => {
setAttemptingTxn(true);

await sleep(1000);

setAttemptingTxn(false);

setTxHash('0x123');
}}
/>,
);

cy.connectFreighterWallet();

cy.get('.token-amount-input').first().type('1');

cy.contains('Supply').click();

cy.get('[data-testid="confirm-swap-button"]').click();

cy.contains('Waiting for confirmation');

cy.contains('Transaction submitted');

cy.wait(1000);

cy.contains('Close').click();
});
});
68 changes: 68 additions & 0 deletions cypress/component/swap.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import '../../styles/globals.css';

import { Field } from 'state/swap/actions';
import { SetStateAction } from 'react';
import { SwapComponent, SwapStateProps } from 'components/Swap/SwapComponent';
import MockRouter from '../utils/router';
import Providers from 'components/Providers';
import { mockedFreighterConnector, sleep, testnetXLM } from '../utils/utils';

interface MockedSwapPageProps {
handleDoSwap?:
| ((setSwapState: (value: SetStateAction<SwapStateProps>) => void) => void)
| undefined;
}

const MockedSwapPage = ({ handleDoSwap }: MockedSwapPageProps) => {
const prefilledState = {
[Field.INPUT]: { currencyId: testnetXLM },
[Field.OUTPUT]: { currencyId: null },
};

return (
<MockRouter>
<Providers
sorobanReactProviderProps={{
connectors: [mockedFreighterConnector],
}}
>
<SwapComponent prefilledState={prefilledState} handleDoSwap={handleDoSwap} />
</Providers>
</MockRouter>
);
};

describe('Swap Page', () => {
// it('Should connect freighter wallet', () => {
// cy.mount(<MockedSwapPage />);
// cy.connectFreighterWallet();
// });
it('Should able to swap tokens', () => {
cy.mount(
<MockedSwapPage
handleDoSwap={async (setSwapState) => {
await sleep(1000);

setSwapState((currentState) => ({
...currentState,
swapError: undefined,
swapResult: {
status: 'SUCCESS',
txHash: '0x123',
},
}));
}}
/>,
);

cy.connectFreighterWallet();

cy.selectUSDCAndTriggerSwap();

cy.contains('Success');

cy.wait(1000);

cy.get('[data-testid="confirmation-close-icon"]').click();
});
});
48 changes: 48 additions & 0 deletions cypress/e2e/connectWallet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// cypress/integration/connectWallet.ts

describe('Connect Wallet', () => {
it('should log the wallet', () => {
cy.visit('/', {
onBeforeLoad: (win: any) => {
win.freighter = {
isConnected: () => true,
getPublicKey: () =>
Promise.resolve('GCHR5WWPDFF3U3HP2NA6TI6FCQPYEWS3UOPIPJKZLAAFM57CEG4ZYBWP'),
signTransaction: () => Promise.resolve('signedTransaction'),
// Add other methods as needed
};

// Create a spy on console.log
cy.spy(win.console, 'log').as('consoleLog');
},
});
cy.get('[data-testid="primary-button"]').click();
cy.contains('Detected');
cy.contains('Freighter Wallet').click();
cy.get('@consoleLog').should('have.been.calledWithMatch', 'wallet');
cy.get('@consoleLog').should('have.been.calledWithMatch', 'Changing connector to ');

// Get the window object
cy.window().then((win: any) => {
// Get the spy from the window object
const consoleLog = win.console.log;
var logs = [];
for (let i = 0; i < consoleLog.callCount; i++) {
// Get the i-th call to the spy
const call = consoleLog.getCall(i);

// Get the arguments of the call
const callArgs = call.args;

// Log the arguments using cy.log()
cy.log(`Call ${i} args: ${JSON.stringify(callArgs)}`);
console.log(`Call ${i} args: ${JSON.stringify(callArgs)}`);
logs.push(`Call ${i} args: ${JSON.stringify(callArgs)}`);
}
//write logs to a file on cypress/logs/logs.txt
cy.writeFile('cypress/logs/logs.txt', logs.join('\n'));
cy.screenshot();
});
// cy.contains('Public Key: publicKey')
});
});
Loading

0 comments on commit 487a0e6

Please sign in to comment.