From 688174fc49a50a72d779705e9f7d8425f6b667ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Miko=C5=82ajczyk?= Date: Thu, 22 Feb 2024 13:54:51 +0100 Subject: [PATCH 1/2] oct-1345 --- .github/workflows/ci-run.yml | 12 +++-- .github/workflows/deploy-master.yml | 1 + .github/workflows/deploy-pr.yml | 1 + .github/workflows/deploy-uat.yml | 1 + .github/workflows/tpl-deploy-app.yml | 17 ++++++- .github/workflows/tpl-images.yml | 17 ++++++- ci/Dockerfile.backend | 2 +- ci/Dockerfile.client | 3 +- ci/Dockerfile.coin-prices-server | 3 +- ci/Dockerfile.contracts-v1 | 3 +- ci/Dockerfile.subgraph | 3 +- client/cypress/e2e/patronMode.cy.ts | 15 +----- client/cypress/e2e/proposal.cy.ts | 39 +++++++++++++++- client/cypress/e2e/proposals.cy.ts | 46 ++++++++++++++++++- client/cypress/utils/e2e.ts | 14 ++++++ .../MetricsNavigation/MetricsNavigation.tsx | 4 +- .../ButtonAddToAllocate.tsx | 7 +-- 17 files changed, 155 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci-run.yml b/.github/workflows/ci-run.yml index e01b1d208d..636a3c39dd 100644 --- a/.github/workflows/ci-run.yml +++ b/.github/workflows/ci-run.yml @@ -79,8 +79,6 @@ jobs: run: | set -ex - exit 0 - export CI_PROJECT_DIR="${GITHUB_WORKSPACE}" source ${CI_PROJECT_DIR}/ci/argocd/resolve_env.sh $ENV_TYPE @@ -96,7 +94,9 @@ jobs: bash ${CI_PROJECT_DIR}/ci/argocd/wait_for_app.sh export OCTANT_BASE_URL; OCTANT_BASE_URL=https://$(bash ${CI_PROJECT_DIR}/ci/argocd/get_web_client_url.sh) - yarn synpress:run + # E2E tests are disabled until we figure out why they take hours to complete + # https://linear.app/golemfoundation/issue/CAQD-331/figure-out-why-synpress-jobs-are-taking-so-long + # yarn synpress:run shell: bash - uses: actions/upload-artifact@v4.0.0 if: failure() @@ -149,7 +149,9 @@ jobs: export ETH_RPC_PROVIDER_URL; ETH_RPC_PROVIDER_URL=https://$(bash ${CI_PROJECT_DIR}/ci/argocd/get_rpc_url.sh) export SUBGRAPH_ENDPOINT; SUBGRAPH_ENDPOINT=https://$(bash ${CI_PROJECT_DIR}/ci/argocd/get_graph_url.sh)/subgraphs/name/octant - poetry run pytest --onlyapi + # Tests are disabled??? + # https://gitlab.com/golemfoundation/governance/octant/-/commit/14e996ebed1fb73788e8ace045ea3b9a69bd5ca8 + # poetry run pytest --onlyapi shell: bash deploy-e2e-env: @@ -161,6 +163,7 @@ jobs: with: # --- env-type: e2e + branch-head-ref: ${{ github.ref }} image-tag: ${{ github.sha }} pull-request-id: ${{ github.event.pull_request.number }} workflow-id: ${{ github.run_id }} @@ -187,6 +190,7 @@ jobs: with: # --- env-type: apitest + branch-head-ref: ${{ github.ref }} image-tag: ${{ github.sha }} pull-request-id: ${{ github.event.pull_request.number }} workflow-id: ${{ github.run_id }} diff --git a/.github/workflows/deploy-master.yml b/.github/workflows/deploy-master.yml index d8b2932e6c..44447eda47 100644 --- a/.github/workflows/deploy-master.yml +++ b/.github/workflows/deploy-master.yml @@ -26,6 +26,7 @@ jobs: uses: ./.github/workflows/tpl-deploy-app.yml with: env-type: master + branch-head-ref: ${{ github.ref }} env-id: ${{ needs.run.outputs.env-id }} deployment-id: ${{ needs.run.outputs.deployment-id }} image-tag: ${{ github.sha }} diff --git a/.github/workflows/deploy-pr.yml b/.github/workflows/deploy-pr.yml index 3fd8df0353..989880668c 100644 --- a/.github/workflows/deploy-pr.yml +++ b/.github/workflows/deploy-pr.yml @@ -23,6 +23,7 @@ jobs: with: # --- env-type: pr + branch-head-ref: ${{ needs.run.outputs.ref }} image-tag: ${{ needs.run.outputs.sha }} pull-request-id: ${{ needs.run.outputs.pr_id }} workflow-id: ${{ github.run_id }} diff --git a/.github/workflows/deploy-uat.yml b/.github/workflows/deploy-uat.yml index c834f6b4be..139a2e7918 100644 --- a/.github/workflows/deploy-uat.yml +++ b/.github/workflows/deploy-uat.yml @@ -26,6 +26,7 @@ jobs: uses: ./.github/workflows/tpl-deploy-app.yml with: env-type: uat + branch-head-ref: ${{ github.ref }} env-id: ${{ needs.run.outputs.env-id }} deployment-id: ${{ needs.run.outputs.deployment-id }} image-tag: ${{ github.sha }} diff --git a/.github/workflows/tpl-deploy-app.yml b/.github/workflows/tpl-deploy-app.yml index 2cb9b01f8b..418ad80ad7 100644 --- a/.github/workflows/tpl-deploy-app.yml +++ b/.github/workflows/tpl-deploy-app.yml @@ -6,6 +6,9 @@ on: contracts-env-artifact-id: value: ${{ inputs.env-type }}-contracts-env inputs: + branch-head-ref: + required: true + type: string env-type: required: true type: string @@ -132,6 +135,7 @@ env: TESTNET_RPC_URL: "${{ secrets.TESTNET_RPC_URL }}" ETHERSCAN_API_KEY: "${{ secrets.ETHERSCAN_API_KEY }}" VITE_ALCHEMY_ID: "${{ secrets.VITE_ALCHEMY_ID }}" + IPFS_GATEWAY: "${{ vars.IPFS_GATEWAY }}" # ---------------------------------------------------------------------------- # CI/CD GCP_DOCKER_IMAGES_REGISTRY_SERVICE_ACCOUNT: "${{ secrets.GCP_DOCKER_IMAGES_REGISTRY_SERVICE_ACCOUNT }}" @@ -158,12 +162,15 @@ jobs: password: "${{ secrets.GITLAB_PAT_CONTAINER_BUILDER_DOCKER_IMAGES_READ }}" steps: - uses: actions/checkout@v4.1.0 + with: + ref: ${{ inputs.branch-head-ref }} - name: (debug) run: | set -ex env + ls -l echo ${{ inputs.env-type }} echo ${{ inputs.image-tag }} @@ -200,6 +207,9 @@ jobs: password: "${{ secrets.GCP_DOCKER_IMAGES_REGISTRY_SERVICE_ACCOUNT }}" steps: - uses: actions/checkout@v4.1.0 + with: + ref: ${{ inputs.branch-head-ref }} + - name: Deploy contracts run: | set -ex @@ -212,7 +222,9 @@ jobs: export LOCAL_RPC_URL; LOCAL_RPC_URL=https://$(bash ${CI_PROJECT_DIR}/ci/argocd/get_rpc_url.sh) - yarn install + # BUG: For some reason this cache is a problem for this job to pass + # https://linear.app/golemfoundation/issue/OCT-1382/error-during-ci-contracts-deployment + rm -r $HOME/.cache/hardhat-nodejs/ /app/entrypoint.sh $NETWORK ${CI_PROJECT_DIR}/contracts.env shell: bash @@ -241,6 +253,9 @@ jobs: password: "${{ secrets.GITLAB_PAT_CONTAINER_BUILDER_DOCKER_IMAGES_READ }}" steps: - uses: actions/checkout@v4.1.0 + with: + ref: ${{ inputs.branch-head-ref }} + - uses: actions/download-artifact@v4 if: ${{ inputs.deploy-contracts }} with: diff --git a/.github/workflows/tpl-images.yml b/.github/workflows/tpl-images.yml index 51195474e7..f0c231a825 100644 --- a/.github/workflows/tpl-images.yml +++ b/.github/workflows/tpl-images.yml @@ -31,17 +31,30 @@ jobs: # account # see: https://github.com/actions/checkout/issues/211 path: __local - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - name: Login to Docker registry uses: docker/login-action@v3 with: registry: europe-docker.pkg.dev username: _json_key_base64 password: ${{ secrets.GCP_DOCKER_IMAGES_REGISTRY_SERVICE_ACCOUNT }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: --debug + driver: docker + config-inline: | + debug = true + insecure-entitlements = [ "network.host", "security.insecure" ] + + [registry."local-docker-registry.wildland.dev:80"] + http = true + insecure = true + - name: Build and push uses: docker/build-push-action@v5 with: + allow: network.host,security.insecure context: __local/${{ matrix.SERVICE }} file: __local/ci/Dockerfile.${{ matrix.SERVICE }} push: true diff --git a/ci/Dockerfile.backend b/ci/Dockerfile.backend index 9951b2cdd3..b9f0de4235 100644 --- a/ci/Dockerfile.backend +++ b/ci/Dockerfile.backend @@ -1,4 +1,4 @@ -FROM acidrain/python-poetry:3.11-slim-1.5.1 +FROM local-docker-registry.wildland.dev:80/acidrain/python-poetry:3.11-slim-1.5.1 WORKDIR /app diff --git a/ci/Dockerfile.client b/ci/Dockerfile.client index 484b2a954d..19bd8d687d 100644 --- a/ci/Dockerfile.client +++ b/ci/Dockerfile.client @@ -1,4 +1,5 @@ -FROM node:16-alpine +FROM local-docker-registry.wildland.dev:80/library/node:16-alpine + WORKDIR /app COPY package.json yarn.lock ./ RUN yarn install --ignore-scripts --frozen-lockfile && yarn cache clean diff --git a/ci/Dockerfile.coin-prices-server b/ci/Dockerfile.coin-prices-server index 46da6a2a86..c1bb3db1d5 100644 --- a/ci/Dockerfile.coin-prices-server +++ b/ci/Dockerfile.coin-prices-server @@ -1,4 +1,5 @@ -FROM node:16-alpine AS root +FROM local-docker-registry.wildland.dev:80/library/node:16-alpine AS root + WORKDIR /app COPY package.json yarn.lock ./ diff --git a/ci/Dockerfile.contracts-v1 b/ci/Dockerfile.contracts-v1 index 74539d8ae2..e9bca8497e 100644 --- a/ci/Dockerfile.contracts-v1 +++ b/ci/Dockerfile.contracts-v1 @@ -1,4 +1,5 @@ -FROM node:16-alpine AS root +FROM local-docker-registry.wildland.dev:80/library/node:16-alpine AS root + WORKDIR /app FROM root AS build diff --git a/ci/Dockerfile.subgraph b/ci/Dockerfile.subgraph index 064fe454cc..1196e10ae0 100644 --- a/ci/Dockerfile.subgraph +++ b/ci/Dockerfile.subgraph @@ -1,4 +1,5 @@ -FROM node:16-alpine AS root +FROM local-docker-registry.wildland.dev:80/library/node:16-alpine AS root + WORKDIR /app FROM root AS build diff --git a/client/cypress/e2e/patronMode.cy.ts b/client/cypress/e2e/patronMode.cy.ts index 0a1dac2b7a..8dd53630e3 100644 --- a/client/cypress/e2e/patronMode.cy.ts +++ b/client/cypress/e2e/patronMode.cy.ts @@ -1,21 +1,8 @@ -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_ALWAYS_VISIBLE, IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes'; -import Chainable = Cypress.Chainable; - -const connectWallet = (isTOSAccepted: boolean, isPatronModeEnabled: boolean): Chainable => { - cy.intercept('GET', '/user/*/tos', { body: { accepted: isTOSAccepted } }); - cy.intercept('GET', '/user/*/patron-mode', { body: { status: isPatronModeEnabled } }); - cy.intercept('PATCH', '/user/*/patron-mode', { body: { status: !isPatronModeEnabled } }); - cy.disconnectMetamaskWalletFromAllDapps(); - cy.get('[data-test=MainLayout__Button--connect]').click(); - cy.get('[data-test=ConnectWallet__BoxRounded--browserWallet]').click(); - cy.switchToMetamaskNotification(); - return cy.acceptMetamaskAccess(); -}; - Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight, isDesktop }) => { describe(`patron mode (disabled): ${device}`, { viewportHeight, viewportWidth }, () => { before(() => { diff --git a/client/cypress/e2e/proposal.cy.ts b/client/cypress/e2e/proposal.cy.ts index e53c50aca1..147d277975 100644 --- a/client/cypress/e2e/proposal.cy.ts +++ b/client/cypress/e2e/proposal.cy.ts @@ -1,4 +1,4 @@ -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import { getNamesOfProposals } from 'cypress/utils/proposals'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; @@ -122,4 +122,41 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => } }); }); + + describe(`proposal (patron mode): ${device}`, { viewportHeight, viewportWidth }, () => { + let proposalNames: string[] = []; + + before(() => { + /** + * Global Metamask setup done by Synpress is not always done. + * Since Synpress needs to have valid provider to fetch the data from contracts, + * setupMetamask is required in each test suite. + */ + cy.setupMetamask(); + }); + + beforeEach(() => { + mockCoinPricesServer(); + localStorage.setItem(IS_ONBOARDING_DONE, 'true'); + visitWithLoader(ROOT_ROUTES.proposals.absolute); + connectWallet(true, true); + cy.get('[data-test^=ProposalItemSkeleton').should('not.exist'); + + /** + * This could be done in before hook, but CY wipes the state after each test + * (could be disabled, but creates other problems) + */ + if (proposalNames.length === 0) { + proposalNames = getNamesOfProposals(); + } + }); + + it('button "add to allocate" is disabled', () => { + for (let i = 0; i < proposalNames.length; i++) { + cy.get('[data-test^=ProposalsView__ProposalsListItem]').eq(i).click(); + getButtonAddToAllocate().should('be.visible').should('be.disabled'); + cy.go('back'); + } + }); + }); }); diff --git a/client/cypress/e2e/proposals.cy.ts b/client/cypress/e2e/proposals.cy.ts index 73ed788814..ed46af2ab2 100644 --- a/client/cypress/e2e/proposals.cy.ts +++ b/client/cypress/e2e/proposals.cy.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies import chaiColors from 'chai-colors'; -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import { getNamesOfProposals } from 'cypress/utils/proposals'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; @@ -11,7 +11,7 @@ import Chainable = Cypress.Chainable; chai.use(chaiColors); -function checkProposalItemElements(index, name): Chainable { +function checkProposalItemElements(index, name, isPatronMode = false): Chainable { cy.get('[data-test^=ProposalsView__ProposalsListItem') .eq(index) .find('[data-test=ProposalsListItem__imageProfile]') @@ -31,6 +31,13 @@ function checkProposalItemElements(index, name): Chainable { .find('[data-test=ProposalsListItem__ButtonAddToAllocate]') .should('be.visible'); + if (isPatronMode) { + cy.get('[data-test^=ProposalsView__ProposalsListItem') + .eq(index) + .find('[data-test=ProposalsListItem__ButtonAddToAllocate]') + .should('be.disabled'); + } + return cy .get('[data-test^=ProposalsView__ProposalsListItem') .eq(index) @@ -133,4 +140,39 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => removeProposalFromAllocate(proposalNames.length, 1, proposalNames.length - 1); }); }); + + describe(`proposals (patron mode): ${device}`, { viewportHeight, viewportWidth }, () => { + let proposalNames: string[] = []; + + before(() => { + /** + * Global Metamask setup done by Synpress is not always done. + * Since Synpress needs to have valid provider to fetch the data from contracts, + * setupMetamask is required in each test suite. + */ + cy.setupMetamask(); + }); + + beforeEach(() => { + mockCoinPricesServer(); + localStorage.setItem(IS_ONBOARDING_DONE, 'true'); + visitWithLoader(ROOT_ROUTES.proposals.absolute); + connectWallet(true, true); + cy.get('[data-test^=ProposalItemSkeleton').should('not.exist'); + /** + * This could be done in before hook, but CY wipes the state after each test + * (could be disabled, but creates other problems) + */ + if (proposalNames.length === 0) { + proposalNames = getNamesOfProposals(); + } + }); + + it('button "add to allocate" is disabled', () => { + for (let i = 0; i < proposalNames.length; i++) { + cy.get('[data-test^=ProposalsView__ProposalsListItem]').eq(i).scrollIntoView(); + checkProposalItemElements(i, proposalNames[i], true); + } + }); + }); }); diff --git a/client/cypress/utils/e2e.ts b/client/cypress/utils/e2e.ts index 2b0e5efc63..c7cd606fd4 100644 --- a/client/cypress/utils/e2e.ts +++ b/client/cypress/utils/e2e.ts @@ -98,3 +98,17 @@ export const moveToNextEpoch = () => // isEpochChanged resolve(Number(currentEpoch) + 1 === Number(currentEpochAfter)); }); + +export const connectWallet = ( + isTOSAccepted: boolean, + isPatronModeEnabled: boolean, +): Chainable => { + cy.intercept('GET', '/user/*/tos', { body: { accepted: isTOSAccepted } }); + cy.intercept('GET', '/user/*/patron-mode', { body: { status: isPatronModeEnabled } }); + cy.intercept('PATCH', '/user/*/patron-mode', { body: { status: !isPatronModeEnabled } }); + cy.disconnectMetamaskWalletFromAllDapps(); + cy.get('[data-test=MainLayout__Button--connect]').click(); + cy.get('[data-test=ConnectWallet__BoxRounded--browserWallet]').click(); + cy.switchToMetamaskNotification(); + return cy.acceptMetamaskAccess(); +}; diff --git a/client/src/components/Metrics/MetricsNavigation/MetricsNavigation.tsx b/client/src/components/Metrics/MetricsNavigation/MetricsNavigation.tsx index c56896e346..950aa061a0 100644 --- a/client/src/components/Metrics/MetricsNavigation/MetricsNavigation.tsx +++ b/client/src/components/Metrics/MetricsNavigation/MetricsNavigation.tsx @@ -66,7 +66,9 @@ const MetricsNavigation = (): ReactElement => { const callback = entries => { entries.forEach(entry => { - if (!entry.intersectionRatio) {return;} + if (!entry.intersectionRatio) { + return; + } if (!entry.isIntersecting) { if (metricsPersonalTarget.isSameNode(entry.target)) { diff --git a/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx b/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx index b9be6e0748..ea1b7632dc 100644 --- a/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx +++ b/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'; import Button from 'components/ui/Button'; import Svg from 'components/ui/Svg'; import Tooltip from 'components/ui/Tooltip'; +import useIsPatronMode from 'hooks/queries/useIsPatronMode'; import { checkMark, heart } from 'svg/misc'; import styles from './ButtonAddToAllocate.module.scss'; @@ -23,9 +24,9 @@ const ButtonAddToAllocate: FC = ({ keyPrefix: 'components.dedicated.buttonAddToAllocate', }); const [scope, animate] = useAnimate(); + const { data: isPatronMode } = useIsPatronMode(); const [isTooltipClicked, setIsTooltipClicked] = useState(false); const [isTooltipVisible, setIsTooltipVisible] = useState(false); - const tooltipText = useMemo(() => { if (isAddedToAllocate && isTooltipClicked) { return t('saved'); @@ -60,7 +61,7 @@ const ButtonAddToAllocate: FC = ({ Icon={ { if (isTooltipVisible) { setIsTooltipClicked(true); @@ -78,7 +79,7 @@ const ButtonAddToAllocate: FC = ({ } - isDisabled={isArchivedProposal} + isDisabled={isArchivedProposal || isPatronMode} onClick={onClick} variant="iconOnly" /> From d60ed13626f3e0c9f84e3cab08fa2fbe1d8ad816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Zi=C3=B3=C5=82ek?= Date: Fri, 23 Feb 2024 09:31:20 +0100 Subject: [PATCH 2/2] fix: enable E2E --- .github/workflows/ci-run.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci-run.yml b/.github/workflows/ci-run.yml index a1bc0b2a49..98e3120283 100644 --- a/.github/workflows/ci-run.yml +++ b/.github/workflows/ci-run.yml @@ -105,9 +105,7 @@ jobs: source /usr/bin/entrypoint.sh - # E2E tests are disabled until we figure out why they take hours to complete - # https://linear.app/golemfoundation/issue/CAQD-331/figure-out-why-synpress-jobs-are-taking-so-long - # yarn synpress:run + yarn synpress:run shell: bash - uses: actions/upload-artifact@v4.0.0