test: cover accept invitation flow

This commit is contained in:
Ali BARIN
2024-07-10 10:33:59 +00:00
committed by Faruk AYDIN
parent 2bd4dd3ab0
commit a9f5736c12
8 changed files with 67 additions and 6 deletions

View File

@@ -0,0 +1,31 @@
const { BasePage } = require('./base-page');
export class AcceptInvitation extends BasePage {
path = '/accept-invitation';
/**
* @param {import('@playwright/test').Page} page
*/
constructor(page) {
super(page);
this.page = page;
this.passwordTextField = this.page.getByTestId('password-text-field');
this.passwordConfirmationTextField = this.page.getByTestId('confirm-password-text-field');
this.submitButton = this.page.getByTestId('submit-button');
this.pageTitle = this.page.getByTestId('accept-invitation-form-title');
}
async open(token) {
return await this.page.goto(`${this.path}?token=${token}`);
}
async acceptInvitation(
password
) {
await this.passwordTextField.fill(password);
await this.passwordConfirmationTextField.fill(password);
await this.submitButton.click();
}
}

View File

@@ -15,6 +15,7 @@ export class AdminCreateUserPage extends AuthenticatedPage {
this.createButton = page.getByTestId('create-button'); this.createButton = page.getByTestId('create-button');
this.pageTitle = page.getByTestId('create-user-title'); this.pageTitle = page.getByTestId('create-user-title');
this.invitationEmailInfoAlert = page.getByTestId('invitation-email-info-alert'); this.invitationEmailInfoAlert = page.getByTestId('invitation-email-info-alert');
this.acceptInvitationLink = page.getByTestId('invitation-email-info-alert').getByRole('link');
} }
seed(seed) { seed(seed) {
@@ -25,7 +26,6 @@ export class AdminCreateUserPage extends AuthenticatedPage {
return { return {
fullName: faker.person.fullName(), fullName: faker.person.fullName(),
email: faker.internet.email().toLowerCase(), email: faker.internet.email().toLowerCase(),
password: faker.internet.password(),
}; };
} }
} }

View File

@@ -1,5 +1,6 @@
const { test, expect } = require('../../fixtures/index'); const { test, expect } = require('../../fixtures/index');
const { LoginPage } = require('../../fixtures/login-page'); const { LoginPage } = require('../../fixtures/login-page');
const { AcceptInvitation } = require('../../fixtures/accept-invitation-page');
test.describe('Role management page', () => { test.describe('Role management page', () => {
test('Admin role is not deletable', async ({ adminRolesPage }) => { test('Admin role is not deletable', async ({ adminRolesPage }) => {
@@ -397,10 +398,23 @@ test('Accessibility of role management page', async ({
}); });
await test.step('Logout and login to the basic role user', async () => { await test.step('Logout and login to the basic role user', async () => {
const acceptInvitationLink = await adminCreateUserPage.acceptInvitationLink;
console.log(acceptInvitationLink);
const acceptInvitationUrl = await acceptInvitationLink.textContent();
console.log(acceptInvitationUrl);
const acceptInvitatonToken = acceptInvitationUrl.split('?token=')[1];
await page.getByTestId('profile-menu-button').click(); await page.getByTestId('profile-menu-button').click();
await page.getByTestId('logout-item').click(); await page.getByTestId('logout-item').click();
// await page.reload({ waitUntil: 'networkidle' });
const acceptInvitationPage = new AcceptInvitation(page);
await acceptInvitationPage.open(acceptInvitatonToken);
await acceptInvitationPage.acceptInvitation('sample');
const loginPage = new LoginPage(page); const loginPage = new LoginPage(page);
// await loginPage.isMounted(); // await loginPage.isMounted();
await loginPage.login('basic-role-test@automatisch.io', 'sample'); await loginPage.login('basic-role-test@automatisch.io', 'sample');
await expect(loginPage.loginButton).not.toBeVisible(); await expect(loginPage.loginButton).not.toBeVisible();
@@ -416,9 +430,14 @@ test('Accessibility of role management page', async ({
await page.waitForTimeout(750); await page.waitForTimeout(750);
const isUnmounted = await page.evaluate(() => { const isUnmounted = await page.evaluate(() => {
const root = document.querySelector('#root'); const root = document.querySelector('#root');
if (root) { if (root) {
return root.children.length === 0; // We have react query devtools only in dev env.
// In production, there is nothing in root.
// That's why `<= 1`.
return root.children.length <= 1;
} }
return false; return false;
}); });
await expect(isUnmounted).toBe(true); await expect(isUnmounted).toBe(true);

View File

@@ -42,6 +42,7 @@ test.describe('User management page', () => {
'snackbar-create-user-success' 'snackbar-create-user-success'
); );
await expect(snackbar.variant).toBe('success'); await expect(snackbar.variant).toBe('success');
await adminUsersPage.navigateTo();
await adminUsersPage.closeSnackbar(); await adminUsersPage.closeSnackbar();
} }
); );
@@ -108,6 +109,7 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Create the test user', 'Create the test user',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.createUserButton.click(); await adminUsersPage.createUserButton.click();
await adminCreateUserPage.fullNameInput.fill(testUser.fullName); await adminCreateUserPage.fullNameInput.fill(testUser.fullName);
await adminCreateUserPage.emailInput.fill(testUser.email); await adminCreateUserPage.emailInput.fill(testUser.email);
@@ -127,6 +129,7 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Delete the created user', 'Delete the created user',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.findUserPageWithEmail(testUser.email); await adminUsersPage.findUserPageWithEmail(testUser.email);
const userRow = await adminUsersPage.getUserRowByEmail(testUser.email); const userRow = await adminUsersPage.getUserRowByEmail(testUser.email);
await adminUsersPage.clickDeleteUser(userRow); await adminUsersPage.clickDeleteUser(userRow);
@@ -148,7 +151,6 @@ test.describe('User management page', () => {
await adminUsersPage.createUserButton.click(); await adminUsersPage.createUserButton.click();
await adminCreateUserPage.fullNameInput.fill(testUser.fullName); await adminCreateUserPage.fullNameInput.fill(testUser.fullName);
await adminCreateUserPage.emailInput.fill(testUser.email); await adminCreateUserPage.emailInput.fill(testUser.email);
await adminCreateUserPage.passwordInput.fill(testUser.password);
await adminCreateUserPage.roleInput.click(); await adminCreateUserPage.roleInput.click();
await adminCreateUserPage.page.getByRole( await adminCreateUserPage.page.getByRole(
'option', { name: 'Admin' } 'option', { name: 'Admin' }
@@ -197,10 +199,10 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Create the user again', 'Create the user again',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.createUserButton.click(); await adminUsersPage.createUserButton.click();
await adminCreateUserPage.fullNameInput.fill(testUser.fullName); await adminCreateUserPage.fullNameInput.fill(testUser.fullName);
await adminCreateUserPage.emailInput.fill(testUser.email); await adminCreateUserPage.emailInput.fill(testUser.email);
await adminCreateUserPage.passwordInput.fill(testUser.password);
const createUserPageUrl = page.url(); const createUserPageUrl = page.url();
await adminCreateUserPage.roleInput.click(); await adminCreateUserPage.roleInput.click();
await adminCreateUserPage.page.getByRole( await adminCreateUserPage.page.getByRole(
@@ -228,6 +230,7 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Create the first user', 'Create the first user',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.createUserButton.click(); await adminUsersPage.createUserButton.click();
await adminCreateUserPage.fullNameInput.fill(user1.fullName); await adminCreateUserPage.fullNameInput.fill(user1.fullName);
await adminCreateUserPage.emailInput.fill(user1.email); await adminCreateUserPage.emailInput.fill(user1.email);
@@ -247,10 +250,10 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Create the second user', 'Create the second user',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.createUserButton.click(); await adminUsersPage.createUserButton.click();
await adminCreateUserPage.fullNameInput.fill(user2.fullName); await adminCreateUserPage.fullNameInput.fill(user2.fullName);
await adminCreateUserPage.emailInput.fill(user2.email); await adminCreateUserPage.emailInput.fill(user2.email);
await adminCreateUserPage.passwordInput.fill(user2.password);
await adminCreateUserPage.roleInput.click(); await adminCreateUserPage.roleInput.click();
await adminCreateUserPage.page.getByRole( await adminCreateUserPage.page.getByRole(
'option', { name: 'Admin' } 'option', { name: 'Admin' }
@@ -267,6 +270,7 @@ test.describe('User management page', () => {
await test.step( await test.step(
'Try editing the second user to have the email of the first user', 'Try editing the second user to have the email of the first user',
async () => { async () => {
await adminUsersPage.navigateTo();
await adminUsersPage.findUserPageWithEmail(user2.email); await adminUsersPage.findUserPageWithEmail(user2.email);
let userRow = await adminUsersPage.getUserRowByEmail(user2.email); let userRow = await adminUsersPage.getUserRowByEmail(user2.email);
await adminUsersPage.clickEditUser(userRow); await adminUsersPage.clickEditUser(userRow);

View File

@@ -36,6 +36,7 @@ test.describe('Connections page', () => {
}) => { }) => {
await connectionsPage.clickAddConnectionButton(); await connectionsPage.clickAddConnectionButton();
await expect(page).toHaveURL('/app/ntfy/connections/add?shared=false'); await expect(page).toHaveURL('/app/ntfy/connections/add?shared=false');
await expect(page.getByTestId('create-connection-button')).not.toBeDisabled();
await page.getByTestId('create-connection-button').click(); await page.getByTestId('create-connection-button').click();
await expect( await expect(
page.getByTestId('create-connection-button') page.getByTestId('create-connection-button')

View File

@@ -57,6 +57,7 @@ export default function ResetPasswordForm() {
mb: 2, mb: 2,
}} }}
gutterBottom gutterBottom
data-test="accept-invitation-form-title"
> >
{formatMessage('acceptInvitationForm.title')} {formatMessage('acceptInvitationForm.title')}
</Typography> </Typography>
@@ -70,6 +71,7 @@ export default function ResetPasswordForm() {
<TextField <TextField
label={formatMessage('acceptInvitationForm.passwordFieldLabel')} label={formatMessage('acceptInvitationForm.passwordFieldLabel')}
name="password" name="password"
data-test="password-text-field"
fullWidth fullWidth
margin="dense" margin="dense"
type="password" type="password"
@@ -90,6 +92,7 @@ export default function ResetPasswordForm() {
'acceptInvitationForm.confirmPasswordFieldLabel', 'acceptInvitationForm.confirmPasswordFieldLabel',
)} )}
name="confirmPassword" name="confirmPassword"
data-test="confirm-password-text-field"
fullWidth fullWidth
margin="dense" margin="dense"
type="password" type="password"
@@ -118,6 +121,7 @@ export default function ResetPasswordForm() {
<LoadingButton <LoadingButton
type="submit" type="submit"
variant="contained" variant="contained"
data-test="submit-button"
color="primary" color="primary"
sx={{ boxShadow: 2, my: 3 }} sx={{ boxShadow: 2, my: 3 }}
loading={acceptInvitation.isPending} loading={acceptInvitation.isPending}

View File

@@ -151,6 +151,7 @@ function AddAppConnection(props) {
color="primary" color="primary"
sx={{ boxShadow: 2 }} sx={{ boxShadow: 2 }}
loading={inProgress} loading={inProgress}
disabled={!authenticate}
data-test="create-connection-button" data-test="create-connection-button"
> >
{formatMessage('addAppConnection.submit')} {formatMessage('addAppConnection.submit')}

View File

@@ -35,6 +35,7 @@ root.render(
</SnackbarProvider> </SnackbarProvider>
</Router>, </Router>,
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log)) // to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals