test: cover accept invitation flow
This commit is contained in:
31
packages/e2e-tests/fixtures/accept-invitation-page.js
Normal file
31
packages/e2e-tests/fixtures/accept-invitation-page.js
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -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(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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')
|
||||||
|
@@ -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}
|
||||||
|
@@ -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')}
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user