diff --git a/cypress/e2e/default/settings/username-change.ts b/cypress/e2e/default/settings/username-change.ts deleted file mode 100644 index 312656d5a55..00000000000 --- a/cypress/e2e/default/settings/username-change.ts +++ /dev/null @@ -1,140 +0,0 @@ -describe('Username input field', () => { - beforeEach(() => { - cy.login(); - cy.goToSettings(); - }); - - it('Should show username is available if it is', () => { - cy.typeUsername('brad'); - - cy.contains('Username is available') - .should('be.visible') - .should('have.attr', 'role', 'alert'); - }); - - it('Should info message if username is available', () => { - cy.typeUsername('mrugesh'); - - cy.contains( - 'Please note, changing your username will also change ' + - 'the URL to your profile and your certifications.' - ) - .should('be.visible') - .should('have.attr', 'role', 'alert'); - }); - - it('Should be able to click the `Save` button if username is available', () => { - cy.typeUsername('oliver'); - - cy.get('@usernameForm').within(() => { - cy.contains('Save').should('have.attr', 'aria-disabled', 'false'); - }); - }); - - it('Should show username is unavailable if it is', () => { - cy.typeUsername('twaha'); - - cy.contains('Username not available') - .should('be.visible') - .should('have.attr', 'role', 'alert'); - }); - - it('Should not be possible to click the `Save` button if username is unavailable', () => { - cy.typeUsername('twaha'); - - cy.contains('Username is available').should('not.exist'); - cy.contains('Username not available').should('not.exist'); - cy.contains( - 'Please note, changing your username will also change ' + - 'the URL to your profile and your certifications.' - ).should('not.exist'); - - cy.get('@usernameForm') - .contains('Save') - .should('have.attr', 'aria-disabled', 'true'); - }); - - it('Should not show anything if user types their current name', () => { - cy.typeUsername('developmentuser'); - - cy.get('@usernameForm') - .contains('Save') - .should('have.attr', 'aria-disabled', 'true'); - }); - - it('Should not be possible to click the `Save` button if user types their current name', () => { - cy.typeUsername('developmentuser'); - - cy.get('@usernameForm') - .contains('Save') - .should('have.attr', 'aria-disabled', 'true'); - }); - - it('Should not be able to click the `Save` button if username includes invalid character', () => { - cy.typeUsername('Quincy Larson'); - - cy.get('@usernameForm') - .contains('Save') - .should('have.attr', 'aria-disabled', 'true'); - }); - - it('Should change username if `Save` button is clicked', () => { - cy.typeUsername('quincy'); - - cy.contains('Username is available'); - - cy.get('@usernameForm').contains('Save').click({ force: true }); - cy.contains('Account Settings for quincy').should('be.visible'); - - cy.resetUsername(); - }); - - it('Should change username with uppercase characters if `Save` button is clicked', () => { - cy.typeUsername('Quincy'); - - cy.contains('Username is available'); - - cy.get('@usernameForm').contains('Save').click({ force: true }); - cy.contains('Account Settings for Quincy').should('be.visible'); - - cy.resetUsername(); - }); - - it('Should show flash message showing username has been updated', () => { - cy.typeUsername('nhcarrigan'); - cy.contains('Username is available'); - - cy.get('@usernameInput').type('{enter}', { force: true, release: false }); - - cy.contains('We have updated your username to nhcarrigan').should( - 'be.visible' - ); - cy.resetUsername(); - }); - - it('Should be able to close the shown flash message', () => { - cy.typeUsername('bjorno'); - cy.contains('Username is available'); - - cy.get('@usernameInput').type('{enter}', { force: true, release: false }); - - cy.contains('We have updated your username to bjorno').within(() => { - cy.get('button').click(); - }); - - cy.contains('We have updated your username to bjorno').should('not.exist'); - - cy.resetUsername(); - }); - - it('Should change username if enter is pressed', () => { - cy.typeUsername('symbol'); - cy.contains('Username is available'); - - cy.get('@usernameInput').type('{enter}', { force: true, release: false }); - - cy.contains('Account Settings for symbol').should('be.visible'); - - cy.resetUsername(); - }); -}); diff --git a/e2e/settings.spec.ts b/e2e/settings.spec.ts index 601e36ed31d..e20fd11db63 100644 --- a/e2e/settings.spec.ts +++ b/e2e/settings.spec.ts @@ -11,14 +11,10 @@ const settingsTestIds = { const settingsObject = { email: 'foo@bar.com', + userNamePlaceholder: '{{username}}', certifiedUsername: 'certifieduser', testEmail: 'test@gmail.com', pageTitle: `${translations.buttons.settings} | freeCodeCamp.org`, - userNamePlaceholder: '{{username}}', - testUser: 'testuser', - errorCode: '404', - invalidUserName: 'user!', - tooShortUserName: 'us', private: 'Private', public: 'Public', supportEmail: 'support@freecodecamp.org', @@ -70,47 +66,6 @@ test.describe('Settings', () => { ); }); - test('Should validate Username Settings', async ({ page }) => { - const inputLabel = page.getByLabel(translations.settings.labels.username); - await expect(inputLabel).toBeVisible(); - await inputLabel.fill(settingsObject.testUser); - await expect( - page.getByText(translations.settings.username.validating) - ).toBeVisible(); - await inputLabel.fill(settingsObject.errorCode); - await expect( - page.getByText( - translations.settings.username['is a reserved error code'].replace( - settingsObject.userNamePlaceholder, - settingsObject.errorCode - ) - ) - ).toBeVisible(); - await inputLabel.fill(settingsObject.invalidUserName); - await expect( - page.getByText( - translations.settings.username['contains invalid characters'].replace( - settingsObject.userNamePlaceholder, - settingsObject.invalidUserName - ) - ) - ).toBeVisible(); - await inputLabel.fill(settingsObject.tooShortUserName); - await expect( - page.getByText( - translations.settings.username['is too short'].replace( - settingsObject.userNamePlaceholder, - settingsObject.tooShortUserName - ) - ) - ).toBeVisible(); - await inputLabel.fill(settingsObject.certifiedUsername); - const saveButton = page.getByRole('button', { - name: translations.settings.labels.username - }); - await expect(saveButton).toBeVisible(); - }); - test('Should validate Privacy Settings', async ({ page }) => { await expect( page.getByRole('heading', { diff --git a/e2e/username-change.spec.ts b/e2e/username-change.spec.ts new file mode 100644 index 00000000000..17b7d4b11be --- /dev/null +++ b/e2e/username-change.spec.ts @@ -0,0 +1,173 @@ +import { test, expect } from '@playwright/test'; +import translations from '../client/i18n/locales/english/translations.json'; +test.use({ storageState: 'playwright/.auth/certified-user.json' }); + +const settingsObject = { + usernamePlaceholder: '{{username}}', + usernameUpdateToLowerCase: 'quincy', + usernameUpdateToUpperCase: 'Mrugesh', + usernameAvailable: 'Sem', + usernameAvailablePressingEnter: 'Oliver', + usernameNotAvailable: 'Twaha', + usernameInvalid: 'user!', + usernameTooShort: 'us', + certifiedUsername: 'certifieduser', + testUser: 'testuser', + errorCode: '404' +}; + +test.describe('Username Settings Validation', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/settings'); + }); + + test('Should display Username Input and Save Button', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + const saveButton = page.getByRole('button', { + name: translations.settings.labels.username + }); + await expect(inputLabel).toBeVisible(); + await expect(saveButton).toBeVisible(); + }); + + test('Should handle Reserved Username Error', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + await inputLabel.fill(settingsObject.errorCode); + await expect( + page.getByText( + translations.settings.username['is a reserved error code'].replace( + settingsObject.usernamePlaceholder, + settingsObject.errorCode + ) + ) + ).toBeVisible(); + }); + + test('Should handle Invalid Username Error', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + await inputLabel.fill(settingsObject.usernameInvalid); + await expect( + page.getByText( + translations.settings.username['contains invalid characters'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameInvalid + ) + ) + ).toBeVisible(); + }); + + test('Should handle Unavailable Username Error', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + await inputLabel.fill(settingsObject.usernameNotAvailable); + await expect( + page.getByText( + translations.settings.username['unavailable'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameNotAvailable + ) + ) + ).toBeVisible(); + }); + + test('Should handle Too Short Username Error', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + await inputLabel.fill(settingsObject.usernameTooShort); + await expect( + page.getByText( + translations.settings.username['is too short'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameTooShort + ) + ) + ).toBeVisible(); + }); + + test('Should save valid Username', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + const saveButton = page.getByRole('button', { + name: translations.settings.labels.username + }); + await inputLabel.fill(settingsObject.usernameAvailable); + await expect(saveButton).not.toBeDisabled(); + await saveButton.click(); + await expect( + page.getByText( + translations.flash['username-updated'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameAvailable + ) + ) + ).toBeVisible(); + }); + + test('should update username in lowercase and reflect in the UI', async ({ + page + }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + const saveButton = page.getByRole('button', { + name: translations.settings.labels.username + }); + await inputLabel.fill(settingsObject.usernameUpdateToLowerCase); + await expect(saveButton).not.toBeDisabled(); + await saveButton.click(); + await expect( + page.getByText( + translations.flash['username-updated'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameUpdateToLowerCase + ) + ) + ).toBeVisible(); + }); + + test('should update username in uppercase and reflect in the UI', async ({ + page + }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + const saveButton = page.getByRole('button', { + name: translations.settings.labels.username + }); + await inputLabel.fill(settingsObject.usernameUpdateToUpperCase); + await expect(saveButton).not.toBeDisabled(); + await saveButton.click(); + await expect( + page.getByText( + translations.flash['username-updated'].replace( + settingsObject.usernamePlaceholder, + settingsObject.usernameUpdateToUpperCase + ) + ) + ).toBeVisible(); + }); + + test('should update username by pressing enter', async ({ page }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + await inputLabel.fill(settingsObject.testUser); + + await expect( + page.getByText(translations.settings.username.available) + ).toBeVisible(); + + await inputLabel.press('Enter'); + + await expect( + page.getByText( + translations.flash['username-updated'].replace( + settingsObject.usernamePlaceholder, + settingsObject.testUser + ) + ) + ).toBeVisible(); + }); + + test('should not be able to update username to the same username', async ({ + page + }) => { + const inputLabel = page.getByLabel(translations.settings.labels.username); + const saveButton = page.getByRole('button', { + name: translations.settings.labels.username + }); + await inputLabel.fill(settingsObject.testUser); + await expect(saveButton).toBeDisabled(); + }); +});