diff --git a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json index 0ee8eeaea89d..1ad38885de21 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package-lock.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package-lock.json @@ -8,7 +8,7 @@ "hasInstallScript": true, "dependencies": { "@umbraco/json-models-builders": "^2.0.5", - "@umbraco/playwright-testhelpers": "^2.0.0-beta.54", + "@umbraco/playwright-testhelpers": "^2.0.0-beta.57", "camelize": "^1.0.0", "dotenv": "^16.3.1", "faker": "^4.1.0", @@ -146,9 +146,9 @@ "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==" }, "node_modules/@umbraco/playwright-testhelpers": { - "version": "2.0.0-beta.54", - "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-2.0.0-beta.54.tgz", - "integrity": "sha512-5nj4aMd2eDI04qEi6iPgh1FlhC86UbMpucBcliZyyZDlC8WGleiOf3jwPzYMIDOR0xuju3i65OHgcmDT0QWuOg==", + "version": "2.0.0-beta.57", + "resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-2.0.0-beta.57.tgz", + "integrity": "sha512-G3RttCiwjygRsa2EcoYAz34IdDX+pHCbqFZG+MMc1tLJu0qQVNykykw15qfOfkBaIPxXSM3zHTCDGSOUY8Jt7w==", "dependencies": { "@umbraco/json-models-builders": "2.0.6", "camelize": "^1.0.0", diff --git a/tests/Umbraco.Tests.AcceptanceTest/package.json b/tests/Umbraco.Tests.AcceptanceTest/package.json index 81cd3194bdb4..6729830dde07 100644 --- a/tests/Umbraco.Tests.AcceptanceTest/package.json +++ b/tests/Umbraco.Tests.AcceptanceTest/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@umbraco/json-models-builders": "^2.0.5", - "@umbraco/playwright-testhelpers": "^2.0.0-beta.54", + "@umbraco/playwright-testhelpers": "^2.0.0-beta.57", "camelize": "^1.0.0", "dotenv": "^16.3.1", "faker": "^4.1.0", diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/Member.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/Member.spec.ts new file mode 100644 index 000000000000..99e92a954d1c --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/Member.spec.ts @@ -0,0 +1,45 @@ +import {test} from '@umbraco/playwright-testhelpers'; +import {expect} from "@playwright/test"; + +test.describe('Member tests', () => { + let memberId = ''; + let memberTypeId = ''; + const memberName = 'TestMember'; + const memberTypeName = 'TestMemberType'; + const username = 'testmember'; + const email = 'testmember@acceptance.test'; + const password = '0123456789'; + + test.beforeEach(async ({umbracoApi}) => { + await umbracoApi.memberType.ensureNameNotExists(memberTypeName); + await umbracoApi.member.ensureNameNotExists(memberName); + }); + + test.afterEach(async ({umbracoApi}) => { + await umbracoApi.memberType.ensureNameNotExists(memberTypeName); + await umbracoApi.member.ensureNameNotExists(memberName); + }); + + test('can create a member', async ({umbracoApi}) => { + // Arrange + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + + // Act + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + + // Assert + expect(await umbracoApi.member.doesExist(memberId)).toBeTruthy(); + }); + + test('can delete a member', async ({umbracoApi}) => { + // Arrange + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + + // Act + await umbracoApi.member.delete(memberId); + + // Assert + expect(await umbracoApi.member.doesExist(memberId)).toBeFalsy(); + }); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/MemberGroup.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/MemberGroup.spec.ts new file mode 100644 index 000000000000..d606925e0cd6 --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/ApiTesting/Member/MemberGroup.spec.ts @@ -0,0 +1,50 @@ +import {test} from '@umbraco/playwright-testhelpers'; +import {expect} from "@playwright/test"; + +test.describe('Member Group tests', () => { + let memberGroupId = ''; + const memberGroupName = 'TestMemberGroup'; + + test.beforeEach(async ({umbracoApi}) => { + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); + }); + + test.afterEach(async ({umbracoApi}) => { + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); + }); + + test('can create a member group', async ({umbracoApi}) => { + // Act + memberGroupId = await umbracoApi.memberGroup.create(memberGroupName); + + // Assert + expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy(); + }); + + test('can rename a member group', async ({umbracoApi}) => { + // Arrange + const wrongMemberGroupName = 'Wrong Name'; + await umbracoApi.memberGroup.ensureNameNotExists(wrongMemberGroupName); + memberGroupId = await umbracoApi.memberGroup.create(wrongMemberGroupName); + expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy(); + + // Act + await umbracoApi.memberGroup.rename(memberGroupId, memberGroupName); + + // Assert + expect(await umbracoApi.memberGroup.doesNameExist(memberGroupName)).toBeTruthy(); + expect(await umbracoApi.memberGroup.doesNameExist(wrongMemberGroupName)).toBeFalsy(); + }); + + test('can delete a member group', async ({umbracoApi}) => { + // Arrange + memberGroupId = await umbracoApi.memberGroup.create(memberGroupName); + expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy(); + + // Act + await umbracoApi.memberGroup.delete(memberGroupId); + + // Assert + expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeFalsy(); + }); +}); \ No newline at end of file diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/MemberGroups.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/MemberGroups.spec.ts new file mode 100644 index 000000000000..d3e3dc2c8759 --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/MemberGroups.spec.ts @@ -0,0 +1,47 @@ +import {ConstantHelper, test} from '@umbraco/playwright-testhelpers'; +import {expect} from "@playwright/test"; + +const memberGroupName = 'Test Member Group'; + +test.beforeEach(async ({umbracoApi, umbracoUi}) => { + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); + await umbracoUi.goToBackOffice(); + await umbracoUi.memberGroup.goToSection(ConstantHelper.sections.members); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); +}); + +test('can create a member group', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Act + await umbracoUi.memberGroup.clickMemberGroupsTab(); + await umbracoUi.memberGroup.clickCreateButton(); + await umbracoUi.memberGroup.enterMemberGroupName(memberGroupName); + await umbracoUi.memberGroup.clickSaveButton(); + + // Assert + await umbracoUi.memberGroup.isSuccessNotificationVisible(); + await umbracoUi.memberGroup.clickLeftArrowButton(); + await umbracoUi.memberGroup.isMemberGroupNameVisible(memberGroupName); + expect(await umbracoApi.memberGroup.doesNameExist(memberGroupName)).toBeTruthy(); +}); + +// TODO: Remove skip when the front-end is ready. Currently it is impossible to delete a member group. +test.skip('can delete a member group', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoApi.memberGroup.create(memberGroupName); + expect(await umbracoApi.memberGroup.doesNameExist(memberGroupName)).toBeTruthy(); + + // Act + await umbracoUi.memberGroup.clickMemberGroupsTab(); + await umbracoUi.memberGroup.clickMemberGroupLinkByName(memberGroupName); + await umbracoUi.memberGroup.clickActionsButton(); + await umbracoUi.memberGroup.clickDeleteButton(); + await umbracoUi.memberGroup.clickConfirmToDeleteButton(); + + // Assert + await umbracoUi.memberGroup.isSuccessNotificationVisible(); + await umbracoUi.memberGroup.isMemberGroupNameVisible(memberGroupName, false); + expect(await umbracoApi.memberGroup.doesNameExist(memberGroupName)).toBeFalsy(); +}); diff --git a/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/Members.spec.ts b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/Members.spec.ts new file mode 100644 index 000000000000..b8189e1d14c0 --- /dev/null +++ b/tests/Umbraco.Tests.AcceptanceTest/tests/DefaultConfig/Members/Members.spec.ts @@ -0,0 +1,213 @@ +import {ConstantHelper, test} from '@umbraco/playwright-testhelpers'; +import {expect} from "@playwright/test"; + +let memberId = ''; +let memberTypeId = ''; +const defaultMemberTypeName = 'Member'; +const memberName = 'Test Member'; +const memberTypeName = 'Test Member Type'; +const comment = 'This is test comment'; +const username = 'testmember'; +const email = 'testmember@acceptance.test'; +const password = '0123456789'; + +test.beforeEach(async ({umbracoApi, umbracoUi}) => { + await umbracoApi.memberType.ensureNameNotExists(memberTypeName); + await umbracoApi.member.ensureNameNotExists(memberName); + await umbracoUi.goToBackOffice(); +}); + +test.afterEach(async ({umbracoApi}) => { + await umbracoApi.memberType.ensureNameNotExists(memberTypeName); + await umbracoApi.member.ensureNameNotExists(memberName); +}); + +test('can create a member', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickCreateButton(); + await umbracoUi.member.enterMemberName(memberName); + await umbracoUi.member.enterUsername(username); + await umbracoUi.member.enterEmail(email); + await umbracoUi.member.enterPassword(password); + await umbracoUi.member.enterConfirmPassword(password); + await umbracoUi.member.clickDetailsTab(); + await umbracoUi.member.enterComments(comment); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + expect(await umbracoApi.member.doesNameExist(memberName)).toBeTruthy(); +}); + +test('can edit comments', async ({umbracoApi, umbracoUi}) => { + // Arrange + const defaultMemberTypeData = await umbracoApi.memberType.getByName(defaultMemberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, defaultMemberTypeData.id, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.clickDetailsTab(); + await umbracoUi.member.enterComments(comment); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.values[0].value).toBe(comment); +}); + +test('can edit username', async ({umbracoApi, umbracoUi}) => { + // Arrange + const updatedUsername = 'updatedusername'; + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.enterUsername(updatedUsername); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.username).toBe(updatedUsername); +}); + +test('can edit email', async ({umbracoApi, umbracoUi}) => { + // Arrange + const updatedEmail = 'updated@acceptance.test'; + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.enterEmail(updatedEmail); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.email).toBe(updatedEmail); +}); + +test('can edit password', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const updatedPassword = '9876543210'; + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.clickChangePasswordButton(); + await umbracoUi.member.enterNewPassword(updatedPassword); + await umbracoUi.member.enterConfirmPassword(updatedPassword); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); +}); + +test('can add member group', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + const memberGroupName = 'TestMemberGroup'; + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); + const memberGroupId = await umbracoApi.memberGroup.create(memberGroupName); + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.chooseMemberGroup(memberGroupName); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.groups[0]).toBe(memberGroupId); + + // Clean + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); +}); + +test('can remove member group', async ({umbracoApi, umbracoUi}) => { + // Arrange + const memberGroupName = 'TestMemberGroup'; + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); + const memberGroupId = await umbracoApi.memberGroup.create(memberGroupName); + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createMemberWithMemberGroup(memberName, memberTypeId, email, username, password, memberGroupId); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.clickRemoveMemberGroupByName(memberGroupName); + await umbracoUi.member.clickConfirmRemoveButton(); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.groups.length).toBe(0); + + // Clean + await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName); +}); + +test('can view member info', async ({umbracoApi, umbracoUi}) => { + // Arrange + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + + // Assert + const memberData = await umbracoApi.member.get(memberId); + await umbracoUi.member.doesMemberInfoHaveValue('Failed login attempts', memberData.failedPasswordAttempts.toString()); + await umbracoUi.member.doesMemberInfoHaveValue('Last lockout date', memberData.lastLoginDate == null ? 'never' : memberData.lastLoginDate); + await umbracoUi.member.doesMemberInfoHaveValue('Last login', memberData.lastLoginDate == null ? 'never' : memberData.lastLoginDate); + await umbracoUi.member.doesMemberInfoHaveValue('Password changed', new Date(memberData.lastPasswordChangeDate).toLocaleString()); +}); + +test('can enable approved', async ({umbracoApi, umbracoUi}) => { + // Arrange + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.member.clickApprovedSlider(); + await umbracoUi.member.clickSaveButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + const memberData = await umbracoApi.member.get(memberId); + expect(memberData.isApproved).toBe(true); +}); + +test('can delete member', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => { + // Arrange + memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName); + memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password); + await umbracoUi.member.goToSection(ConstantHelper.sections.members); + + // Act + await umbracoUi.member.clickMemberLinkByName(memberName); + await umbracoUi.memberGroup.clickActionsButton(); + await umbracoUi.memberGroup.clickDeleteButton(); + await umbracoUi.memberGroup.clickConfirmToDeleteButton(); + + // Assert + await umbracoUi.member.isSuccessNotificationVisible(); + expect(await umbracoApi.member.doesNameExist(memberName)).toBeFalsy(); +});