-
Notifications
You must be signed in to change notification settings - Fork 209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: Add CCTP E2E tests to CI #1843
Changes from 90 commits
a10e181
b69c875
98f820d
1b9b0f8
068647a
f5579e4
87d5076
d25098a
aa1a658
c800534
ebd0fe7
2fd494f
2dfa7f9
1b1f88e
4617247
beca089
b71132b
2d954e5
4665586
c4dcec5
e533bbc
4190b17
0ea6870
c4522ac
c15c6de
103adf0
a56f574
861adc5
0cbdad3
fe1e06f
7e26873
6e8bcc6
25fa4d4
1b316ce
4d47ca3
3cf381d
a54e1e6
56e7cec
91ab959
ead5eb0
c270d21
1be6714
f2c2dc7
973b841
c0e99df
6e14faa
833be8c
c2bbefb
dca3362
f7f5a06
2880a0e
bdfb67e
4d9f090
779dbd8
7643194
d58aaa0
c66adea
557cd4d
4334b65
ffb579b
4b51541
cb4af3b
723a297
af967ea
3ede98b
6f1f65b
316eb24
874e159
baf317a
a57d136
38650ee
ca34996
ff978ac
e891ca4
fc5a3ef
608f655
99a0ec8
9df8a58
3343b91
820532b
22dc256
dca4c3f
17afffd
02f05ac
0176245
75afe34
7004d59
ce9bc3f
628fa6d
a97d852
4f6bfd9
84549e0
7f787bc
da3983e
89a8173
5dc75dd
d5a8050
cbfb7f4
88474cb
f1d60ab
21c6af5
734b147
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -155,21 +155,24 @@ jobs: | |||||
|
||||||
- id: set-matrix | ||||||
run: | | ||||||
content=`cat packages/arb-token-bridge-ui/tests/e2e/specfiles.json | jq --compact-output .` | ||||||
echo "e2eFiles=$content" >> $GITHUB_OUTPUT | ||||||
e2e_content=$(cat packages/arb-token-bridge-ui/tests/e2e/specfiles.json | jq --compact-output .) | ||||||
cctp_content=$(cat packages/arb-token-bridge-ui/tests/e2e/cctp.json | jq --compact-output .) | ||||||
|
||||||
e2e_with_orbit=$(echo "$e2e_content" | jq '[.[] | {type: "regular", name: .name, file: .file, recordVideo: .recordVideo, orbitTest: "0"}, {type: "regular", name: .name, file: .file, recordVideo: .recordVideo, orbitTest: "1"}]' | jq . --compact-output) | ||||||
cctp_formatted=$(echo "$cctp_content" | jq '[.[] | {type: "cctp", name: .name, file: .file, recordVideo: .recordVideo, orbitTest: null}]' | jq . --compact-output) | ||||||
|
||||||
combined_content=$(echo "$e2e_with_orbit $cctp_formatted" | jq -s 'add' --compact-output) | ||||||
echo "e2eFiles=$combined_content" >> $GITHUB_OUTPUT | ||||||
|
||||||
# based on https://github.com/Synthetixio/synpress/blob/dev/.github/workflows/e2e_cypress-action.yml | ||||||
test-e2e: | ||||||
name: "Test E2E${{ matrix.orbit-test == '1' && ' with L3' || '' }} - ${{ matrix.tests.name }}" | ||||||
name: "Test ${{ matrix.test.type == 'cctp' && 'E2E CCTP' || 'E2E' }}${{ matrix.test.type == 'regular' && matrix.test.orbitTest == '1' && ' with L3' || '' }} - ${{ matrix.test.name }}" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
does this work? |
||||||
runs-on: ubuntu-latest | ||||||
needs: [build, check-files, check-is-hotfix, load-e2e-files] | ||||||
if: needs.check-files.outputs.run_tests == 'true' && needs.check-is-hotfix.outputs.is_hotfix == 'false' | ||||||
strategy: | ||||||
fail-fast: false # If one test fails, let the other tests run | ||||||
matrix: | ||||||
tests: | ||||||
${{ fromJson(needs.load-e2e-files.outputs.matrix) }} | ||||||
orbit-test: ['0', '1'] | ||||||
test: ${{ fromJson(needs.load-e2e-files.outputs.matrix) }} | ||||||
|
||||||
steps: | ||||||
- name: Free Disk Space (Ubuntu) | ||||||
|
@@ -214,27 +217,29 @@ jobs: | |||||
DISPLAY: :0.0 | ||||||
|
||||||
- name: Run nitro testnode | ||||||
if: matrix.test.type == 'regular' | ||||||
uses: OffchainLabs/actions/run-nitro-test-node@a20a76172ce524832ac897bef2fa10a62ed81c29 | ||||||
with: | ||||||
nitro-testnode-ref: aab133aceadec2e622f15fa438f6327e3165392d | ||||||
l3-node: ${{ matrix.orbit-test == '1' }} | ||||||
no-l3-token-bridge: ${{ matrix.orbit-test == '0' }} | ||||||
l3-node: ${{ matrix.test.orbitTest == '1' }} | ||||||
no-l3-token-bridge: ${{ matrix.test.orbitTest == '0' }} | ||||||
|
||||||
- name: Run e2e tests via cypress-io/github-action | ||||||
uses: cypress-io/github-action@8d3918616d8ac34caa2b49afc8b408b6a872a6f5 # [email protected] | ||||||
with: | ||||||
start: yarn start | ||||||
command: ${{ matrix.orbit-test == '1' && 'yarn test:e2e:orbit --browser chromium' || 'yarn test:e2e --browser chromium' }} | ||||||
command: ${{ matrix.test.type == 'cctp' && 'yarn test:e2e:cctp --browser chromium' || (matrix.test.orbitTest == '1' && 'yarn test:e2e:orbit --browser chromium' || 'yarn test:e2e --browser chromium') }} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
does this work? |
||||||
wait-on: http://127.0.0.1:3000 | ||||||
wait-on-timeout: 120 | ||||||
spec: ./packages/arb-token-bridge-ui/tests/e2e/specs/* | ||||||
env: | ||||||
DISPLAY: :0.0 | ||||||
TEST_FILE: ${{ matrix.tests.file }} | ||||||
TEST_FILE: ${{ matrix.test.file }} | ||||||
SKIP_METAMASK_SETUP: true | ||||||
CYPRESS_RECORD_VIDEO: ${{ matrix.tests.recordVideo }} | ||||||
CYPRESS_RECORD_VIDEO: ${{ matrix.test.recordVideo }} | ||||||
PRIVATE_KEY_CUSTOM: ${{ secrets.E2E_PRIVATE_KEY }} | ||||||
PRIVATE_KEY_USER: ${{ secrets.E2E_PRIVATE_KEY_USER }} | ||||||
PRIVATE_KEY_CCTP: ${{ secrets.E2E_PRIVATE_KEY_CCTP }} | ||||||
NEXT_PUBLIC_IS_E2E_TEST: true | ||||||
NEXT_PUBLIC_INFURA_KEY: ${{ secrets.NEXT_PUBLIC_INFURA_KEY }} | ||||||
NEXT_PUBLIC_LOCAL_ETHEREUM_RPC_URL: http://127.0.0.1:8545 | ||||||
|
@@ -245,17 +250,16 @@ jobs: | |||||
uses: actions/upload-artifact@v4 | ||||||
if: always() | ||||||
with: | ||||||
name: e2e-artifacts-pull-request-${{ github.event.pull_request.number }}-commit-${{ github.sha }}-${{ matrix.tests.name }} | ||||||
name: e2e-artifacts-pull-request-${{ github.event.pull_request.number }}-commit-${{ github.sha }}-${{ matrix.test.name }}-${{ matrix.test.type }}-${{ matrix.test.orbitTest }} | ||||||
path: | | ||||||
./packages/arb-token-bridge-ui/cypress/videos | ||||||
./packages/arb-token-bridge-ui/cypress/screenshots | ||||||
if-no-files-found: 'ignore' | ||||||
continue-on-error: true | ||||||
|
||||||
- name: Throw error if tests failed | ||||||
if: steps.e2e-run.outputs.status == 'failed' | ||||||
run: exit 1 | ||||||
|
||||||
test-e2e-success: | ||||||
name: "Test E2E Success" | ||||||
runs-on: ubuntu-latest | ||||||
|
@@ -269,7 +273,6 @@ jobs: | |||||
- name: E2E Failed | ||||||
if: needs.test-e2e.result != 'success' && needs.test-e2e.result != 'skipped' | ||||||
run: exit 1 | ||||||
|
||||||
clean-up: | ||||||
name: "Clean Up" | ||||||
runs-on: ubuntu-latest | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,14 +51,6 @@ if (typeof INFURA_KEY === 'undefined') { | |
throw new Error('Infura API key not provided') | ||
} | ||
|
||
const SEPOLIA_INFURA_RPC_URL = `https://sepolia.infura.io/v3/${INFURA_KEY}` | ||
const sepoliaRpcUrl = | ||
process.env.NEXT_PUBLIC_SEPOLIA_RPC_URL ?? SEPOLIA_INFURA_RPC_URL | ||
const arbSepoliaRpcUrl = 'https://sepolia-rollup.arbitrum.io/rpc' | ||
|
||
const sepoliaProvider = new StaticJsonRpcProvider(sepoliaRpcUrl) | ||
const arbSepoliaProvider = new StaticJsonRpcProvider(arbSepoliaRpcUrl) | ||
|
||
if (!process.env.PRIVATE_KEY_CCTP) { | ||
throw new Error('PRIVATE_KEY_CCTP variable missing.') | ||
} | ||
|
@@ -67,6 +59,14 @@ if (!process.env.PRIVATE_KEY_USER) { | |
throw new Error('PRIVATE_KEY_USER variable missing.') | ||
} | ||
|
||
const SEPOLIA_INFURA_RPC_URL = `https://sepolia.infura.io/v3/${INFURA_KEY}` | ||
const sepoliaRpcUrl = | ||
process.env.NEXT_PUBLIC_SEPOLIA_RPC_URL ?? SEPOLIA_INFURA_RPC_URL | ||
const arbSepoliaRpcUrl = 'https://sepolia-rollup.arbitrum.io/rpc' | ||
|
||
const sepoliaProvider = new StaticJsonRpcProvider(sepoliaRpcUrl) | ||
const arbSepoliaProvider = new StaticJsonRpcProvider(arbSepoliaRpcUrl) | ||
|
||
Comment on lines
+62
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nbd but why move them? |
||
// Wallet funded on Sepolia and ArbSepolia with ETH and USDC | ||
const localWallet = new Wallet(process.env.PRIVATE_KEY_CCTP) | ||
// Generate a new wallet every time | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
[ | ||
{ | ||
"name": "Deposit Cctp", | ||
"file": "tests/e2e/specs/**/depositCctp.cy.{js,jsx,ts,tsx}" | ||
"file": "tests/e2e/specs/**/depositCctp.cy.{js,jsx,ts,tsx}", | ||
"recordVideo": false | ||
}, | ||
{ | ||
"name": "Withdraw Cctp", | ||
"file": "tests/e2e/specs/**/withdrawCctp.cy.{js,jsx,ts,tsx}" | ||
"file": "tests/e2e/specs/**/withdrawCctp.cy.{js,jsx,ts,tsx}", | ||
"recordVideo": false | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,7 +52,9 @@ const confirmAndApproveCctpDeposit = () => { | |
.should('be.enabled') | ||
.click() | ||
|
||
cy.findByText(/I understand that I have to/).click() | ||
cy.findByText(/I understand that I have to/) | ||
.should('be.visible') | ||
.click() | ||
cy.findByRole('button', { | ||
name: /Pay approval fee of/ | ||
}).click() | ||
|
@@ -61,86 +63,73 @@ const confirmAndApproveCctpDeposit = () => { | |
|
||
describe('Deposit USDC through CCTP', () => { | ||
// Happy Path | ||
context('User has some USDC and is on L1', () => { | ||
let USDCAmountToSend: number = 0 | ||
|
||
// log in to metamask before deposit | ||
beforeEach(() => { | ||
USDCAmountToSend = Number((Math.random() * 0.001).toFixed(6)) // randomize the amount to be sure that previous transactions are not checked in e2e | ||
|
||
cy.fundUserWalletEth('parentChain') | ||
cy.fundUserUsdcTestnet('parentChain') | ||
cy.resetCctpAllowance('parentChain') | ||
|
||
/// common code before all tests | ||
cy.login({ networkType: 'parentChain', networkName: 'sepolia' }) | ||
context('should show L1 and L2 chains, and USD correctly', () => { | ||
cy.findSourceChainButton('Sepolia') | ||
cy.findDestinationChainButton('Arbitrum Sepolia') | ||
cy.findSelectTokenButton('ETH') | ||
}) | ||
|
||
cy.searchAndSelectToken({ | ||
tokenName: 'USDC', | ||
tokenAddress: CommonAddress.Sepolia.USDC | ||
}) | ||
|
||
context('should show summary', () => { | ||
cy.typeAmount(USDCAmountToSend) | ||
cy.findGasFeeSummary(zeroToLessThanOneETH) | ||
cy.findGasFeeForChain('Sepolia', zeroToLessThanOneETH) | ||
cy.findGasFeeForChain( | ||
/You'll have to pay Arbitrum Sepolia gas fee upon claiming./i | ||
) | ||
}) | ||
}) | ||
const USDCAmountToSend = 0.0001 | ||
|
||
beforeEach(() => { | ||
cy.login({ networkType: 'parentChain', networkName: 'sepolia' }) | ||
cy.findSourceChainButton('Sepolia') | ||
cy.findDestinationChainButton('Arbitrum Sepolia') | ||
cy.findSelectTokenButton('ETH') | ||
|
||
it('should initiate depositing USDC to the same address through CCTP successfully', () => { | ||
context('should show clickable deposit button', () => { | ||
cy.findMoveFundsButton().click() | ||
}) | ||
|
||
context('Should display CCTP modal', () => { | ||
confirmAndApproveCctpDeposit() | ||
cy.confirmMetamaskPermissionToSpend(USDCAmountToSend.toString()) | ||
|
||
// eslint-disable-next-line | ||
cy.wait(40_000) | ||
cy.confirmMetamaskTransaction() | ||
cy.findTransactionInTransactionHistory({ | ||
duration: 'a minute', | ||
amount: USDCAmountToSend, | ||
symbol: 'USDC' | ||
}) | ||
}) | ||
cy.searchAndSelectToken({ | ||
tokenName: 'USDC', | ||
tokenAddress: CommonAddress.Sepolia.USDC | ||
}) | ||
|
||
it('should initiate depositing USDC to custom destination address through CCTP successfully', () => { | ||
context('should fill custom destination address successfully', () => { | ||
cy.fillCustomDestinationAddress() | ||
}) | ||
|
||
context('should click deposit successfully', () => { | ||
cy.findMoveFundsButton().click() | ||
}) | ||
|
||
context('Should display CCTP modal', () => { | ||
confirmAndApproveCctpDeposit() | ||
cy.confirmMetamaskPermissionToSpend(USDCAmountToSend.toString()) | ||
|
||
// eslint-disable-next-line | ||
cy.wait(40_000) | ||
cy.confirmMetamaskTransaction() | ||
const txData = { amount: USDCAmountToSend, symbol: 'USDC' } | ||
cy.findTransactionInTransactionHistory({ | ||
duration: 'a minute', | ||
...txData | ||
}) | ||
cy.openTransactionDetails(txData) | ||
cy.findTransactionDetailsCustomDestinationAddress( | ||
Cypress.env('CUSTOM_DESTINATION_ADDRESS') | ||
) | ||
}) | ||
cy.typeAmount(USDCAmountToSend) | ||
cy.findGasFeeSummary(zeroToLessThanOneETH) | ||
cy.findGasFeeForChain('Sepolia', zeroToLessThanOneETH) | ||
cy.findGasFeeForChain( | ||
/You'll have to pay Arbitrum Sepolia gas fee upon claiming./i | ||
) | ||
}) | ||
|
||
it('should initiate depositing USDC to the same address through CCTP successfully', () => { | ||
cy.findMoveFundsButton().click() | ||
|
||
confirmAndApproveCctpDeposit() | ||
cy.confirmSpending(USDCAmountToSend.toString()) | ||
|
||
/** | ||
* Currently synpress cy.confirmMetamaskTransaction doesn't work on Sepolia | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there no way to fix this currently? We are also skipping 1 test coz of it which isn't ideal. |
||
* CCTP flow is tested in withdrawCctp.cy.ts | ||
*/ | ||
// cy.wait(40_000) | ||
// cy.confirmMetamaskTransaction(undefined) | ||
// cy.findTransactionInTransactionHistory({ | ||
// duration: 'a minute', | ||
// amount: USDCAmountToSend, | ||
// symbol: 'USDC', | ||
// options: { | ||
// timeout: 60_000 | ||
// } | ||
// }) | ||
}) | ||
|
||
/** | ||
* Because the previous test doesn't send any transaction, allowance is still valid here. | ||
* Skipping the test for now | ||
*/ | ||
it.skip('should initiate depositing USDC to custom destination address through CCTP successfully', () => { | ||
cy.fillCustomDestinationAddress() | ||
cy.findMoveFundsButton().click() | ||
confirmAndApproveCctpDeposit() | ||
|
||
cy.confirmSpending(USDCAmountToSend.toString()) | ||
|
||
cy.wait(40_000) | ||
cy.confirmMetamaskTransaction(undefined) | ||
const txData = { amount: USDCAmountToSend, symbol: 'USDC' } | ||
cy.findTransactionInTransactionHistory({ | ||
duration: 'a minute', | ||
...txData, | ||
options: { | ||
timeout: 60_000 | ||
} | ||
}) | ||
cy.openTransactionDetails(txData) | ||
cy.findTransactionDetailsCustomDestinationAddress( | ||
Cypress.env('CUSTOM_DESTINATION_ADDRESS') | ||
) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is way too chunky to read now
can you clean this up please?
we can also handle this in a separate file rather than inlining the processing script