200 lines
7.5 KiB
JavaScript
200 lines
7.5 KiB
JavaScript
import { expect, test } from '@playwright/test';
|
|
|
|
const adminEmail = 'e2e-admin@example.com';
|
|
const adminPassword = 'e2e-pass-123';
|
|
|
|
test.describe.configure({ mode: 'serial' });
|
|
|
|
/**
|
|
* @param {import('@playwright/test').APIRequestContext} request
|
|
* @param {string} email
|
|
* @param {string} template
|
|
*/
|
|
async function latestLink(request, email, template) {
|
|
const response = await request.get(
|
|
`http://127.0.0.1:4000/api/dev/outbox?email=${encodeURIComponent(email)}&template=${template}`,
|
|
);
|
|
expect(response.ok()).toBeTruthy();
|
|
const rows = await response.json();
|
|
const last = rows.at(-1);
|
|
expect(last?.url).toBeTruthy();
|
|
const url = new URL(last.url);
|
|
url.protocol = 'http:';
|
|
url.host = '127.0.0.1:5173';
|
|
return url.toString();
|
|
}
|
|
|
|
/**
|
|
* @param {import('@playwright/test').Page} page
|
|
* @param {string} registration
|
|
*/
|
|
async function fillAgreement(page, registration, email) {
|
|
await expect(page.locator('#agreement_date')).not.toHaveValue('');
|
|
await page.locator('#email').fill(email);
|
|
await page.locator('#full_name').fill('E2E Physician');
|
|
await page.locator('#age').fill('42');
|
|
await page.locator('#address').fill('Pune');
|
|
await page.locator('#registration_no').fill(registration);
|
|
await page.locator('#medical_council').fill('Maharashtra Medical Council');
|
|
await page.locator('#pan').fill('ABCDE1234F');
|
|
await page.locator('#bank_name').fill('State Bank of India');
|
|
await page.locator('#account_holder').fill('E2E Physician');
|
|
await page.locator('#account_number').fill('123456789012');
|
|
await page.locator('#ifsc').fill('SBIN0001234');
|
|
await page.locator('#accepted').check();
|
|
await page.getByRole('button', { name: 'Continue to review' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Review agreement' })).toBeVisible();
|
|
}
|
|
|
|
/**
|
|
* @param {import('@playwright/test').Page} page
|
|
*/
|
|
async function signAgreement(page) {
|
|
await page.getByRole('button', { name: 'Proceed to sign' }).click();
|
|
await page.getByRole('tab', { name: 'Type instead' }).click();
|
|
await page.locator('#typed-name').fill('E2E Physician');
|
|
await page.getByRole('button', { name: 'Submit signature' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Agreement submitted' })).toBeVisible();
|
|
}
|
|
|
|
/**
|
|
* @param {import('@playwright/test').Page} page
|
|
* @param {string} registration
|
|
*/
|
|
async function openApplication(page, registration) {
|
|
await page.goto('/admin/login');
|
|
await page.locator('#admin-email').fill(adminEmail);
|
|
await page.locator('#admin-password').fill(adminPassword);
|
|
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
await expect(page.getByRole('link', { name: 'Applications' })).toBeVisible();
|
|
await page.goto('/admin/applications');
|
|
await page.getByLabel('Search').fill(registration);
|
|
await page
|
|
.getByRole('row', { name: new RegExp(registration) })
|
|
.getByRole('link')
|
|
.click();
|
|
await expect(page.getByRole('heading', { name: 'E2E Physician' })).toBeVisible();
|
|
}
|
|
|
|
/**
|
|
* @param {import('@playwright/test').Page} page
|
|
*/
|
|
async function fillSurveySection(page) {
|
|
const numbers = page.locator('section input[type="number"]');
|
|
const numberCount = await numbers.count();
|
|
|
|
for (let index = 0; index < numberCount; index += 1) {
|
|
await numbers.nth(index).fill('25');
|
|
}
|
|
|
|
const texts = page.locator('section input[type="text"], section textarea');
|
|
const textCount = await texts.count();
|
|
|
|
for (let index = 0; index < textCount; index += 1) {
|
|
if (!(await texts.nth(index).inputValue())) {
|
|
await texts.nth(index).fill('Pune clinic');
|
|
}
|
|
}
|
|
|
|
const radios = page.locator('section input[type="radio"]');
|
|
const seen = new Set();
|
|
const radioCount = await radios.count();
|
|
|
|
for (let index = 0; index < radioCount; index += 1) {
|
|
const name = await radios.nth(index).getAttribute('name');
|
|
|
|
if (name && !seen.has(name)) {
|
|
seen.add(name);
|
|
await radios.nth(index).check();
|
|
}
|
|
}
|
|
|
|
const boxes = page.locator('section input[type="checkbox"]');
|
|
|
|
if ((await boxes.count()) > 0) {
|
|
await boxes.first().check();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {import('@playwright/test').Page} page
|
|
*/
|
|
async function completeSurvey(page) {
|
|
await expect(page.locator('section h2').first()).toBeVisible();
|
|
|
|
for (let step = 0; step < 24; step += 1) {
|
|
const title = await page.locator('section h2').first().innerText();
|
|
|
|
if (title === 'Review') {
|
|
break;
|
|
}
|
|
|
|
await fillSurveySection(page);
|
|
const progress = await page.getByRole('progressbar').getAttribute('aria-valuenow');
|
|
await page.getByRole('button', { name: 'Next' }).click();
|
|
await expect(page.getByRole('progressbar')).not.toHaveAttribute(
|
|
'aria-valuenow',
|
|
progress ?? '',
|
|
);
|
|
}
|
|
|
|
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
|
await page.getByRole('dialog').getByRole('button', { name: 'Submit' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Thank you' })).toBeVisible();
|
|
}
|
|
|
|
test('completes the agreement and refuses a second survey', async ({ page, request }) => {
|
|
const email = `e2e-approve-${Date.now()}@example.com`;
|
|
const registration = `MMC-E2E-${Date.now()}`;
|
|
|
|
await page.goto('/');
|
|
await fillAgreement(page, registration, email);
|
|
await page.getByRole('button', { name: 'Edit details' }).click();
|
|
await expect(page.locator('#full_name')).toHaveValue('E2E Physician');
|
|
await expect(page.locator('#agreement_date')).not.toHaveValue('');
|
|
await page.locator('#address').fill('Pune clinic');
|
|
await page.getByRole('button', { name: 'Continue to review' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Review agreement' })).toBeVisible();
|
|
await signAgreement(page);
|
|
|
|
await openApplication(page, registration);
|
|
await page.getByRole('button', { name: 'Approve', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Approve', exact: true }).last().click();
|
|
await expect(page.getByText('APPROVED', { exact: true })).toBeVisible();
|
|
|
|
await page.goto(await latestLink(request, email, 'approved'));
|
|
await completeSurvey(page);
|
|
await page.reload();
|
|
await expect(page.getByRole('heading', { name: 'Already submitted' })).toBeVisible();
|
|
});
|
|
|
|
test('returns a rejected agreement for a new signature and approval', async ({ page, request }) => {
|
|
const email = `e2e-reject-${Date.now()}@example.com`;
|
|
const registration = `MMC-REJ-${Date.now()}`;
|
|
|
|
await page.goto('/');
|
|
await fillAgreement(page, registration, email);
|
|
await signAgreement(page);
|
|
|
|
await openApplication(page, registration);
|
|
await page.getByRole('button', { name: 'Reject', exact: true }).click();
|
|
await page.locator('#reject-reason').fill('Please correct the clinic address.');
|
|
await page.getByRole('button', { name: 'Reject' }).last().click();
|
|
await expect(page.getByText('REJECTED', { exact: true })).toBeVisible();
|
|
|
|
await page.goto(await latestLink(request, email, 'rejected'));
|
|
await page.getByRole('button', { name: 'Edit and resubmit' }).click();
|
|
await expect(page.locator('#full_name')).toHaveValue('E2E Physician');
|
|
await expect(page.locator('#agreement_date')).not.toHaveValue('');
|
|
await page.locator('#address').fill('Corrected Pune clinic');
|
|
await page.locator('#accepted').check();
|
|
await page.getByRole('button', { name: 'Continue to review' }).click();
|
|
await expect(page.getByRole('heading', { name: 'Review agreement' })).toBeVisible();
|
|
await signAgreement(page);
|
|
|
|
await openApplication(page, registration);
|
|
await page.getByRole('button', { name: 'Approve', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Approve', exact: true }).last().click();
|
|
await expect(page.getByText('APPROVED', { exact: true })).toBeVisible();
|
|
});
|