-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
e2e: campaign application admin and giver specs
- add logic for admin or giver user login (see fixtures.ts) - add logic to get a localized text for the e2e tests - test edit a campaign application from admin UI - test create a campaign application from general user UI
- Loading branch information
Showing
9 changed files
with
423 additions
and
27 deletions.
There are no files selected for viewing
170 changes: 170 additions & 0 deletions
170
e2e/tests/regression/campaign-application/campaign-application-admin.spec.ts
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,170 @@ | ||
import { | ||
CampaignApplicationResponse, | ||
CampaignApplicationExisting, | ||
CampaignApplicationAdminResponse, | ||
} from '../../../../src/gql/campaign-applications' | ||
import { Page } from 'playwright/test' | ||
import { expect, adminTest as test } from '../../../utils/fixtures' | ||
import { textLocalized } from '../../../utils/texts-localized' | ||
|
||
test.describe('Campaign application admin', () => { | ||
test('should see list of applications', async ({ page, baseURL }) => { | ||
// arrange | ||
const { paginationFooter } = await setup(page) | ||
.withCampaignApplications([ | ||
{ id: '1', state: 'review' }, | ||
{ id: '2', state: 'approved' }, | ||
{ id: '3', state: 'denied' }, | ||
{ id: '4', state: 'forCommitteeReview' }, | ||
{ id: '5' }, | ||
]) | ||
.build() | ||
|
||
// act | ||
await page.goto(`${baseURL}/admin/campaign-applications`) | ||
|
||
// assert | ||
const t = await textLocalized().campaign.bg() | ||
await expect(page.getByRole('heading')).toHaveText(t.admin.title) | ||
await expect(page.getByRole('row')).toHaveCount(6) // title + 5 campaigns | ||
await expect(page.getByRole('row').nth(1)).toContainText(t.status.review) | ||
await expect(page.getByRole('row').nth(2)).toContainText(t.status.approved) | ||
await expect(page.getByRole('row').nth(3)).toContainText(t.status.denied) | ||
await expect(page.getByRole('row').nth(4)).toContainText(t.status.forCommitteeReview) | ||
await expect(page.getByRole('row').nth(5)).toContainText(t.status.requestInfo) | ||
await expect(paginationFooter(page)).toHaveText('Rows per page:1001–5 of 5') | ||
}) | ||
|
||
test('should open a campaign application for edit', async ({ page, baseURL }) => { | ||
// arrange | ||
await setup(page).withEditCampaignApplication({}).build() | ||
|
||
// act | ||
await page.goto(`${baseURL}/admin/campaign-applications/edit/1234`) | ||
|
||
// assert | ||
const t = await textLocalized().campaign.bg() | ||
await expect(page.getByRole('heading').first()).toHaveText(t.admin.title) | ||
await expect(page.getByRole('heading').nth(1)).toHaveText(t.steps.admin.title) | ||
}) | ||
|
||
test('should update status of campaign application to approved, archive it, and set the external link', async ({ | ||
page, | ||
baseURL, | ||
}) => { | ||
// arrange | ||
await setup(page).withEditCampaignApplication({ id: '1234', state: 'review' }).build() | ||
await page.goto(`${baseURL}/admin/campaign-applications/edit/1234`) | ||
const t = await textLocalized().campaign.bg() | ||
|
||
// act | ||
await page.getByLabel(t.steps.admin.status).click() | ||
await page.getByText(t.status.approved).click() | ||
|
||
const [req] = await Promise.all([ | ||
page.waitForRequest(/campaign-application\/1234/), | ||
page.getByRole('button', { name: t.result.editButton }).click(), | ||
]) | ||
|
||
// assert | ||
const postData = req.postDataJSON() | ||
expect(postData.state).toEqual('approved') | ||
expect(page.getByText(t.result.edited)).toBeInViewport() | ||
}) | ||
}) | ||
|
||
function setup(page: Page) { | ||
const promises: Promise<unknown>[] = [] | ||
|
||
const builder = { | ||
withCampaignApplications(cams: Array<Partial<CampaignApplicationResponse>>) { | ||
promises.push( | ||
page.route('*/**/api/v1/campaign-application/list', (route, req) => { | ||
return route.fulfill({ | ||
json: cams.map((c) => ({ ...defaultCampaignApplication(), ...c })), | ||
}) | ||
}), | ||
) | ||
return builder | ||
}, | ||
|
||
withEditCampaignApplication(c: Partial<CampaignApplicationExisting>) { | ||
promises.push( | ||
page.route('*/**/api/v1/campaign-application/byId/*', (route, req) => { | ||
return route.fulfill({ | ||
json: { ...camAppForEdit(), ...c }, | ||
}) | ||
}), | ||
page.route(`*/**/api/v1/campaign-application/${c.id}`, (r) => { | ||
return r.fulfill({ json: { ...camAppForEdit(), ...c } }) | ||
}), | ||
) | ||
return builder | ||
}, | ||
|
||
async build() { | ||
await promises | ||
|
||
const selectors = { | ||
paginationFooter: (p: Page) => p.locator('.MuiDataGrid-footerContainer'), | ||
} | ||
|
||
return selectors | ||
}, | ||
} | ||
|
||
return builder | ||
} | ||
|
||
function defaultCampaignApplication(): CampaignApplicationAdminResponse { | ||
return { | ||
id: 'eb4347a2-c8b4-47f1-83e5-67457b20909c', | ||
createdAt: '2024-09-13T09:26:50.909Z', | ||
updatedAt: '2024-09-28T20:56:13.728Z', | ||
organizerName: 'Giver Dev', | ||
organizerEmail: '[email protected]', | ||
organizerPhone: '+35928700500', | ||
beneficiary: 'Bene', | ||
organizerBeneficiaryRel: 'бене', | ||
campaignName: 'Camp name', | ||
goal: 'Целта на кампанията', | ||
history: '', | ||
amount: '1455', | ||
description: '', | ||
state: 'requestInfo', | ||
campaignTypeId: 'c6ef0a79-11cf-4175-9f66-3cec940c9259', | ||
ticketURL: 'https://trello.com/linkforthiscamapp', | ||
archived: false, | ||
campaignEnd: 'date', | ||
campaignEndDate: '2025-09-30T00:00:00.000Z', | ||
acceptTermsAndConditions: true, | ||
transparencyTermsAccepted: true, | ||
personalInformationProcessingAccepted: true, | ||
} | ||
} | ||
|
||
function camAppForEdit(): CampaignApplicationExisting { | ||
return { | ||
id: 'eb4347a2-c8b4-47f1-83e5-67457b20909c', | ||
organizerName: 'Giver Dev', | ||
organizerEmail: '[email protected]', | ||
organizerPhone: '+35928700500', | ||
beneficiary: 'Bene', | ||
organizerBeneficiaryRel: 'бене', | ||
campaignName: 'Camp name', | ||
goal: 'Целта на кампанията', | ||
history: '', | ||
amount: '1455', | ||
description: '', | ||
state: 'requestInfo', | ||
campaignTypeId: 'c6ef0a79-11cf-4175-9f66-3cec940c9259', | ||
ticketURL: 'https://trello.com/linkforthiscamapp', | ||
archived: false, | ||
campaignEnd: 'date', | ||
campaignEndDate: '2025-09-30T00:00:00.000Z', | ||
acceptTermsAndConditions: true, | ||
transparencyTermsAccepted: true, | ||
personalInformationProcessingAccepted: true, | ||
documents: [], | ||
} | ||
} |
10 changes: 0 additions & 10 deletions
10
e2e/tests/regression/campaign-application/campaign-application-create.spec.ts
This file was deleted.
Oops, something went wrong.
195 changes: 195 additions & 0 deletions
195
e2e/tests/regression/campaign-application/campaign-application-giver.spec.ts
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,195 @@ | ||
import { | ||
CampaignApplicationResponse, | ||
CampaignApplicationExisting, | ||
CampaignApplicationAdminResponse, | ||
} from '../../../../src/gql/campaign-applications' | ||
import { Page } from 'playwright/test' | ||
import { expect, giverTest as test } from '../../../utils/fixtures' | ||
import { textLocalized } from '../../../utils/texts-localized' | ||
|
||
test.describe('Campaign application giver', () => { | ||
test('should see the first step - organizer - of create campaign application wizard and after accepting the terms to be able to go to step 2', async ({ | ||
page, | ||
baseURL, | ||
}) => { | ||
// arrange | ||
// act | ||
await page.goto(`${baseURL}/campaigns/application`) | ||
|
||
// assert | ||
const t = await textLocalized().campaign.bg() | ||
await expect(page.getByRole('heading')).toHaveText(t.steps.organizer.title) | ||
|
||
await page.getByRole('checkbox').first().click() | ||
await page.getByRole('checkbox').nth(1).click() | ||
await page.getByRole('checkbox').nth(2).click() | ||
|
||
await page.getByRole('button', { name: t.cta.next }).click() | ||
|
||
// assert | ||
await expect(page.getByRole('heading')).toHaveText(t.steps.application.title) | ||
}) | ||
|
||
test('should see the second step -application - of create campaign application wizard and after filling in the beneficiary, relations, title, type and funds go to step 3', async ({ | ||
page, | ||
baseURL, | ||
}) => { | ||
// arrange | ||
await page.goto(`${baseURL}/campaigns/application`) | ||
const t = await textLocalized().campaign.bg() | ||
|
||
// step 1 | ||
await page.getByRole('checkbox').first().click() | ||
await page.getByRole('checkbox').nth(1).click() | ||
await page.getByRole('checkbox').nth(2).click() | ||
await page.getByRole('button', { name: t.cta.next }).click() | ||
|
||
// act | ||
await page.getByLabel(t.steps.application.beneficiary).fill('beneficiary') | ||
await page.getByLabel(t.steps.application.beneficiaryRelationship).fill('rel') | ||
await page.getByLabel(t.steps.application.campaignTitle).fill('title') | ||
|
||
// select type of campaign app by opening the dropdown and arrow down and enter to select | ||
await page.locator('[name="applicationBasic.campaignType"]').click({ force: true }) // this is the underlying input and it's hidden - hence the force | ||
await page.keyboard.down('ArrowDown') | ||
await page.keyboard.down('Enter') | ||
|
||
await page.getByLabel(t.steps.application.funds).fill('12345') | ||
|
||
// go next | ||
await page.getByRole('button', { name: t.cta.next }).click() | ||
|
||
// assert | ||
await expect(page.getByRole('heading')).toHaveText(t.steps.details.title) | ||
}) | ||
|
||
test('should see the third step - details - of create campaign application wizard and after filling the title, description, history and 2 files be able to create a new campaign application', async ({ | ||
page, | ||
baseURL, | ||
}) => { | ||
// arrange | ||
await page.goto(`${baseURL}/campaigns/application`) | ||
const t = await textLocalized().campaign.bg() | ||
|
||
// step 1 | ||
await page.getByRole('checkbox').first().click() | ||
await page.getByRole('checkbox').nth(1).click() | ||
await page.getByRole('checkbox').nth(2).click() | ||
await page.getByRole('button', { name: t.cta.next }).click() | ||
// step 2 | ||
await page.getByLabel(t.steps.application.beneficiary).fill('beneficiary') | ||
await page.getByLabel(t.steps.application.beneficiaryRelationship).fill('rel') | ||
await page.getByLabel(t.steps.application.campaignTitle).fill('title') | ||
|
||
// select type of campaign app by opening the dropdown and arrow down and enter to select | ||
await page.locator('[name="applicationBasic.campaignType"]').click({ force: true }) // this is the underlying input and it's hidden - hence the force | ||
await page.keyboard.down('ArrowDown') | ||
await page.keyboard.down('Enter') | ||
|
||
await page.getByLabel(t.steps.application.funds).fill('12345') | ||
|
||
await page.getByRole('button', { name: t.cta.next }).click() | ||
|
||
// act | ||
await page.getByLabel(t.steps.details.cause).fill('goal') | ||
await page.getByLabel(t.steps.details.description).fill('description') | ||
await page.getByLabel(t.steps.details['current-status'].label).fill('history') | ||
|
||
await page.getByLabel(t.steps.details.documents).setInputFiles([ | ||
{ | ||
name: 'file.txt', | ||
mimeType: 'text/plain', | ||
buffer: Buffer.from('this is test'), | ||
}, | ||
{ | ||
name: 'file1.txt', | ||
mimeType: 'text/plain', | ||
buffer: Buffer.from('this is test'), | ||
}, | ||
]) | ||
|
||
// ensure we intercept the create and not let it go to the server... | ||
page.route('*/**/api/v1/campaign-application/create', (route, req) => { | ||
return route.fulfill({ | ||
json: defaultCampaignApplication(), | ||
}) | ||
}) | ||
// and the upload file as well | ||
page.route('*/**/api/v1/campaign-application/uploadFile/*', (route, req) => { | ||
return route.fulfill({ | ||
json: { id: '1' }, | ||
}) | ||
}) | ||
|
||
const [createApplication, uploadFile1, uploadFile2] = await Promise.all([ | ||
page.waitForRequest(/\/api\/v1\/campaign-application\/create/), | ||
page.waitForRequest(/\/api\/v1\/campaign-application\/uploadFile.*/), | ||
page.waitForRequest(/\/api\/v1\/campaign-application\/uploadFile.*/), | ||
page.getByRole('button', { name: t.cta.submit }).click(), | ||
]) | ||
|
||
// assert | ||
await expect(createApplication.postDataJSON()).toEqual({ | ||
acceptTermsAndConditions: true, | ||
amount: '12345', | ||
archived: false, | ||
beneficiary: 'beneficiary', | ||
campaignEnd: 'funds', | ||
campaignName: 'title', | ||
campaignTypeId: 'b9043466-a3c1-4ced-b951-6282ca3e6a7b', | ||
description: 'description', | ||
goal: 'goal', | ||
history: 'history', | ||
organizerBeneficiaryRel: 'rel', | ||
organizerEmail: '[email protected]', | ||
organizerName: 'Giver Dev', | ||
organizerPhone: '+35928700500', | ||
personalInformationProcessingAccepted: true, | ||
state: 'review', | ||
ticketURL: '', | ||
transparencyTermsAccepted: true, | ||
}) | ||
|
||
expect(uploadFile1.method()).toEqual('POST') | ||
expect(uploadFile1.url()).toMatch('api/v1/campaign-application/uploadFile/created') | ||
expect(uploadFile2.method()).toEqual('POST') | ||
expect(uploadFile2.url()).toMatch('api/v1/campaign-application/uploadFile/created') | ||
|
||
await expect(page.getByRole('heading')).toHaveText(t.result.created) | ||
await expect(page.getByText('file.txt')).toBeVisible() | ||
await expect(page.getByText('file1.txt')).toBeVisible() | ||
await expect(page.getByText('[email protected]')).toBeVisible() | ||
await expect(page.getByText('Giver Dev')).toBeVisible() | ||
await expect(page.getByText('+35928700500')).toBeVisible() | ||
await expect(page.getByText('beneficiary')).toBeVisible() | ||
await expect(page.getByText('rel')).toBeVisible() | ||
await expect(page.getByText('title')).toBeVisible() | ||
await expect(page.getByText('12345')).toBeVisible() | ||
await expect(page.getByText(t.steps.application['campaign-end'].options.funds)).toBeVisible() | ||
await expect(page.getByText('goal')).toBeVisible() | ||
}) | ||
}) | ||
|
||
function defaultCampaignApplication() { | ||
return { | ||
id: 'created', | ||
acceptTermsAndConditions: true, | ||
personalInformationProcessingAccepted: true, | ||
transparencyTermsAccepted: true, | ||
organizerName: 'Giver Dev', | ||
organizerEmail: '[email protected]', | ||
organizerPhone: '+35928700500', | ||
beneficiary: 'beneficiary', | ||
campaignName: 'title', | ||
amount: '12345', | ||
goal: 'goal', | ||
description: '', | ||
organizerBeneficiaryRel: 'rel', | ||
history: '', | ||
campaignEnd: 'funds', | ||
campaignTypeId: 'b9043466-a3c1-4ced-b951-6282ca3e6a7b', | ||
archived: false, | ||
state: 'review', | ||
ticketURL: '', | ||
} | ||
} |
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,11 @@ | ||
{ | ||
"extends": "../tsconfig.json", | ||
"compilerOptions": { | ||
"rootDir": "..", | ||
"paths": { | ||
"@src/*": ["./src/*"] | ||
} | ||
}, | ||
"include": ["./e2e", "./src"], | ||
"exclude": ["./node_modules"] | ||
} |
Oops, something went wrong.