Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:safe-global/safe-wallet-web into cha…
Browse files Browse the repository at this point in the history
…in-redirect
  • Loading branch information
katspaugh committed Jun 4, 2024
2 parents 9bc2c69 + 59b891d commit 645eec6
Show file tree
Hide file tree
Showing 54 changed files with 1,007 additions and 460 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ inputs:

runs:
using: 'composite'

steps:
- name: Set environment variables
shell: bash
run: |
if [ "${{ inputs.prod }}" = "true" ]; then
echo "NEXT_PUBLIC_INFURA_TOKEN=${{ fromJSON(inputs.secrets).NEXT_PUBLIC_INFURA_TOKEN }}" >> $GITHUB_ENV
echo "NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN=${{ fromJSON(inputs.secrets).NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN }}" >> $GITHUB_ENV
else
echo "NEXT_PUBLIC_INFURA_TOKEN=${{ fromJSON(inputs.secrets).NEXT_PUBLIC_INFURA_TOKEN_DEVSTAGING }}" >> $GITHUB_ENV
echo "NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN=${{ fromJSON(inputs.secrets).NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN_DEVSTAGING }}" >> $GITHUB_ENV
fi
- name: Build
shell: bash
run: yarn build
Expand All @@ -31,8 +43,6 @@ runs:
NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID }}
NEXT_PUBLIC_GOOGLE_TAG_MANAGER_LATEST_AUTH: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_GOOGLE_TAG_MANAGER_LATEST_AUTH }}
NEXT_PUBLIC_GOOGLE_TAG_MANAGER_LIVE_AUTH: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_GOOGLE_TAG_MANAGER_LIVE_AUTH }}
NEXT_PUBLIC_INFURA_TOKEN: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_INFURA_TOKEN }}
NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN }}
NEXT_PUBLIC_SENTRY_DSN: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_SENTRY_DSN }}
NEXT_PUBLIC_TENDERLY_ORG_NAME: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_TENDERLY_ORG_NAME }}
NEXT_PUBLIC_TENDERLY_PROJECT_NAME: ${{ fromJSON(inputs.secrets).NEXT_PUBLIC_TENDERLY_PROJECT_NAME }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- uses: ./.github/workflows/build
with:
secrets: ${{ toJSON(secrets) }}
prod: ${{ github.ref == 'refs/heads/main' }}
if: startsWith(github.ref, 'refs/heads/main')

- uses: ./.github/workflows/build-storybook

Expand All @@ -53,14 +53,14 @@ jobs:

# Staging
- name: Deploy to the staging S3
if: github.ref == 'refs/heads/main'
if: startsWith(github.ref, 'refs/heads/main')
env:
BUCKET: s3://${{ secrets.AWS_STAGING_BUCKET_NAME }}/current
run: bash ./scripts/github/s3_upload.sh

# Dev
- name: Deploy to the dev S3
if: github.ref == 'refs/heads/dev'
if: startsWith(github.ref, 'refs/heads/dev')
env:
BUCKET: s3://${{ secrets.AWS_DEVELOPMENT_BUCKET_NAME }}
run: bash ./scripts/github/s3_upload.sh
Expand Down
25 changes: 6 additions & 19 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ jobs:
id-token: write

runs-on: ubuntu-latest

name: Deploy release

env:
ARCHIVE_NAME: ${{ github.event.repository.name }}-${{ github.event.release.tag_name }}

steps:
- uses: actions/checkout@v4

Expand All @@ -36,32 +39,16 @@ jobs:
aws-region: ${{ secrets.AWS_REGION }}

# Script to upload release files
- name: 'Upload release build files for production'
- name: Upload release build files for production
env:
BUCKET: s3://${{ secrets.AWS_STAGING_BUCKET_NAME }}/releases/${{ github.event.release.tag_name }}
CHECKSUM_FILE: ${{ env.ARCHIVE_NAME }}-sha256-checksum.txt
run: bash ./scripts/github/s3_upload.sh

# Script to prepare production deployments
- run: bash ./scripts/github/prepare_production_deployment.sh
- name: Prepare deployment
run: bash ./scripts/github/prepare_production_deployment.sh
env:
PROD_DEPLOYMENT_HOOK_TOKEN: ${{ secrets.PROD_DEPLOYMENT_HOOK_TOKEN }}
PROD_DEPLOYMENT_HOOK_URL: ${{ secrets.PROD_DEPLOYMENT_HOOK_URL }}
VERSION_TAG: ${{ github.event.release.tag_name }}

# Update the GitHub release with a checksummed archive
- name: Upload archive
- uses: Shopify/upload-to-release@v2.0.0
with:
path: ${{ env.ARCHIVE_NAME }}.tar.gz
name: ${{ env.ARCHIVE_NAME }}.tar.gz
content-type: application/gzip
repo-token: ${{ github.token }}

- name: Upload checksum
uses: Shopify/upload-to-release@v2.0.0
with:
path: ${{ env.ARCHIVE_NAME }}-sha256-checksum.txt
name: ${{ env.ARCHIVE_NAME }}-sha256-checksum.txt
content-type: text/plain
repo-token: ${{ github.token }}
136 changes: 136 additions & 0 deletions cypress/e2e/happypath/tx_history_filter_hp_1.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/* eslint-disable */
import * as constants from '../../support/constants.js'
import * as main from '../pages/main.page.js'
import * as createTx from '../pages/create_tx.pages.js'
import { getSafes, CATEGORIES } from '../../support/safes/safesHandler.js'

let staticSafes = []
const startDate = '01/12/2023'
const endDate = '01/12/2023'
const startDate2 = '20/12/2023'
const endDate2 = '20/12/2023'

describe('Tx history happy path tests 1', () => {
before(async () => {
staticSafes = await getSafes(CATEGORIES.static)
})

beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.transactionsHistoryUrl + staticSafes.SEP_STATIC_SAFE_7)
main.acceptCookies()
})

it('Verify a user can filter incoming transactions by dates, amount and token address', () => {
const uiDate = 'Dec 1, 2023'
const uiDate2 = 'Dec 1, 2023 - 8:05:00 AM'
const uiDate3 = 'Dec 1, 2023 - 7:52:36 AM'
const uiDate4 = 'Dec 15, 2023 - 10:33:00 AM'
const amount = '0.001'
const token = '0x7CB180dE9BE0d8935EbAAc9b4fc533952Df128Ae'

// date and amount
createTx.clickOnFilterBtn()
createTx.setTxType(createTx.filterTypes.incoming)
createTx.fillFilterForm({ endDate: endDate, amount: amount })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(2)
createTx.checkTxItemDate(0, uiDate)
createTx.checkTxItemDate(1, uiDate)

// combined filters
createTx.clickOnFilterBtn()
createTx.fillFilterForm({ startDate: startDate })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(2)
createTx.checkTxItemDate(0, uiDate)
createTx.checkTxItemDate(1, uiDate)

// reset txs
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.verifyNumberOfTransactions(25)

// chronological order
createTx.fillFilterForm({ startDate: startDate, endDate: endDate })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(7)
createTx.checkTxItemDate(5, uiDate2)
createTx.checkTxItemDate(6, uiDate3)

// token
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.fillFilterForm({ token: token })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(1)
createTx.checkTxItemDate(0, uiDate4)

// no txs
createTx.clickOnFilterBtn()
createTx.fillFilterForm({ startDate: startDate2, endDate: endDate2 })
createTx.clickOnApplyBtn()
createTx.verifyNoTxDisplayed('incoming')
})

it('Verify a user can filter outgoing transactions by dates, nonce, amount and recipient', () => {
const uiDate = 'Nov 30, 2023 - 11:06:00 AM'
const uiDate2 = 'Dec 1, 2023 - 7:54:36 AM'
const uiDate3 = 'Dec 1, 2023 - 7:37:24 AM'
const uiDate4 = 'Nov 30, 2023 - 11:02:12 AM'
const amount = '0.000000000001'
const recipient = 'sep:0x06373d5e45AD31BD354CeBfA8dB4eD2c75B8708e'

// date and recipient
createTx.clickOnFilterBtn()
createTx.setTxType(createTx.filterTypes.outgoing)

createTx.fillFilterForm({ endDate: endDate, recipient: recipient })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(1)
createTx.checkTxItemDate(0, uiDate4)

// combined filters
createTx.clickOnFilterBtn()
createTx.fillFilterForm({ startDate: startDate })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(0)

// reset txs
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(14)

// chronological order
createTx.clickOnFilterBtn()
createTx.fillFilterForm({ startDate: startDate, endDate: endDate })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(2)
createTx.checkTxItemDate(0, uiDate2)
createTx.checkTxItemDate(1, uiDate3)

// nonce
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.fillFilterForm({ nonce: '1' })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(1)
createTx.checkTxItemDate(0, uiDate)

// amount
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.fillFilterForm({ amount: amount })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(1)
createTx.checkTxItemDate(0, uiDate4)

// no txs
createTx.clickOnFilterBtn()
createTx.clickOnClearBtn()
createTx.fillFilterForm({ startDate: startDate2, endDate: endDate2 })
createTx.clickOnApplyBtn()
createTx.verifyNoTxDisplayed('outgoing')
})
})
30 changes: 30 additions & 0 deletions cypress/e2e/happypath/tx_history_filter_hp_2.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as constants from '../../support/constants.js'
import * as main from '../pages/main.page.js'
import * as createTx from '../pages/create_tx.pages.js'
import { getSafes, CATEGORIES } from '../../support/safes/safesHandler.js'

let staticSafes = []

describe('Tx history happy path tests 2', () => {
before(async () => {
staticSafes = await getSafes(CATEGORIES.static)
})

beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.transactionsHistoryUrl + staticSafes.SEP_STATIC_SAFE_8)
main.acceptCookies()
})

it('Verify a user can filter outgoing transactions by module', () => {
const moduleAddress = 'sep:0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134'
const uiDate = 'Jan 30, 2024 - 10:53:48 AM'

createTx.clickOnFilterBtn()
createTx.setTxType(createTx.filterTypes.module)
createTx.fillFilterForm({ address: moduleAddress })
createTx.clickOnApplyBtn()
createTx.verifyNumberOfTransactions(1)
createTx.checkTxItemDate(0, uiDate)
})
})
76 changes: 76 additions & 0 deletions cypress/e2e/pages/create_tx.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ const untrustedTokenWarningModal = '[data-testid="untrusted-token-warning"]'
const sendTokensBtn = '[data-testid="send-tokens-btn"]'
export const replacementNewSigner = '[data-testid="new-owner"]'
export const messageItem = '[data-testid="message-item"]'
const filterStartDateInput = '[data-testid="start-date"]'
const filterEndDateInput = '[data-testid="end-date"]'
const filterAmountInput = '[data-testid="amount-input"]'
const filterTokenInput = '[data-testid="token-input"]'
const filterNonceInput = '[data-testid="nonce-input"]'
const filterApplyBtn = '[data-testid="apply-btn"]'
const filterClearBtn = '[data-testid="clear-btn"]'
const addressItem = '[data-testid="address-item"]'
const radioSelector = 'div[role="radiogroup"]'

const viewTransactionBtn = 'View transaction'
const transactionDetailsTitle = 'Transaction details'
Expand All @@ -52,6 +61,73 @@ const signBtnStr = 'Sign'
const expandAllBtnStr = 'Expand all'
const collapseAllBtnStr = 'Collapse all'
export const messageNestedStr = `"nestedString": "Test message 3 off-chain"`
const noTxFoundStr = (type) => `0 ${type} transactions found`

export const filterTypes = {
incoming: 'Incoming',
outgoing: 'Outgoing',
module: 'Module-based',
}

export function setTxType(type) {
cy.get(radioSelector).find('label').contains(type).click()
}

export function verifyNoTxDisplayed(type) {
cy.get(transactionItem)
.should('have.length', 0)
.then(($items) => {
main.verifyElementsCount($items, 0)
})

cy.contains(noTxFoundStr(type)).should('be.visible')
}

export function clickOnApplyBtn() {
cy.get(filterApplyBtn).click()
}

export function clickOnClearBtn() {
cy.get(filterClearBtn).click()
}

export function fillFilterForm({ address, startDate, endDate, amount, token, nonce, recipient } = {}) {
const inputMap = {
address: { selector: addressItem, findInput: true },
startDate: { selector: filterStartDateInput, findInput: true },
endDate: { selector: filterEndDateInput, findInput: true },
amount: { selector: filterAmountInput, findInput: true },
token: { selector: filterTokenInput, findInput: true },
nonce: { selector: filterNonceInput, findInput: true },
recipient: { selector: addressItem, findInput: true },
}

Object.entries({ address, startDate, endDate, amount, token, nonce, recipient }).forEach(([key, value]) => {
if (value !== undefined) {
const { selector, findInput } = inputMap[key]
const element = findInput ? cy.get(selector).find('input') : cy.get(selector)
element.clear().type(value)
}
})
}

export function clickOnFilterBtn() {
cy.get('button').then((buttons) => {
const filterButton = [...buttons].find((button) => {
return ['Filter', 'Incoming', 'Outgoing', 'Module-based'].includes(button.innerText)
})

if (filterButton) {
cy.wrap(filterButton).click()
} else {
throw new Error('No filter button found')
}
})
}

export function checkTxItemDate(index, date) {
cy.get(txDate).eq(index).should('contain', date)
}

export function clickOnSendTokensBtn() {
cy.get(sendTokensBtn).click()
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/owners.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,5 +242,5 @@ export function verifyThreshold(startValue, endValue) {
cy.get(thresholdInput).parent().click()
cy.get(thresholdList).contains(endValue).should('be.visible')
cy.get(thresholdList).find('li').should('have.length', endValue)
cy.get('body').click({ force: true })
cy.get('body').click(0, 0)
}
Loading

0 comments on commit 645eec6

Please sign in to comment.