-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OCT-1119 Cypress: projects archives (#61)
- Loading branch information
Showing
9 changed files
with
233 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import { checkLocationWithLoader, visitWithLoader } from 'cypress/utils/e2e'; | ||
import viewports from 'cypress/utils/viewports'; | ||
import { QUERY_KEYS } from 'src/api/queryKeys'; | ||
import { IS_ONBOARDING_ALWAYS_VISIBLE, IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; | ||
import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes'; | ||
|
||
let wasEpochMoved = false; | ||
|
||
Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => { | ||
describe(`proposals archive: ${device}`, { viewportHeight, viewportWidth }, () => { | ||
beforeEach(() => { | ||
localStorage.setItem(IS_ONBOARDING_ALWAYS_VISIBLE, 'false'); | ||
localStorage.setItem(IS_ONBOARDING_DONE, 'true'); | ||
visitWithLoader(ROOT_ROUTES.proposals.absolute); | ||
}); | ||
|
||
it('moves to the next epoch', () => { | ||
// Move time only once, for the first device. | ||
if (!wasEpochMoved) { | ||
cy.window().then(async win => { | ||
const currentEpochBefore = Number( | ||
win.clientReactQuery.getQueryData(QUERY_KEYS.currentEpoch), | ||
); | ||
await win.mutateAsyncMoveEpoch(); | ||
const currentEpochAfter = Number( | ||
win.clientReactQuery.getQueryData(QUERY_KEYS.currentEpoch), | ||
); | ||
wasEpochMoved = true; | ||
expect(currentEpochBefore + 1).to.eq(currentEpochAfter); | ||
}); | ||
} else { | ||
expect(true).to.be.true; | ||
} | ||
}); | ||
|
||
it('renders archive elements + clicking on epoch archive ProposalsListItem opens ProposalView for particular epoch and project', () => { | ||
cy.get('[data-test=MainLayout__body]').then(el => { | ||
const mainLayoutPaddingTop = parseInt(el.css('paddingTop'), 10); | ||
|
||
cy.get('[data-test=ProposalsView__ProposalsList]') | ||
.should('be.visible') | ||
.children() | ||
.then(children => { | ||
children[children.length - 1].scrollIntoView(); | ||
cy.window().then(window => window.scrollTo(0, window.scrollY - mainLayoutPaddingTop)); | ||
cy.wait(1000); | ||
// header test | ||
cy.get('[data-test=ProposalsView__ProposalsList__header--archive]').should( | ||
'be.visible', | ||
); | ||
|
||
// list test | ||
cy.get('[data-test=ProposalsView__ProposalsList--archive]') | ||
.first() | ||
.should('be.visible'); | ||
cy.get('[data-test=ProposalsView__ProposalsList--archive]') | ||
.first() | ||
.children() | ||
.then(childrenArchive => { | ||
const numberOfArchivedProposals = childrenArchive.length - 2; // archived proposals tiles - (header + divider)[2] | ||
for (let i = 0; i < numberOfArchivedProposals; i++) { | ||
cy.get(`[data-test=ProposalsView__ProposalsListItem--archive--${i}]`) | ||
.first() | ||
.scrollIntoView(); | ||
cy.window().then(window => | ||
window.scrollTo(0, window.scrollY - mainLayoutPaddingTop), | ||
); | ||
// list item test | ||
cy.get(`[data-test=ProposalsView__ProposalsListItem--archive--${i}]`) | ||
.first() | ||
.should('be.visible') | ||
.within(() => { | ||
// rewards test | ||
cy.get('[data-test=ProposalRewards]').should('be.visible'); | ||
}); | ||
|
||
if (numberOfArchivedProposals - 1) { | ||
cy.get('[data-test=ProposalsView__ProposalsList--archive]') | ||
.first() | ||
.should('have.length', 1); | ||
} | ||
|
||
cy.get(`[data-test=ProposalsView__ProposalsListItem--archive--${i}]`) | ||
.first() | ||
.invoke('data', 'address') | ||
.then(address => { | ||
cy.get(`[data-test=ProposalsView__ProposalsListItem--archive--${i}]`) | ||
.first() | ||
.invoke('data', 'epoch') | ||
.then(epoch => { | ||
cy.get(`[data-test=ProposalsView__ProposalsListItem--archive--${i}]`) | ||
.first() | ||
.click(); | ||
checkLocationWithLoader( | ||
`${ROOT_ROUTES.proposal.absolute}/${epoch}/${address}`, | ||
); | ||
cy.go('back'); | ||
checkLocationWithLoader(ROOT_ROUTES.proposals.absolute); | ||
}); | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/// <reference types="cypress" /> | ||
|
||
declare namespace Cypress { | ||
interface ApplicationWindow { | ||
// Importing QueryClient breaks <reference types="cypress" /> making these types not visible. | ||
clientReactQuery: any; | ||
mutateAsyncMoveEpoch: () => Promise<void>; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { useEffect } from 'react'; | ||
|
||
import useCypressMoveEpoch from 'hooks/mutations/useCypressMoveEpoch'; | ||
|
||
export default function useCypressHelpers(): void { | ||
const { mutateAsync: mutateAsyncMoveEpoch } = useCypressMoveEpoch(); | ||
|
||
useEffect(() => { | ||
/** | ||
* In Cypress E2E tests some exclusive interactions with contracts are required. | ||
* Currently, it's moving the epoch to the next one via JSON RPC API. | ||
* | ||
* These need to be exposed from within the application instead of being called from Cypress itself. | ||
* Numerous attempts were made to call contracts via wagmiConfig.publicClient from Cypress, | ||
* all of which were unsuccessful (1). | ||
* | ||
* The only working solution for the moment is exposing these calls from within the applicaiton. | ||
* | ||
* (1) History of commits here: https://github.com/golemfoundation/octant/pull/13. | ||
*/ | ||
if (window.Cypress) { | ||
// @ts-expect-error Left for debug purposes. | ||
window.mutateAsyncMoveEpoch = mutateAsyncMoveEpoch; | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, []); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { useMutation, UseMutationResult, useQueryClient } from '@tanstack/react-query'; | ||
import { useConfig } from 'wagmi'; | ||
|
||
import { QUERY_KEYS } from 'api/queryKeys'; | ||
import { readContractEpochs } from 'hooks/contracts/readContracts'; | ||
|
||
export default function useCypressMoveEpoch(): UseMutationResult<boolean, unknown, bigint> { | ||
const queryClient = useQueryClient(); | ||
const wagmiConfig = useConfig(); | ||
|
||
return useMutation({ | ||
mutationFn: () => { | ||
// eslint-disable-next-line no-async-promise-executor | ||
return new Promise(async (resolve, reject) => { | ||
if (!window.Cypress) { | ||
reject(new Error('useCypressMoveEpoch was called outside Cypress.')); | ||
} | ||
|
||
const currentEpochPromise = queryClient.fetchQuery({ | ||
queryFn: () => | ||
readContractEpochs({ | ||
functionName: 'getCurrentEpoch', | ||
publicClient: wagmiConfig.publicClient, | ||
}), | ||
queryKey: QUERY_KEYS.currentEpoch, | ||
}); | ||
|
||
const blockPromise = wagmiConfig.publicClient.getBlock(); | ||
|
||
const currentEpochEndPromise = queryClient.fetchQuery({ | ||
queryFn: () => | ||
readContractEpochs({ | ||
functionName: 'getCurrentEpochEnd', | ||
publicClient: wagmiConfig.publicClient, | ||
}), | ||
queryKey: QUERY_KEYS.currentEpochEnd, | ||
}); | ||
|
||
const [block, currentEpochEnd, currentEpoch] = await Promise.all([ | ||
blockPromise, | ||
currentEpochEndPromise, | ||
currentEpochPromise, | ||
]); | ||
|
||
if (block === undefined || currentEpoch === undefined || currentEpochEnd === undefined) { | ||
// eslint-disable-next-line prefer-promise-reject-errors | ||
reject( | ||
new Error( | ||
'useCypressMoveEpoch fetched undefined block or currentEpoch or currentEpochEnd.', | ||
), | ||
); | ||
} | ||
|
||
const blockTimestamp = Number(block.timestamp); | ||
const currentEpochEndTimestamp = Number(currentEpochEnd); | ||
|
||
const timeToIncrease = currentEpochEndTimestamp - blockTimestamp + 10; // [s] | ||
await wagmiConfig.publicClient.request({ | ||
method: 'evm_increaseTime' as any, | ||
params: [timeToIncrease] as any, | ||
}); | ||
await wagmiConfig.publicClient.request({ method: 'evm_mine' as any, params: [] as any }); | ||
|
||
const currentEpochAfter = await queryClient.fetchQuery({ | ||
queryFn: () => | ||
readContractEpochs({ | ||
functionName: 'getCurrentEpoch', | ||
publicClient: wagmiConfig.publicClient, | ||
}), | ||
queryKey: QUERY_KEYS.currentEpoch, | ||
}); | ||
|
||
// isEpochChanged | ||
resolve(Number(currentEpoch) + 1 === Number(currentEpochAfter)); | ||
}); | ||
}, | ||
}); | ||
} |