From 1fc5e1c35a5286e3c9c3ae860dd9383d25919017 Mon Sep 17 00:00:00 2001 From: Christian Heel <66922325+heelc29@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:05:13 +0100 Subject: [PATCH 01/16] [5.2] test user registration workflow (#44734) * [5.2] test user registration workflow * cs * fix --- .../components/com_users/Registration.cy.js | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/tests/System/integration/site/components/com_users/Registration.cy.js b/tests/System/integration/site/components/com_users/Registration.cy.js index 5cc44ace40ca2..bb856f52762a7 100644 --- a/tests/System/integration/site/components/com_users/Registration.cy.js +++ b/tests/System/integration/site/components/com_users/Registration.cy.js @@ -1,11 +1,65 @@ describe('Test in frontend that the users registration view', () => { - beforeEach(() => cy.db_updateExtensionParameter('allowUserRegistration', '1', 'com_users')); - afterEach(() => cy.db_updateExtensionParameter('allowUserRegistration', '0', 'com_users')); + beforeEach(() => { + cy.db_updateExtensionParameter('allowUserRegistration', '1', 'com_users'); + cy.task('clearEmails'); + }); + afterEach(() => { + cy.db_updateExtensionParameter('allowUserRegistration', '0', 'com_users'); + cy.task('queryDB', "DELETE FROM #__users WHERE username = 'testuser'"); + }); it('can display a registration form for a test user without a menu item', () => { cy.visit('/index.php?option=com_users&view=registration'); cy.get('.com-users-registration__form').should('contain.text', 'User Registration'); + cy.get('#jform_name').clear().type('test user'); + cy.get('#jform_username').clear().type('testuser'); + cy.get('#jform_password1').clear().type(`${Cypress.env('password')}-test`); + cy.get('#jform_password2').clear().type(`${Cypress.env('password')}-test`); + cy.get('#jform_email1').clear().type('testuser@example.com'); + cy.get('#member-registration').submit(); + cy.checkForSystemMessage('Your account has been created and a verification link has been sent to the email address you entered.'); + + cy.task('getMails').then((mails) => { + cy.wrap(mails).should('have.lengthOf', 1); + cy.wrap(mails[0].headers.subject).should('have.string', `Account Details for test user at ${Cypress.env('sitename')}`); + cy.wrap(mails[0].headers.to).should('equal', 'testuser@example.com'); + cy.wrap(mails[0].body).should('have.string', `Hello test user,\n\nThank you for registering at ${Cypress.env('sitename')}.`); + cy.wrap(mails[0].body).should('match', /http\S+\?task=registration\.activate&token=[a-z0-9]+/); + cy.wrap(/http\S+\?task=registration\.activate&token=[a-z0-9]+/.exec(mails[0].body)[0]).as('activatelink'); + cy.wrap(mails[0].html).should('be.false'); + }); + cy.get('@activatelink').then((url) => cy.visit(url)); + cy.checkForSystemMessage('Your email address has been verified.'); + + cy.task('getMails').then((mails) => { + cy.wrap(mails).should('have.lengthOf', 2); + cy.wrap(mails[1].headers.subject).should('have.string', `Registration approval required for account of test user at ${Cypress.env('sitename')}`); + cy.wrap(mails[1].headers.to).should('equal', Cypress.env('email')); + cy.wrap(mails[1].body).should('have.string', `Hello administrator,\n\nA new user has registered at ${Cypress.env('sitename')}.`); + cy.wrap(mails[1].body).should('have.string', 'Name : test user'); + cy.wrap(mails[1].body).should('have.string', 'email: testuser@example.com'); + cy.wrap(mails[1].body).should('have.string', 'Username: testuser'); + cy.wrap(mails[1].body).should('match', /http\S+\?task=registration\.activate&token=[a-z0-9]+/); + cy.wrap(/http\S+\?task=registration\.activate&token=[a-z0-9]+/.exec(mails[1].body)[0]).as('activatelinkadmin'); + cy.wrap(mails[1].html).should('be.false'); + }); + cy.get('@activatelinkadmin').then((url) => cy.visit(url)); + cy.checkForSystemMessage('Please log in to confirm that you are authorised to activate new accounts.'); + + cy.doFrontendLogin(); + cy.get('@activatelinkadmin').then((url) => cy.visit(url)); + cy.checkForSystemMessage('The user\'s account has been activated and the user has been notified about it.'); + cy.doFrontendLogout(); + cy.task('getMails').then((mails) => { + cy.wrap(mails).should('have.lengthOf', 3); + cy.wrap(mails[2].headers.subject).should('have.string', `Account activated for test user at ${Cypress.env('sitename')}`); + cy.wrap(mails[2].headers.to).should('equal', 'testuser@example.com'); + cy.wrap(mails[2].body).should('have.string', 'Hello test user,\n\nYour account has been activated by an administrator.'); + cy.wrap(mails[2].html).should('be.false'); + }); + cy.doFrontendLogin('testuser', `${Cypress.env('password')}-test`); + cy.doFrontendLogout(); }); it('can display a registration form for a test user in a menu item', () => { From 68be1b3405694f730b59688b4dbb33d93a9a2d59 Mon Sep 17 00:00:00 2001 From: Christian Heel <66922325+heelc29@users.noreply.github.com> Date: Fri, 24 Jan 2025 09:35:57 +0100 Subject: [PATCH 02/16] [5.2] refactor tests to use checkForSystemMessage (#44772) Co-authored-by: Allon Moritz --- .../components/com_actionlogs/Actionlogs.cy.js | 8 ++++---- .../components/com_banners/Banner.cy.js | 2 +- .../components/com_banners/Banners.cy.js | 8 ++++---- .../components/com_banners/Client.cy.js | 2 +- .../components/com_banners/Clients.cy.js | 8 ++++---- .../components/com_cache/Default.cy.js | 4 ++-- .../components/com_categories/Categories.cy.js | 8 ++++---- .../components/com_categories/Category.cy.js | 2 +- .../components/com_checkin/Default.cy.js | 2 +- .../components/com_config/Application.cy.js | 2 +- .../components/com_contact/Contact.cy.js | 2 +- .../components/com_contact/Contacts.cy.js | 12 ++++++------ .../components/com_content/Article.cy.js | 2 +- .../components/com_content/Articles.cy.js | 12 ++++++------ .../components/com_fields/Field.cy.js | 2 +- .../components/com_fields/Fields.cy.js | 8 ++++---- .../components/com_joomlaupdate/Update.cy.js | 4 ++-- .../administrator/components/com_login/Login.cy.js | 6 +++--- .../administrator/components/com_media/Media.cy.js | 4 ++-- .../administrator/components/com_menu/Menu.cy.js | 2 +- .../components/com_menu/MenuItem.cy.js | 2 +- .../components/com_modules/Module.cy.js | 2 +- .../components/com_modules/Modules.cy.js | 8 ++++---- .../components/com_newsfeeds/Newsfeed.cy.js | 2 +- .../components/com_newsfeeds/Newsfeeds.cy.js | 8 ++++---- .../components/com_plugins/Plugins.cy.js | 4 ++-- .../components/com_scheduler/Tasks.cy.js | 14 +++++++------- .../administrator/components/com_tags/Tag.cy.js | 2 +- .../administrator/components/com_tags/Tags.cy.js | 8 ++++---- .../administrator/components/com_users/Group.cy.js | 4 ++-- .../components/com_users/Groups.cy.js | 2 +- .../administrator/components/com_users/Level.cy.js | 4 ++-- .../components/com_users/Levels.cy.js | 2 +- .../administrator/components/com_users/User.cy.js | 6 +++--- .../administrator/components/com_users/Users.cy.js | 2 +- .../site/components/com_users/Logout.cy.js | 4 ++-- .../site/components/com_users/Profile_Edit.cy.js | 4 ++-- .../site/components/com_users/Remind.cy.js | 4 ++-- .../site/components/com_users/Reset.cy.js | 6 +++--- 39 files changed, 94 insertions(+), 94 deletions(-) diff --git a/tests/System/integration/administrator/components/com_actionlogs/Actionlogs.cy.js b/tests/System/integration/administrator/components/com_actionlogs/Actionlogs.cy.js index ae4d7392b26a4..1b36bea17a7c5 100644 --- a/tests/System/integration/administrator/components/com_actionlogs/Actionlogs.cy.js +++ b/tests/System/integration/administrator/components/com_actionlogs/Actionlogs.cy.js @@ -25,19 +25,19 @@ describe('Test in backend that the action logs', () => { it('has an export button', () => { cy.get('#toolbar-download1').click(); - cy.get('#system-message-container').contains('There are no User Action logs to export').should('exist'); + cy.checkForSystemMessage('There are no User Action logs to export'); }); it('can clear logs', () => { cy.get('#toolbar-delete1').click(); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('All User Action logs have been deleted').should('exist'); + cy.checkForSystemMessage('All User Action logs have been deleted'); }); it('can delete selected logs', () => { cy.get('#toolbar-delete').click(); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Please first make a selection from the list').should('exist'); + cy.checkForSystemMessage('Please first make a selection from the list'); cy.log('Make a selection first'); cy.doAdministratorLogout(); cy.doAdministratorLogin(); @@ -45,7 +45,7 @@ describe('Test in backend that the action logs', () => { cy.checkAllResults(); cy.get('#toolbar-delete').click(); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('logs deleted').should('exist'); + cy.checkForSystemMessage('logs deleted'); cy.task('queryDB', 'TRUNCATE #__action_logs'); }); }); diff --git a/tests/System/integration/administrator/components/com_banners/Banner.cy.js b/tests/System/integration/administrator/components/com_banners/Banner.cy.js index 656434df59dd7..e0c6b3ca4a984 100644 --- a/tests/System/integration/administrator/components/com_banners/Banner.cy.js +++ b/tests/System/integration/administrator/components/com_banners/Banner.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the banners form', () => { cy.get('#jform_name').clear().type('Test banner'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Banner saved.').should('exist'); + cy.checkForSystemMessage('Banner saved.'); cy.contains('Test banner'); }); diff --git a/tests/System/integration/administrator/components/com_banners/Banners.cy.js b/tests/System/integration/administrator/components/com_banners/Banners.cy.js index 5c3e6235e40a8..9c9fc81417b43 100644 --- a/tests/System/integration/administrator/components/com_banners/Banners.cy.js +++ b/tests/System/integration/administrator/components/com_banners/Banners.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the banners list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Banner published.').should('exist'); + cy.checkForSystemMessage('Banner published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the banners list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Banner unpublished.').should('exist'); + cy.checkForSystemMessage('Banner unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the banners list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Banner trashed.').should('exist'); + cy.checkForSystemMessage('Banner trashed.'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the banners list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Banner deleted.').should('exist'); + cy.checkForSystemMessage('Banner deleted.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_banners/Client.cy.js b/tests/System/integration/administrator/components/com_banners/Client.cy.js index 84eac4dfae8df..0e48d09a129de 100644 --- a/tests/System/integration/administrator/components/com_banners/Client.cy.js +++ b/tests/System/integration/administrator/components/com_banners/Client.cy.js @@ -12,7 +12,7 @@ describe('Test in backend that the banner clients form', () => { cy.get('#jform_contact').clear().type('test banner client'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Client saved.').should('exist'); + cy.checkForSystemMessage('Client saved.'); cy.contains('test banner client'); }); diff --git a/tests/System/integration/administrator/components/com_banners/Clients.cy.js b/tests/System/integration/administrator/components/com_banners/Clients.cy.js index 7e3fec806f8b7..52d73fb6d5124 100644 --- a/tests/System/integration/administrator/components/com_banners/Clients.cy.js +++ b/tests/System/integration/administrator/components/com_banners/Clients.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the clients list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Client published.').should('exist'); + cy.checkForSystemMessage('Client published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the clients list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Client unpublished.').should('exist'); + cy.checkForSystemMessage('Client unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the clients list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Client trashed.').should('exist'); + cy.checkForSystemMessage('Client trashed.'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the clients list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Client deleted.').should('exist'); + cy.checkForSystemMessage('Client deleted.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_cache/Default.cy.js b/tests/System/integration/administrator/components/com_cache/Default.cy.js index 4e9439461a964..a827ff5efca60 100644 --- a/tests/System/integration/administrator/components/com_cache/Default.cy.js +++ b/tests/System/integration/administrator/components/com_cache/Default.cy.js @@ -23,11 +23,11 @@ describe('Test in backend that the cache', () => { cy.get('div.buttons-holder button[data-button-ok]').click(); } }); - cy.get('#system-message-container').contains('Expired cached items have been cleared').should('exist'); + cy.checkForSystemMessage('Expired cached items have been cleared'); }); it('can delete all', () => { cy.get('#toolbar-delete1').click(); - cy.get('#system-message-container').contains('All cache group(s) have been cleared').should('exist'); + cy.checkForSystemMessage('All cache group(s) have been cleared'); }); }); diff --git a/tests/System/integration/administrator/components/com_categories/Categories.cy.js b/tests/System/integration/administrator/components/com_categories/Categories.cy.js index 4abebb573edab..8a6d1bd484b44 100644 --- a/tests/System/integration/administrator/components/com_categories/Categories.cy.js +++ b/tests/System/integration/administrator/components/com_categories/Categories.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the categories list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Category published.').should('exist'); + cy.checkForSystemMessage('Category published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the categories list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Category unpublished.').should('exist'); + cy.checkForSystemMessage('Category unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the categories list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Category trashed.').should('exist'); + cy.checkForSystemMessage('Category trashed.'); }); }); @@ -70,6 +70,6 @@ describe('Test in backend that the categories list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Category deleted.').should('exist'); + cy.checkForSystemMessage('Category deleted.'); }); }); diff --git a/tests/System/integration/administrator/components/com_categories/Category.cy.js b/tests/System/integration/administrator/components/com_categories/Category.cy.js index cc542daa671ff..84a4daadb1a83 100644 --- a/tests/System/integration/administrator/components/com_categories/Category.cy.js +++ b/tests/System/integration/administrator/components/com_categories/Category.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the category form', () => { cy.get('#jform_title').should('exist').type('Test category'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Category saved.').should('exist'); + cy.checkForSystemMessage('Category saved.'); cy.contains('Test category'); }); diff --git a/tests/System/integration/administrator/components/com_checkin/Default.cy.js b/tests/System/integration/administrator/components/com_checkin/Default.cy.js index 406426772a328..810e6030002dc 100644 --- a/tests/System/integration/administrator/components/com_checkin/Default.cy.js +++ b/tests/System/integration/administrator/components/com_checkin/Default.cy.js @@ -25,7 +25,7 @@ describe('Test in backend that the checkin', () => { cy.searchForItem('content'); cy.checkAllResults(); cy.get('#toolbar-checkin').click(); - cy.get('#system-message-container').contains('Item checked in').should('exist'); + cy.checkForSystemMessage('Item checked in'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_config/Application.cy.js b/tests/System/integration/administrator/components/com_config/Application.cy.js index 4a9be2772a950..c38a55aaf76ac 100644 --- a/tests/System/integration/administrator/components/com_config/Application.cy.js +++ b/tests/System/integration/administrator/components/com_config/Application.cy.js @@ -22,7 +22,7 @@ describe('Test in backend that the application configuration', () => { cy.get('#sendtestmail').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'The email was sent to'); + cy.checkForSystemMessage('The email was sent to'); expect(mails.length).to.equal(1); cy.wrap(mails[0].body).should('have.string', 'This is a test mail sent using'); diff --git a/tests/System/integration/administrator/components/com_contact/Contact.cy.js b/tests/System/integration/administrator/components/com_contact/Contact.cy.js index 7b3332570550c..ae4e6f033e66c 100644 --- a/tests/System/integration/administrator/components/com_contact/Contact.cy.js +++ b/tests/System/integration/administrator/components/com_contact/Contact.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the contact form', () => { cy.get('#jform_name').clear().type('Test contact'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Contact saved.').should('exist'); + cy.checkForSystemMessage('Contact saved.'); cy.contains('Test contact'); }); diff --git a/tests/System/integration/administrator/components/com_contact/Contacts.cy.js b/tests/System/integration/administrator/components/com_contact/Contacts.cy.js index 6025b8008fc25..8fb985e427624 100644 --- a/tests/System/integration/administrator/components/com_contact/Contacts.cy.js +++ b/tests/System/integration/administrator/components/com_contact/Contacts.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Contact published.').should('exist'); + cy.checkForSystemMessage('Contact published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Contact unpublished.').should('exist'); + cy.checkForSystemMessage('Contact unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('Action'); cy.contains('.button-featured', 'Feature').click(); - cy.get('#system-message-container').contains('Contact featured.').should('exist'); + cy.checkForSystemMessage('Contact featured.'); }); }); @@ -66,7 +66,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('Action'); cy.contains('Unfeature').click(); - cy.get('#system-message-container').contains('Contact unfeatured.').should('exist'); + cy.checkForSystemMessage('Contact unfeatured.'); }); }); @@ -78,7 +78,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Contact trashed.').should('exist'); + cy.checkForSystemMessage('Contact trashed.'); }); }); @@ -91,7 +91,7 @@ describe('Test in backend that the contacts list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Contact deleted.').should('exist'); + cy.checkForSystemMessage('Contact deleted.'); }); }); diff --git a/tests/System/integration/administrator/components/com_content/Article.cy.js b/tests/System/integration/administrator/components/com_content/Article.cy.js index a5b2e69e73703..d0c30fc62ff06 100644 --- a/tests/System/integration/administrator/components/com_content/Article.cy.js +++ b/tests/System/integration/administrator/components/com_content/Article.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the article form', () => { cy.get('#jform_title').clear().type('Test article'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Article saved.').should('exist'); + cy.checkForSystemMessage('Article saved.'); cy.contains('Test article'); }); diff --git a/tests/System/integration/administrator/components/com_content/Articles.cy.js b/tests/System/integration/administrator/components/com_content/Articles.cy.js index 84b97ed828167..a03adefbcd5aa 100644 --- a/tests/System/integration/administrator/components/com_content/Articles.cy.js +++ b/tests/System/integration/administrator/components/com_content/Articles.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Article published.').should('exist'); + cy.checkForSystemMessage('Article published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Article unpublished.').should('exist'); + cy.checkForSystemMessage('Article unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('Action'); cy.contains('.button-featured', 'Feature').click(); - cy.get('#system-message-container').contains('Article featured.').should('exist'); + cy.checkForSystemMessage('Article featured.'); }); }); @@ -66,7 +66,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('Action'); cy.contains('Unfeature').click(); - cy.get('#system-message-container').contains('Article unfeatured.').should('exist'); + cy.checkForSystemMessage('Article unfeatured.'); }); }); @@ -78,7 +78,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Article trashed.').should('exist'); + cy.checkForSystemMessage('Article trashed.'); }); }); @@ -91,7 +91,7 @@ describe('Test in backend that the articles list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Article deleted.').should('exist'); + cy.checkForSystemMessage('Article deleted.'); }); }); diff --git a/tests/System/integration/administrator/components/com_fields/Field.cy.js b/tests/System/integration/administrator/components/com_fields/Field.cy.js index 3b7514e58e11d..43f9ae1d632da 100644 --- a/tests/System/integration/administrator/components/com_fields/Field.cy.js +++ b/tests/System/integration/administrator/components/com_fields/Field.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the field form', () => { cy.get('#jform_title').clear().type('Test field'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Field saved').should('exist'); + cy.checkForSystemMessage('Field saved'); cy.contains('Test field'); }); diff --git a/tests/System/integration/administrator/components/com_fields/Fields.cy.js b/tests/System/integration/administrator/components/com_fields/Fields.cy.js index fea32673c9697..a6ad229e85700 100644 --- a/tests/System/integration/administrator/components/com_fields/Fields.cy.js +++ b/tests/System/integration/administrator/components/com_fields/Fields.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the custom fields list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Field published').should('exist'); + cy.checkForSystemMessage('Field published'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the custom fields list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Field unpublished').should('exist'); + cy.checkForSystemMessage('Field unpublished'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the custom fields list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Field trashed').should('exist'); + cy.checkForSystemMessage('Field trashed'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the custom fields list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Field deleted').should('exist'); + cy.checkForSystemMessage('Field deleted'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_joomlaupdate/Update.cy.js b/tests/System/integration/administrator/components/com_joomlaupdate/Update.cy.js index bc81d06389e6e..3312be290231d 100644 --- a/tests/System/integration/administrator/components/com_joomlaupdate/Update.cy.js +++ b/tests/System/integration/administrator/components/com_joomlaupdate/Update.cy.js @@ -14,7 +14,7 @@ describe('Test the update retrieval logic', () => { cy.get('#toolbar joomla-toolbar-button[task="update.purge"] button').click(); - cy.get('#system-message-container').contains('Checked for updates.').should('exist'); + cy.checkForSystemMessage('Checked for updates.'); }); it('Receives error fetching available updates with invalid metadata', () => { @@ -24,6 +24,6 @@ describe('Test the update retrieval logic', () => { cy.get('#confirmButton').click(); - cy.get('#system-message-container').contains('Update not possible because the offered update does not have enough signatures.').should('exist'); + cy.checkForSystemMessage('Update not possible because the offered update does not have enough signatures.'); }); }); diff --git a/tests/System/integration/administrator/components/com_login/Login.cy.js b/tests/System/integration/administrator/components/com_login/Login.cy.js index f7f999f54b09e..824ab5aae209b 100644 --- a/tests/System/integration/administrator/components/com_login/Login.cy.js +++ b/tests/System/integration/administrator/components/com_login/Login.cy.js @@ -24,7 +24,7 @@ describe('Test in backend that the login component', () => { cy.get('#mod-login-password').type(Cypress.env('password')); cy.get('#btn-login-submit').click(); - cy.get('#system-message-container').contains('Username and password do not match or you do not have an account yet.').should('exist'); + cy.checkForSystemMessage('Username and password do not match or you do not have an account yet.'); }); it('can not log in with wrong password', () => { @@ -33,7 +33,7 @@ describe('Test in backend that the login component', () => { cy.get('#mod-login-password').type('invalid'); cy.get('#btn-login-submit').click(); - cy.get('#system-message-container').contains('Username and password do not match or you do not have an account yet.').should('exist'); + cy.checkForSystemMessage('Username and password do not match or you do not have an account yet.'); }); it('can not log in with non-existing user', () => { @@ -42,6 +42,6 @@ describe('Test in backend that the login component', () => { cy.get('#mod-login-password').type('invalid'); cy.get('#btn-login-submit').click(); - cy.get('#system-message-container').contains('Username and password do not match or you do not have an account yet.').should('exist'); + cy.checkForSystemMessage('Username and password do not match or you do not have an account yet.'); }); }); diff --git a/tests/System/integration/administrator/components/com_media/Media.cy.js b/tests/System/integration/administrator/components/com_media/Media.cy.js index 3ddf849f9c4e7..dcdd714c060fd 100644 --- a/tests/System/integration/administrator/components/com_media/Media.cy.js +++ b/tests/System/integration/administrator/components/com_media/Media.cy.js @@ -77,7 +77,7 @@ describe('Test in backend that the media manager', () => { cy.visit('/administrator/index.php?option=com_media&path=local-images:/invalid'); cy.wait('@getMedia'); - cy.get('#system-message-container').should('contain.text', 'File or Folder not found'); + cy.checkForSystemMessage('File or Folder not found'); }); it('can display an error message when an invalid path is defined in the session', () => { @@ -85,6 +85,6 @@ describe('Test in backend that the media manager', () => { cy.visit('/administrator/index.php?option=com_media'); cy.wait('@getMedia'); - cy.get('#system-message-container').should('contain.text', 'File or Folder not found'); + cy.checkForSystemMessage('File or Folder not found'); }); }); diff --git a/tests/System/integration/administrator/components/com_menu/Menu.cy.js b/tests/System/integration/administrator/components/com_menu/Menu.cy.js index a1d0055097f75..f775ca49edd43 100644 --- a/tests/System/integration/administrator/components/com_menu/Menu.cy.js +++ b/tests/System/integration/administrator/components/com_menu/Menu.cy.js @@ -10,7 +10,7 @@ describe('Test in backend that the user form', () => { cy.get('#jform_menudescription').clear().type('test description'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Menu saved').should('exist'); + cy.checkForSystemMessage('Menu saved'); cy.contains('test menu'); }); }); diff --git a/tests/System/integration/administrator/components/com_menu/MenuItem.cy.js b/tests/System/integration/administrator/components/com_menu/MenuItem.cy.js index f448e1375f613..c8ff8e666db21 100644 --- a/tests/System/integration/administrator/components/com_menu/MenuItem.cy.js +++ b/tests/System/integration/administrator/components/com_menu/MenuItem.cy.js @@ -27,7 +27,7 @@ describe('Test in backend that the menu list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Menu item trashed.').should('exist'); + cy.checkForSystemMessage('Menu item trashed.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_modules/Module.cy.js b/tests/System/integration/administrator/components/com_modules/Module.cy.js index 761d79fa9aea5..03849db2cab20 100644 --- a/tests/System/integration/administrator/components/com_modules/Module.cy.js +++ b/tests/System/integration/administrator/components/com_modules/Module.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the module form', () => { cy.get('#jform_title').clear().type('Test module'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Module saved').should('exist'); + cy.checkForSystemMessage('Module saved'); cy.contains('Test module'); }); diff --git a/tests/System/integration/administrator/components/com_modules/Modules.cy.js b/tests/System/integration/administrator/components/com_modules/Modules.cy.js index 5497fe6152c7b..3c258d6adea0a 100644 --- a/tests/System/integration/administrator/components/com_modules/Modules.cy.js +++ b/tests/System/integration/administrator/components/com_modules/Modules.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the module list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Module published').should('exist'); + cy.checkForSystemMessage('Module published'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the module list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Module unpublished').should('exist'); + cy.checkForSystemMessage('Module unpublished'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the module list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Module trashed').should('exist'); + cy.checkForSystemMessage('Module trashed'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the module list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Module deleted').should('exist'); + cy.checkForSystemMessage('Module deleted'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_newsfeeds/Newsfeed.cy.js b/tests/System/integration/administrator/components/com_newsfeeds/Newsfeed.cy.js index d3eac81b022ec..e0c611a780626 100644 --- a/tests/System/integration/administrator/components/com_newsfeeds/Newsfeed.cy.js +++ b/tests/System/integration/administrator/components/com_newsfeeds/Newsfeed.cy.js @@ -8,7 +8,7 @@ describe('Test in backend that the newsfeed form', () => { cy.get('#jform_link').clear().type('https://newsfeedtesturl'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('News feed saved.').should('exist'); + cy.checkForSystemMessage('News feed saved.'); cy.contains('Test newsfeed'); }); diff --git a/tests/System/integration/administrator/components/com_newsfeeds/Newsfeeds.cy.js b/tests/System/integration/administrator/components/com_newsfeeds/Newsfeeds.cy.js index 02382578001b1..a9cb2e006a4c7 100644 --- a/tests/System/integration/administrator/components/com_newsfeeds/Newsfeeds.cy.js +++ b/tests/System/integration/administrator/components/com_newsfeeds/Newsfeeds.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the newsfeeds list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('News feed published.').should('exist'); + cy.checkForSystemMessage('News feed published.'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the newsfeeds list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('News feed unpublished.').should('exist'); + cy.checkForSystemMessage('News feed unpublished.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the newsfeeds list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('News feed trashed.').should('exist'); + cy.checkForSystemMessage('News feed trashed.'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the newsfeeds list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('News feed deleted.').should('exist'); + cy.checkForSystemMessage('News feed deleted.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_plugins/Plugins.cy.js b/tests/System/integration/administrator/components/com_plugins/Plugins.cy.js index 6e0980ff321da..bc27778110384 100644 --- a/tests/System/integration/administrator/components/com_plugins/Plugins.cy.js +++ b/tests/System/integration/administrator/components/com_plugins/Plugins.cy.js @@ -17,7 +17,7 @@ describe('Test in backend that the plugins list', () => { cy.checkAllResults(); cy.contains('Disable').click(); cy.on('window:confirm', () => true); - cy.get('#system-message-container').contains('Plugin disabled.').should('exist'); + cy.checkForSystemMessage('Plugin disabled.'); }); it('can publish a plugin', () => { @@ -25,7 +25,7 @@ describe('Test in backend that the plugins list', () => { cy.checkAllResults(); cy.contains('Enable').click(); cy.on('window:confirm', () => true); - cy.get('#system-message-container').contains('Plugin enabled.').should('exist'); + cy.checkForSystemMessage('Plugin enabled.'); }); it('can edit a plugin', () => { diff --git a/tests/System/integration/administrator/components/com_scheduler/Tasks.cy.js b/tests/System/integration/administrator/components/com_scheduler/Tasks.cy.js index 4588e6e33947f..531391e2e0e24 100644 --- a/tests/System/integration/administrator/components/com_scheduler/Tasks.cy.js +++ b/tests/System/integration/administrator/components/com_scheduler/Tasks.cy.js @@ -27,7 +27,7 @@ describe('Test in backend that the tasks list', () => { cy.get('#jform_params_url').clear().type('www.test.task'); cy.get('#jform_execution_rules_interval_minutes').clear().type('1'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Item saved').should('exist'); + cy.checkForSystemMessage('Item saved'); }); it('can unpublish the test task', () => { @@ -38,7 +38,7 @@ describe('Test in backend that the tasks list', () => { cy.get('#jform_params_url').clear().type('www.test.task'); cy.get('#jform_execution_rules_interval_minutes').clear().type('1'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Item saved').should('exist'); + cy.checkForSystemMessage('Item saved'); cy.reload(); cy.searchForItem('Test task'); @@ -47,7 +47,7 @@ describe('Test in backend that the tasks list', () => { cy.contains('Disable').click(); cy.on('window:confirm', () => true); - cy.get('#system-message-container').contains('Task disabled').should('exist'); + cy.checkForSystemMessage('Task disabled'); }); it('can trash the test task', () => { @@ -60,7 +60,7 @@ describe('Test in backend that the tasks list', () => { cy.get('#jform_state').select('Disabled'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Item saved').should('exist'); + cy.checkForSystemMessage('Item saved'); cy.reload(); cy.searchForItem('Test task'); @@ -69,7 +69,7 @@ describe('Test in backend that the tasks list', () => { cy.contains('Trash').click(); cy.on('window:confirm', () => true); - cy.get('#system-message-container').contains('Task trashed').should('exist'); + cy.checkForSystemMessage('Task trashed'); }); it('can delete the test task', () => { @@ -82,7 +82,7 @@ describe('Test in backend that the tasks list', () => { cy.get('#jform_state').select('Trashed'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Item saved').should('exist'); + cy.checkForSystemMessage('Item saved'); cy.reload(); @@ -92,6 +92,6 @@ describe('Test in backend that the tasks list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Task deleted').should('exist'); + cy.checkForSystemMessage('Task deleted'); }); }); diff --git a/tests/System/integration/administrator/components/com_tags/Tag.cy.js b/tests/System/integration/administrator/components/com_tags/Tag.cy.js index c9dc6fbf07121..a936520b069f0 100644 --- a/tests/System/integration/administrator/components/com_tags/Tag.cy.js +++ b/tests/System/integration/administrator/components/com_tags/Tag.cy.js @@ -11,7 +11,7 @@ describe('Test in backend that the tag form', () => { cy.get('#jform_title').clear().type('Test tag'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Tag saved').should('exist'); + cy.checkForSystemMessage('Tag saved'); cy.contains('Test tag'); }); diff --git a/tests/System/integration/administrator/components/com_tags/Tags.cy.js b/tests/System/integration/administrator/components/com_tags/Tags.cy.js index acd4bad9529cb..f021402acac8c 100644 --- a/tests/System/integration/administrator/components/com_tags/Tags.cy.js +++ b/tests/System/integration/administrator/components/com_tags/Tags.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the custom tags list', () => { cy.clickToolbarButton('Action'); cy.contains('Publish').click(); - cy.get('#system-message-container').contains('Tag published').should('exist'); + cy.checkForSystemMessage('Tag published'); }); }); @@ -42,7 +42,7 @@ describe('Test in backend that the custom tags list', () => { cy.clickToolbarButton('Action'); cy.contains('Unpublish').click(); - cy.get('#system-message-container').contains('Tag unpublished').should('exist'); + cy.checkForSystemMessage('Tag unpublished'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the custom tags list', () => { cy.clickToolbarButton('Action'); cy.contains('Trash').click(); - cy.get('#system-message-container').contains('Tag trashed').should('exist'); + cy.checkForSystemMessage('Tag trashed'); }); }); @@ -67,7 +67,7 @@ describe('Test in backend that the custom tags list', () => { cy.clickToolbarButton('empty trash'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('Tag deleted').should('exist'); + cy.checkForSystemMessage('Tag deleted'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_users/Group.cy.js b/tests/System/integration/administrator/components/com_users/Group.cy.js index 94b891ad22b1b..c161c0f2ad6e4 100644 --- a/tests/System/integration/administrator/components/com_users/Group.cy.js +++ b/tests/System/integration/administrator/components/com_users/Group.cy.js @@ -8,7 +8,7 @@ describe('Test in backend that the user group form', () => { cy.get('#jform_title').clear().type('test group'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Group saved.').should('exist'); + cy.checkForSystemMessage('Group saved.'); cy.contains('test group'); }); @@ -19,7 +19,7 @@ describe('Test in backend that the user group form', () => { cy.get('#jform_title').clear().type('test group edited'); cy.clickToolbarButton('Save'); - cy.get('#system-message-container').contains('Group saved.').should('exist'); + cy.checkForSystemMessage('Group saved.'); }); }); diff --git a/tests/System/integration/administrator/components/com_users/Groups.cy.js b/tests/System/integration/administrator/components/com_users/Groups.cy.js index 1903fe9c68db2..1ac489ca8a7f8 100644 --- a/tests/System/integration/administrator/components/com_users/Groups.cy.js +++ b/tests/System/integration/administrator/components/com_users/Groups.cy.js @@ -29,7 +29,7 @@ describe('Test in backend that the user group list', () => { cy.clickToolbarButton('Delete'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('User Group deleted.').should('exist'); + cy.checkForSystemMessage('User Group deleted.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_users/Level.cy.js b/tests/System/integration/administrator/components/com_users/Level.cy.js index 2b781a726d8b8..ae8334999f195 100644 --- a/tests/System/integration/administrator/components/com_users/Level.cy.js +++ b/tests/System/integration/administrator/components/com_users/Level.cy.js @@ -8,7 +8,7 @@ describe('Test in backend that the user access level form', () => { cy.get('#jform_title').clear().type('test level'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('Access level saved.').should('exist'); + cy.checkForSystemMessage('Access level saved.'); cy.contains('test level'); }); @@ -19,7 +19,7 @@ describe('Test in backend that the user access level form', () => { cy.get('#jform_title').clear().type('test level edited'); cy.clickToolbarButton('Save'); - cy.get('#system-message-container').contains('Access level saved.').should('exist'); + cy.checkForSystemMessage('Access level saved.'); }); }); diff --git a/tests/System/integration/administrator/components/com_users/Levels.cy.js b/tests/System/integration/administrator/components/com_users/Levels.cy.js index dae7787337fde..fda381242df76 100644 --- a/tests/System/integration/administrator/components/com_users/Levels.cy.js +++ b/tests/System/integration/administrator/components/com_users/Levels.cy.js @@ -29,7 +29,7 @@ describe('Test in backend that the user access level list', () => { cy.clickToolbarButton('Delete'); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('View Access Level removed.').should('exist'); + cy.checkForSystemMessage('View Access Level removed.'); }); }); }); diff --git a/tests/System/integration/administrator/components/com_users/User.cy.js b/tests/System/integration/administrator/components/com_users/User.cy.js index 824dd1eb47893..ef24e41b701d0 100644 --- a/tests/System/integration/administrator/components/com_users/User.cy.js +++ b/tests/System/integration/administrator/components/com_users/User.cy.js @@ -12,7 +12,7 @@ describe('Test in backend that the user form', () => { cy.get('#jform_password2').clear().type('testtesttest'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('User saved').should('exist'); + cy.checkForSystemMessage('User saved'); cy.contains('test user'); }); @@ -27,7 +27,7 @@ describe('Test in backend that the user form', () => { cy.get('#jform_email').clear().type('testedited@example.com'); cy.clickToolbarButton('Save'); - cy.get('#system-message-container').contains('User saved.').should('exist'); + cy.checkForSystemMessage('User saved.'); }); }); @@ -54,7 +54,7 @@ describe('Test in backend that the user form', () => { cy.get('#jform_password').clear().type('testresetpswd'); cy.get('#jform_password2').clear().type('testresetpswd'); cy.clickToolbarButton('Save & Close'); - cy.get('#system-message-container').contains('User saved.').should('exist'); + cy.checkForSystemMessage('User saved.'); cy.doAdministratorLogout(); // Check that the user can login with the new password diff --git a/tests/System/integration/administrator/components/com_users/Users.cy.js b/tests/System/integration/administrator/components/com_users/Users.cy.js index 89eb4853e9caa..4090865a4b31b 100644 --- a/tests/System/integration/administrator/components/com_users/Users.cy.js +++ b/tests/System/integration/administrator/components/com_users/Users.cy.js @@ -30,7 +30,7 @@ describe('Test in backend that the user list', () => { cy.contains('Delete').click(); cy.clickDialogConfirm(true); - cy.get('#system-message-container').contains('User deleted.').should('exist'); + cy.checkForSystemMessage('User deleted.'); }); }); diff --git a/tests/System/integration/site/components/com_users/Logout.cy.js b/tests/System/integration/site/components/com_users/Logout.cy.js index 0798a83dec41f..80221ff1fa908 100644 --- a/tests/System/integration/site/components/com_users/Logout.cy.js +++ b/tests/System/integration/site/components/com_users/Logout.cy.js @@ -6,7 +6,7 @@ describe('Test in frontend that the users logout view', () => { cy.contains(`Hi ${Cypress.env('name')}`).should('not.exist'); // This is disabled for now as it looks like cypress has an issue after redirect with the session - // cy.get('#system-message-container').should('contain.text', 'You have been logged out.'); + // cy.checkForSystemMessage('You have been logged out.'); }); it('can log out the user in a menu item', () => { @@ -18,7 +18,7 @@ describe('Test in frontend that the users logout view', () => { cy.get('a:contains(Automated logout)').click(); cy.contains(`Hi ${Cypress.env('name')}`).should('not.exist'); - cy.get('#system-message-container').should('contain.text', 'You have been logged out.'); + cy.checkForSystemMessage('You have been logged out.'); }); }); }); diff --git a/tests/System/integration/site/components/com_users/Profile_Edit.cy.js b/tests/System/integration/site/components/com_users/Profile_Edit.cy.js index 83ff1f134ab0d..8c9834ec94230 100644 --- a/tests/System/integration/site/components/com_users/Profile_Edit.cy.js +++ b/tests/System/integration/site/components/com_users/Profile_Edit.cy.js @@ -29,7 +29,7 @@ describe('Test in frontend that the users profile view edit layout', () => { cy.get('#jform_email1').clear().type('testedited@example.com'); cy.get('.controls > .btn-primary').click({ force: true }); - cy.get('#system-message-container').contains('Profile saved.'); + cy.checkForSystemMessage('Profile saved.'); cy.get('#users-profile-core').should('contain.text', 'Name'); cy.get('#users-profile-core').should('contain.text', 'automated test user edited'); }); @@ -49,7 +49,7 @@ describe('Test in frontend that the users profile view edit layout', () => { cy.get('#jform_email1').clear().type('testedited@example.com'); cy.get('.controls > .btn-primary').should('be.visible').click({ force: true }); - cy.get('#system-message-container').contains('Profile saved.'); + cy.checkForSystemMessage('Profile saved.'); cy.get('.profile .btn-primary').should('be.visible').click({ force: true }); cy.get('#jform_name').should('have.value', 'automated test user edited'); cy.get('#jform_email1').should('have.value', 'testedited@example.com'); diff --git a/tests/System/integration/site/components/com_users/Remind.cy.js b/tests/System/integration/site/components/com_users/Remind.cy.js index 362ffac376cfa..1d73bb3c6ab4a 100644 --- a/tests/System/integration/site/components/com_users/Remind.cy.js +++ b/tests/System/integration/site/components/com_users/Remind.cy.js @@ -9,7 +9,7 @@ describe('Test in frontend that the users remind view', () => { cy.get('.controls > .btn').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.'); + cy.checkForSystemMessage('If the email address you entered is registered on this site you will shortly receive an email with a reminder.'); expect(mails.length).to.equal(1); cy.wrap(mails[0].body).should('have.string', 'A username reminder has been requested'); @@ -26,7 +26,7 @@ describe('Test in frontend that the users remind view', () => { cy.get('.controls > .btn').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.'); + cy.checkForSystemMessage('If the email address you entered is registered on this site you will shortly receive an email with a reminder.'); expect(mails.length).to.equal(0); }); diff --git a/tests/System/integration/site/components/com_users/Reset.cy.js b/tests/System/integration/site/components/com_users/Reset.cy.js index df93ce7e5f952..1bf4610f07ac2 100644 --- a/tests/System/integration/site/components/com_users/Reset.cy.js +++ b/tests/System/integration/site/components/com_users/Reset.cy.js @@ -9,7 +9,7 @@ describe('Test in frontend that the users reset view', () => { cy.get('.controls > .btn').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); + cy.checkForSystemMessage('If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); expect(mails.length).to.equal(1); cy.wrap(mails[0].body).should('have.string', 'To reset your password, you will need to submit this verification code'); @@ -32,7 +32,7 @@ describe('Test in frontend that the users reset view', () => { cy.get('.controls > .btn').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); + cy.checkForSystemMessage('If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); expect(mails.length).to.equal(1); cy.wrap(mails[0].body).should('have.string', 'To reset your password, you will need to submit this verification code'); @@ -49,7 +49,7 @@ describe('Test in frontend that the users reset view', () => { cy.get('.controls > .btn').click(); cy.task('getMails').then((mails) => { - cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); + cy.checkForSystemMessage('If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.'); expect(mails.length).to.equal(0); }); From c55abeef427a4555dd72830dd43852f680d8426a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20L=C3=BCbbe?= Date: Sat, 25 Jan 2025 09:37:10 +0100 Subject: [PATCH 03/16] [Cypress] Refactoring SEF Test to Avoid Using the Joomla Command-Line Client Tool (#44656) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Cypress] Remove Joomla command line dependency With the `SefPlugin.cy.js` test specification, the Joomla command line client tool was added to the Joomla system tests for the first time. This is an additional complexity and dependency. Especially if the test environment is containerised and Cypress container has no PHP installed. And PHP version needs to be 8.1 and additional modules like `php-simplexml` are needed. And with the Docker access rights, `configuration.php` must be opened for writing (`chmod 644`). And then there is the locally running Cypress GUI to be configured... Therefore switched from using the Joomla command line client tool to using the existing `config_setParameter` Cypress command. The original creator of [44253](https://github.com/joomla/joomla-cms/pull/44253) could not know as it is not documented (will be solved with another PR and together with enabling `mod_rewrite` and the `AllowOverride All` needed configuration). Since sometimes the first SEF test failed when the entire Joomla System Tests was performed, the following was implemented: * The operations of the `writeRelativeFile` Cypress task are wrapped in a Promise to ensure that they are only resolved when everything is done * The `config_setParameter` Cypress custom command to return a Cypress chainable * Chaining has been implemented everywhere in `SefPlugin.cy.js` For this test spec the Cypress best practice to use `beforeEach` to ensure tests is added to run independently from one another (and needed for other places in the Joomla System Tests – one more PR). As a small side effect the SEF test spec with 9 tests runs faster, e.g. 3 instead of 18 seconds before. Tested with own target Joomla 5.2-dev three times the single test spec on: * Intel macOS 15.2 using Apache/MariaDB * Apple Silicon macOS 15.2 using Apache/MariaDB * Windows 11 24H2 using Laragon/Apache/MySQL ``` npx cypress run --spec tests/System/integration/plugins/system/sef/SefPlugin.cy.js ``` And once the overall test suite: ``` npm run cypress:run ``` * writeRelativeFile() header adapted return Promise Thank @heekc29 for the hint * Delete cy.log in custom command --------- Co-authored-by: Allon Moritz --- .../plugins/system/sef/SefPlugin.cy.js | 184 ++++++++++-------- tests/System/plugins/fs.mjs | 43 ++-- tests/System/support/commands/config.mjs | 5 +- 3 files changed, 133 insertions(+), 99 deletions(-) diff --git a/tests/System/integration/plugins/system/sef/SefPlugin.cy.js b/tests/System/integration/plugins/system/sef/SefPlugin.cy.js index 35b27448284b0..b4a81da32df4e 100644 --- a/tests/System/integration/plugins/system/sef/SefPlugin.cy.js +++ b/tests/System/integration/plugins/system/sef/SefPlugin.cy.js @@ -1,77 +1,99 @@ describe('Test that the sef system plugin', () => { - afterEach(() => { - cy.task('deleteRelativePath', '.htaccess'); - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef=true sef_suffix=false sef_rewrite=false`); - cy.db_updateExtensionParameter('enforcesuffix', '1', 'plg_system_sef'); - cy.db_updateExtensionParameter('indexphp', '1', 'plg_system_sef'); - cy.db_updateExtensionParameter('trailingslash', '0', 'plg_system_sef'); - cy.db_updateExtensionParameter('strictrouting', '1', 'plg_system_sef'); - }); + const setSefDefaults = () => cy.task('deleteRelativePath', '.htaccess') + .then(() => cy.config_setParameter('sef', true)) + .then(() => cy.config_setParameter('sef_suffix', false)) + .then(() => cy.config_setParameter('sef_rewrite', false)) + .then(() => cy.db_updateExtensionParameter('enforcesuffix', '1', 'plg_system_sef')) + .then(() => cy.db_updateExtensionParameter('indexphp', '1', 'plg_system_sef')) + .then(() => cy.db_updateExtensionParameter('trailingslash', '0', 'plg_system_sef')) + .then(() => cy.db_updateExtensionParameter('strictrouting', '1', 'plg_system_sef')); + + // Ensure that we always start with a clean SEF default state + beforeEach(() => setSefDefaults()); + + // Return to the clean SEF default state for subsequent Joomla System Tests + afterEach(() => setSefDefaults()); it('can process if option \'sef\' disabled', () => { - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef=false`); - cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); - cy.request({ url: '/index.php/component/users/login', failOnStatusCode: false, followRedirect: false }).then((response) => { - expect(response.status).to.eq(404); - }); + cy.config_setParameter('sef', false) + .then(() => { + cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(200); + }); + cy.request({ url: '/index.php/component/users/login', failOnStatusCode: false, followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(404); + }); + }); }); it('can process if option \'enforcesuffix\' enabled', () => { - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef_suffix=true`); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(301); - expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login\.html$/); - }); - cy.request({ url: '/index.php/component/users/login.html', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.config_setParameter('sef_suffix', true) + .then(() => { + cy.request({ url: '/index.php/component/users/login', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(301); + expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login\.html$/); + }); + cy.request({ url: '/index.php/component/users/login.html', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(200); + }); + }); }); it('can process if option \'enforcesuffix\' disabled', () => { - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef_suffix=true`); - cy.db_updateExtensionParameter('enforcesuffix', '0', 'plg_system_sef'); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); - cy.request({ url: '/index.php/component/users/login.html', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.config_setParameter('sef_suffix', true) + .then(() => cy.db_updateExtensionParameter('enforcesuffix', '0', 'plg_system_sef')) + .then(() => cy.request({ url: '/index.php/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }) + .then(() => cy.request({ url: '/index.php/component/users/login.html', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }); }); it('can process if option \'indexphp\' enabled', () => { - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef_rewrite=true`); - cy.task('copyRelativeFile', { source: 'htaccess.txt', destination: '.htaccess' }); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(301); - expect(response.redirectedToUrl).to.match(/(? { - expect(response.status).to.eq(200); - }); + cy.config_setParameter('sef_rewrite', true) + .then(() => cy.task('copyRelativeFile', { source: 'htaccess.txt', destination: '.htaccess' })) + .then(() => cy.request({ url: '/index.php/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(301); + expect(response.redirectedToUrl).to.match(/(? cy.request({ url: '/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }); }); it('can process if option \'indexphp\' disabled', () => { - cy.exec(`php ${Cypress.env('cmsPath')}/cli/joomla.php config:set sef_rewrite=true`); - cy.task('copyRelativeFile', { source: 'htaccess.txt', destination: '.htaccess' }); - cy.db_updateExtensionParameter('indexphp', '0', 'plg_system_sef'); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); - cy.request({ url: '/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.config_setParameter('sef_rewrite', true) + .then(() => cy.task('copyRelativeFile', { source: 'htaccess.txt', destination: '.htaccess' })) + .then(() => cy.db_updateExtensionParameter('indexphp', '0', 'plg_system_sef')) + .then(() => cy.request({ url: '/index.php/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }) + .then(() => cy.request({ url: '/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }); }); it('can process if option \'trailingslash\' disabled', () => { - cy.request({ url: '/index.php/component/users/login/', followRedirect: false }).then((response) => { - expect(response.status).to.eq(301); - expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login$/); - }); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.request({ url: '/index.php/component/users/login/', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(301); + expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login$/); + }); + cy.request({ url: '/index.php/component/users/login', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(200); + }); cy.visit('/'); cy.get('li.nav-item').contains('Home') .should('have.attr', 'href') @@ -79,14 +101,16 @@ describe('Test that the sef system plugin', () => { }); it('can process if option \'trailingslash\' enabled', () => { - cy.db_updateExtensionParameter('trailingslash', '1', 'plg_system_sef'); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(301); - expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login\/$/); - }); - cy.request({ url: '/index.php/component/users/login/', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.db_updateExtensionParameter('trailingslash', '1', 'plg_system_sef') + .then(() => cy.request({ url: '/index.php/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(301); + expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login\/$/); + }) + .then(() => cy.request({ url: '/index.php/component/users/login/', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }); cy.visit('/'); cy.get('li.nav-item').contains('Home') .should('have.attr', 'href') @@ -94,22 +118,26 @@ describe('Test that the sef system plugin', () => { }); it('can process if option \'strictrouting\' enabled', () => { - cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(301); - expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login$/); - }); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(301); + expect(response.redirectedToUrl).to.match(/\/index\.php\/component\/users\/login$/); + }); + cy.request({ url: '/index.php/component/users/login', followRedirect: false }) + .then((response) => { + expect(response.status).to.eq(200); + }); }); it('can process if option \'strictrouting\' disabled', () => { - cy.db_updateExtensionParameter('strictrouting', '0', 'plg_system_sef'); - cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); - cy.request({ url: '/index.php/component/users/login', followRedirect: false }).then((response) => { - expect(response.status).to.eq(200); - }); + cy.db_updateExtensionParameter('strictrouting', '0', 'plg_system_sef') + .then(() => cy.request({ url: '/index.php?option=com_users&view=login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }) + .then(() => cy.request({ url: '/index.php/component/users/login', followRedirect: false })) + .then((response) => { + expect(response.status).to.eq(200); + }); }); }); diff --git a/tests/System/plugins/fs.mjs b/tests/System/plugins/fs.mjs index 5dd1a23e3a59c..fd04e5122e003 100644 --- a/tests/System/plugins/fs.mjs +++ b/tests/System/plugins/fs.mjs @@ -33,27 +33,32 @@ function deleteRelativePath(relativePath, config) { * @param {object} config - The Cypress configuration object * @param {number} [mode=0o444] - The file mode to be used (in octal) * - * @returns null + * @returns {Promise} - A promise that resolves to a success message or rejects with an error */ function writeRelativeFile(relativePath, content, config, mode = 0o444) { - const fullPath = join(config.env.cmsPath, relativePath); - // Prologue: Reset process file mode creation mask to ensure the umask value is not subtracted - const oldmask = umask(0); - // Create missing parent directories with 'rwxrwxrwx' - mkdirSync(dirname(fullPath), { recursive: true, mode: 0o777 }); - // Check if the file exists - if (existsSync(fullPath)) { - // Set 'rw-rw-rw-' to be able to overwrite the file - chmodSync(fullPath, 0o666); - } - // Write or overwrite the file on relative path with given content - writeFileSync(fullPath, content); - // Finally set given file mode or default 'r--r--r--' - chmodSync(fullPath, mode); - // Epilogue: Restore process file mode creation mask - umask(oldmask); - - return null; + return new Promise((resolve, reject) => { + try { + const fullPath = join(config.env.cmsPath, relativePath); + // Prologue: Reset process file mode creation mask to ensure the umask value is not subtracted + const oldmask = umask(0); + // Create missing parent directories with 'rwxrwxrwx' + mkdirSync(dirname(fullPath), { recursive: true, mode: 0o777 }); + // Check if the file exists + if (existsSync(fullPath)) { + // Set 'rw-rw-rw-' to be able to overwrite the file + chmodSync(fullPath, 0o666); + } + // Write or overwrite the file on relative path with given content + writeFileSync(fullPath, content); + // Finally set given file mode or default 'r--r--r--' + chmodSync(fullPath, mode); + // Epilogue: Restore process file mode creation mask + umask(oldmask); + resolve(`File successfully written: ${fullPath}`); + } catch (error) { + reject(new Error(`Failed to write file: ${error.message}`)); + } + }); } /** diff --git a/tests/System/support/commands/config.mjs b/tests/System/support/commands/config.mjs index 4987273e8ee49..e9d51de635fac 100644 --- a/tests/System/support/commands/config.mjs +++ b/tests/System/support/commands/config.mjs @@ -1,7 +1,8 @@ Cypress.Commands.add('config_setParameter', (parameter, value) => { const configPath = `${Cypress.env('cmsPath')}/configuration.php`; - cy.readFile(configPath).then((fileContent) => { + // Return a Cypress chainable for chaining + return cy.readFile(configPath).then((fileContent) => { // Setup the new value const newValue = typeof value === 'string' ? `'${value}'` : value; @@ -12,6 +13,6 @@ Cypress.Commands.add('config_setParameter', (parameter, value) => { const content = fileContent.replace(regex, `public $${parameter} = ${newValue};`); // Write the modified content back to the configuration file relative to the CMS root folder - cy.task('writeRelativeFile', { path: 'configuration.php', content }); + return cy.task('writeRelativeFile', { path: 'configuration.php', content }); }); }); From 9956abc42ca69b697ac83476642f44c1f77e4ba6 Mon Sep 17 00:00:00 2001 From: Stefan Wendhausen Date: Sat, 25 Jan 2025 18:07:34 +0100 Subject: [PATCH 04/16] [5.2] superfluous space deleted, alpha sorting and wording for pr #39878 (#44753) --- administrator/language/en-GB/com_media.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/language/en-GB/com_media.ini b/administrator/language/en-GB/com_media.ini index f8e617dc457a9..ffb7bace8c5db 100644 --- a/administrator/language/en-GB/com_media.ini +++ b/administrator/language/en-GB/com_media.ini @@ -24,10 +24,10 @@ COM_MEDIA_COPY_FOLDER_DESTINATION_CAN_NOT_DELETE="Copy folder is not possible as COM_MEDIA_COPY_FOLDER_NOT_POSSIBLE="Copy folder is not possible" COM_MEDIA_CREATE_NEW_FOLDER="Create New Folder" COM_MEDIA_CREATE_NEW_FOLDER_ERROR="Error creating folder." +COM_MEDIA_CREATE_NEW_FOLDER_EXISTING_FOLDER_ERROR="Folder or file name already exists." +COM_MEDIA_CREATE_NEW_FOLDER_RELATIVE_PATH_ERROR="Use of relative paths not permitted." COM_MEDIA_CREATE_NEW_FOLDER_SUCCESS="Folder created." -COM_MEDIA_CREATE_NEW_FOLDER_EXISTING_FOLDER_ERROR="Folder or file name already exists " -COM_MEDIA_CREATE_NEW_FOLDER_RELATIVE_PATH_ERROR="Use of relative paths not permitted" -COM_MEDIA_CREATE_NEW_FOLDER_UNEXPECTED_CHARACTER="Only Alphanumeric ,underscore(_),hyphen(-) and peroid(.) are allowed" +COM_MEDIA_CREATE_NEW_FOLDER_UNEXPECTED_CHARACTER="Invalid folder name. Please choose a folder name with a-z, A-Z, 0-9, ., - and _." COM_MEDIA_DECREASE_GRID="Decrease grid size" COM_MEDIA_DELETE_ERROR="Error deleting the item." COM_MEDIA_DELETE_NOT_POSSIBLE="Delete not possible!" From 6ca08f1d23983599bf1e36d7255fe50afa56fb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20L=C3=BCbbe?= Date: Sun, 26 Jan 2025 11:55:06 +0100 Subject: [PATCH 05/16] [5.2][Cypress] Minor Code Simplicifcation (#44780) Since `setSefDefaults` already returns a Promise (which Cypress understands and waits for), there's no need to wrap it in an anonymous function. Therefore, the code is simplified for more beauty. Thanks to @laoneo for the hint. --- tests/System/integration/plugins/system/sef/SefPlugin.cy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/System/integration/plugins/system/sef/SefPlugin.cy.js b/tests/System/integration/plugins/system/sef/SefPlugin.cy.js index b4a81da32df4e..8de2a9951da75 100644 --- a/tests/System/integration/plugins/system/sef/SefPlugin.cy.js +++ b/tests/System/integration/plugins/system/sef/SefPlugin.cy.js @@ -9,10 +9,10 @@ describe('Test that the sef system plugin', () => { .then(() => cy.db_updateExtensionParameter('strictrouting', '1', 'plg_system_sef')); // Ensure that we always start with a clean SEF default state - beforeEach(() => setSefDefaults()); + beforeEach(setSefDefaults); // Return to the clean SEF default state for subsequent Joomla System Tests - afterEach(() => setSefDefaults()); + afterEach(setSefDefaults); it('can process if option \'sef\' disabled', () => { cy.config_setParameter('sef', false) From 365fb99188deb4f051e4a7da921a16ed103ca216 Mon Sep 17 00:00:00 2001 From: Brian Teeman Date: Sun, 26 Jan 2025 17:55:58 +0000 Subject: [PATCH 06/16] [5.2.3] User Action Logs Email (#44709) --- .../com_admin/sql/updates/mysql/5.2.3-2025-01-09.sql | 3 +++ .../com_admin/sql/updates/postgresql/5.2.3-2025-01-09.sql | 3 +++ administrator/language/en-GB/com_actionlogs.ini | 2 +- installation/sql/mysql/supports.sql | 2 +- installation/sql/postgresql/supports.sql | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 administrator/components/com_admin/sql/updates/mysql/5.2.3-2025-01-09.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/5.2.3-2025-01-09.sql diff --git a/administrator/components/com_admin/sql/updates/mysql/5.2.3-2025-01-09.sql b/administrator/components/com_admin/sql/updates/mysql/5.2.3-2025-01-09.sql new file mode 100644 index 0000000000000..8620500fb8c00 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/5.2.3-2025-01-09.sql @@ -0,0 +1,3 @@ +UPDATE `#__mail_templates` +SET `params` = '{"tags":["messages","message","date","extension","username"]}' +WHERE `template_id` = 'com_actionlogs.notification'; diff --git a/administrator/components/com_admin/sql/updates/postgresql/5.2.3-2025-01-09.sql b/administrator/components/com_admin/sql/updates/postgresql/5.2.3-2025-01-09.sql new file mode 100644 index 0000000000000..d2b74690080b7 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/5.2.3-2025-01-09.sql @@ -0,0 +1,3 @@ +UPDATE "#__mail_templates" +SET "params" = '"tags":["messages","message","date","extension","username"]}' +WHERE "template_id" = 'com_actionlogs.notification'; diff --git a/administrator/language/en-GB/com_actionlogs.ini b/administrator/language/en-GB/com_actionlogs.ini index 66fed04dec690..d7e71dc5098e8 100644 --- a/administrator/language/en-GB/com_actionlogs.ini +++ b/administrator/language/en-GB/com_actionlogs.ini @@ -18,7 +18,7 @@ COM_ACTIONLOGS_DATE_RELATIVE_LABEL="Relative Date/Time" COM_ACTIONLOGS_DISABLED="Disabled" COM_ACTIONLOGS_EMAIL_BODY="Latest User Actions\n------\nThis is the latest action performed by a user on your website.\n\nAction | Date | Extension | Name\n{MESSAGES} {MESSAGE} | {DATE} | {EXTENSION} | {USERNAME} \n{/MESSAGES}" COM_ACTIONLOGS_EMAIL_DESC="This is the latest action performed by a user on your website." -COM_ACTIONLOGS_EMAIL_HTMLBODY="

Latest User Actions

\n

This is the latest action performed by a user on your website.

\n\n\n\n\n\n\n\n\n{MESSAGES}\n\n\n\n\n{/MESSAGES}\n\n
ActionDateExtensionName
{MESSAGE}{DATE}{EXTENSION}{USERNAME}
" +COM_ACTIONLOGS_EMAIL_HTMLBODY="

Latest User Actions

\n

This is the latest action performed by a user on your website.

\n{MESSAGES}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
ActionDateExtensionName
{MESSAGE}{DATE}{EXTENSION}{USERNAME}
{/MESSAGES}" COM_ACTIONLOGS_EMAIL_SUBJECT="Latest User Actions" COM_ACTIONLOGS_ERROR_COULD_NOT_EXPORT_DATA="Could not export data." COM_ACTIONLOGS_EXPORT_ALL_CSV="Export All as CSV" diff --git a/installation/sql/mysql/supports.sql b/installation/sql/mysql/supports.sql index fdfd982e81ce0..2ef219f6d728f 100644 --- a/installation/sql/mysql/supports.sql +++ b/installation/sql/mysql/supports.sql @@ -416,7 +416,7 @@ INSERT INTO `#__mail_templates` (`template_id`, `extension`, `language`, `subjec ('com_users.reminder', 'com_users','', 'COM_USERS_EMAIL_USERNAME_REMINDER_SUBJECT', 'COM_USERS_EMAIL_USERNAME_REMINDER_BODY', '', '', '{"tags":["name","username","sitename","email","link_text","link_html"]}'), ('plg_task_updatenotification.mail', 'plg_task_updatenotification', '', 'PLG_TASK_UPDATENOTIFICATION_EMAIL_SUBJECT', 'PLG_TASK_UPDATENOTIFICATION_EMAIL_BODY', '', '', '{"tags":["newversion","curversion","sitename","url","link","releasenews"]}'), ('plg_user_joomla.mail', 'plg_user_joomla', '', 'PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT', 'PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY', '', '', '{"tags":["name","sitename","url","username","password","email"]}'), -('com_actionlogs.notification', 'com_actionlogs', '', 'COM_ACTIONLOGS_EMAIL_SUBJECT', 'COM_ACTIONLOGS_EMAIL_BODY', 'COM_ACTIONLOGS_EMAIL_HTMLBODY', '', '{"tags":["message","date","extension","username"]}'), +('com_actionlogs.notification', 'com_actionlogs', '', 'COM_ACTIONLOGS_EMAIL_SUBJECT', 'COM_ACTIONLOGS_EMAIL_BODY', 'COM_ACTIONLOGS_EMAIL_HTMLBODY', '', '{"tags":["messages","message","date","extension","username"]}'), ('com_privacy.userdataexport', 'com_privacy', '', 'COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT', 'COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY', '', '', '{"tags":["sitename","url"]}'), ('com_privacy.notification.export', 'com_privacy', '', 'COM_PRIVACY_EMAIL_REQUEST_SUBJECT_EXPORT_REQUEST', 'COM_PRIVACY_EMAIL_REQUEST_BODY_EXPORT_REQUEST', '', '', '{"tags":["sitename","url","tokenurl","formurl","token"]}'), ('com_privacy.notification.remove', 'com_privacy', '', 'COM_PRIVACY_EMAIL_REQUEST_SUBJECT_REMOVE_REQUEST', 'COM_PRIVACY_EMAIL_REQUEST_BODY_REMOVE_REQUEST', '', '', '{"tags":["sitename","url","tokenurl","formurl","token"]}'), diff --git a/installation/sql/postgresql/supports.sql b/installation/sql/postgresql/supports.sql index fb6571f6f951b..1478ef3ce2575 100644 --- a/installation/sql/postgresql/supports.sql +++ b/installation/sql/postgresql/supports.sql @@ -427,7 +427,7 @@ INSERT INTO "#__mail_templates" ("template_id", "extension", "language", "subjec ('com_users.reminder', 'com_users', '', 'COM_USERS_EMAIL_USERNAME_REMINDER_SUBJECT', 'COM_USERS_EMAIL_USERNAME_REMINDER_BODY', '', '', '{"tags":["name","username","sitename","email","link_text","link_html"]}'), ('plg_task_updatenotification.mail', 'plg_task_updatenotification', '', 'PLG_TASK_UPDATENOTIFICATION_EMAIL_SUBJECT', 'PLG_TASK_UPDATENOTIFICATION_EMAIL_BODY', '', '', '{"tags":["newversion","curversion","sitename","url","link","releasenews"]}'), ('plg_user_joomla.mail', 'plg_user_joomla', '', 'PLG_USER_JOOMLA_NEW_USER_EMAIL_SUBJECT', 'PLG_USER_JOOMLA_NEW_USER_EMAIL_BODY', '', '', '{"tags":["name","sitename","url","username","password","email"]}'), -('com_actionlogs.notification', 'com_actionlogs', '', 'COM_ACTIONLOGS_EMAIL_SUBJECT', 'COM_ACTIONLOGS_EMAIL_BODY', 'COM_ACTIONLOGS_EMAIL_HTMLBODY', '', '{"tags":["message","date","extension","username"]}'), +('com_actionlogs.notification', 'com_actionlogs', '', 'COM_ACTIONLOGS_EMAIL_SUBJECT', 'COM_ACTIONLOGS_EMAIL_BODY', 'COM_ACTIONLOGS_EMAIL_HTMLBODY', '', '{"tags":["messages","message","date","extension","username"]}'), ('com_privacy.userdataexport', 'com_privacy', '', 'COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_SUBJECT', 'COM_PRIVACY_EMAIL_DATA_EXPORT_COMPLETED_BODY', '', '', '{"tags":["sitename","url"]}'), ('com_privacy.notification.export', 'com_privacy', '', 'COM_PRIVACY_EMAIL_REQUEST_SUBJECT_EXPORT_REQUEST', 'COM_PRIVACY_EMAIL_REQUEST_BODY_EXPORT_REQUEST', '', '', '{"tags":["sitename","url","tokenurl","formurl","token"]}'), ('com_privacy.notification.remove', 'com_privacy', '', 'COM_PRIVACY_EMAIL_REQUEST_SUBJECT_REMOVE_REQUEST', 'COM_PRIVACY_EMAIL_REQUEST_BODY_REMOVE_REQUEST', '', '', '{"tags":["sitename","url","tokenurl","formurl","token"]}'), From 8dab706cbc7dafe0a8b08a19258ff3316529e114 Mon Sep 17 00:00:00 2001 From: Brian Teeman Date: Tue, 28 Jan 2025 09:36:06 +0000 Subject: [PATCH 07/16] [5.2] Remove trailing slash for consistency (#44793) Joomla uses html not xhtml so it is not needed to close a ` Date: Fri, 31 Jan 2025 18:14:03 +0100 Subject: [PATCH 08/16] [5.2] Fix namespace map creation on PHP 8.4 (#44789) --- libraries/namespacemap.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/namespacemap.php b/libraries/namespacemap.php index 9cb31ae86c345..39ec5df367c31 100644 --- a/libraries/namespacemap.php +++ b/libraries/namespacemap.php @@ -144,8 +144,11 @@ protected function writeNamespaceFile($elements) */ $error_reporting = error_reporting(0); + // Convert array of lines to string + $content = implode("\n", $content); + try { - File::write($this->file, implode("\n", $content)); + File::write($this->file, $content); } catch (Exception $e) { Log::add('Could not save ' . $this->file, Log::WARNING); From b2258c993241c14ebb0b223529f04d6a701eea2d Mon Sep 17 00:00:00 2001 From: Christian Heel <66922325+heelc29@users.noreply.github.com> Date: Sun, 2 Feb 2025 20:51:19 +0100 Subject: [PATCH 09/16] [5.2] add PHP8.4 to PhpVersionCheck quickicon (#44809) --- .../phpversioncheck/src/Extension/PhpVersionCheck.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/quickicon/phpversioncheck/src/Extension/PhpVersionCheck.php b/plugins/quickicon/phpversioncheck/src/Extension/PhpVersionCheck.php index 69b27c005bb0e..d3fddac3dd1e4 100644 --- a/plugins/quickicon/phpversioncheck/src/Extension/PhpVersionCheck.php +++ b/plugins/quickicon/phpversioncheck/src/Extension/PhpVersionCheck.php @@ -147,6 +147,10 @@ private function getPhpSupport() 'security' => '2025-12-31', 'eos' => '2027-12-31', ], + '8.4' => [ + 'security' => '2026-12-31', + 'eos' => '2028-12-31', + ], ]; // Fill our return array with default values From 2f6810245b4b0379e2940392d41b551af8e20e6c Mon Sep 17 00:00:00 2001 From: Brian Teeman Date: Sun, 2 Feb 2025 22:17:24 +0000 Subject: [PATCH 10/16] [5.2] Email alt text on contact (#44491) --- components/com_contact/src/View/Contact/HtmlView.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/com_contact/src/View/Contact/HtmlView.php b/components/com_contact/src/View/Contact/HtmlView.php index bf5850a9eed4c..f0114ab71b04f 100644 --- a/components/com_contact/src/View/Contact/HtmlView.php +++ b/components/com_contact/src/View/Contact/HtmlView.php @@ -270,7 +270,7 @@ public function display($tpl = null) if ($item->params->get('icon_email')) { $item->params->set( 'marker_email', - HTMLHelper::_('image', $item->params->get('icon_email', ''), Text::_('COM_CONTACT_EMAIL'), false) + HTMLHelper::_('image', $item->params->get('icon_email', ''), Text::_('COM_CONTACT_EMAIL_LABEL'), false) ); } From 58b0f85ba9edfeb8682d01b859b866fa52a12ddc Mon Sep 17 00:00:00 2001 From: Fedir Zinchuk Date: Mon, 3 Feb 2025 00:18:43 +0200 Subject: [PATCH 11/16] [5.2] Web Asset Manager incorect loading of external resource with / at the end (#44774) --- libraries/src/WebAsset/WebAssetItem.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/src/WebAsset/WebAssetItem.php b/libraries/src/WebAsset/WebAssetItem.php index 02f05ae273203..14ecdf246c249 100644 --- a/libraries/src/WebAsset/WebAssetItem.php +++ b/libraries/src/WebAsset/WebAssetItem.php @@ -177,7 +177,10 @@ public function getUri($resolvePath = true): string break; default: // Asset for the ES modules may give us a folder for ESM import map - if (str_ends_with($path, '/') && !str_starts_with($path, '.')) { + if ( + $this->getOption('importmap') && !$this->isPathExternal($path) && + str_ends_with($path, '/') && !str_starts_with($path, '.') + ) { $path = Uri::root(true) . '/' . $path; } break; From 6a5ad383187a886ca8a03fe92bbe0bb9a5ab54a2 Mon Sep 17 00:00:00 2001 From: Richard Fath Date: Sun, 2 Feb 2025 23:23:35 +0100 Subject: [PATCH 12/16] [5.2] [Security] Composer update symfony/http-client and symfony/process to version 6.4.15 (#44805) --- composer.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.lock b/composer.lock index cdb240820a8d4..3a14c9193ae5d 100644 --- a/composer.lock +++ b/composer.lock @@ -4344,16 +4344,16 @@ }, { "name": "symfony/http-client", - "version": "v6.4.11", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "4c92046bb788648ff1098cc66da69aa7eac8cb65" + "reference": "cb4073c905cd12b8496d24ac428a9228c1750670" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/4c92046bb788648ff1098cc66da69aa7eac8cb65", - "reference": "4c92046bb788648ff1098cc66da69aa7eac8cb65", + "url": "https://api.github.com/repos/symfony/http-client/zipball/cb4073c905cd12b8496d24ac428a9228c1750670", + "reference": "cb4073c905cd12b8496d24ac428a9228c1750670", "shasum": "" }, "require": { @@ -4417,7 +4417,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.11" + "source": "https://github.com/symfony/http-client/tree/v6.4.15" }, "funding": [ { @@ -4433,7 +4433,7 @@ "type": "tidelift" } ], - "time": "2024-08-26T06:30:21+00:00" + "time": "2024-11-13T13:40:18+00:00" }, { "name": "symfony/http-client-contracts", @@ -10068,16 +10068,16 @@ }, { "name": "symfony/process", - "version": "v6.4.8", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5" + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8d92dd79149f29e89ee0f480254db595f6a6a2c5", - "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5", + "url": "https://api.github.com/repos/symfony/process/zipball/3cb242f059c14ae08591c5c4087d1fe443564392", + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392", "shasum": "" }, "require": { @@ -10109,7 +10109,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.8" + "source": "https://github.com/symfony/process/tree/v6.4.15" }, "funding": [ { @@ -10125,7 +10125,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T14:49:08+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/stopwatch", From e7c183698fc5d5d5379a25d21974ad60b8200027 Mon Sep 17 00:00:00 2001 From: Cliff Date: Sun, 2 Feb 2025 22:24:48 +0000 Subject: [PATCH 13/16] Update Developers link in README.md and README.txt (#44802) --- README.md | 2 +- README.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a8aef9f1d4846..0578e66327ea0 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ Do you want to improve Joomla? * Where to [request a feature](https://issues.joomla.org)? * How do you [report a bug](https://docs.joomla.org/Special:MyLanguage/Filing_bugs_and_issues) on the [Issue Tracker](https://issues.joomla.org)? * Get Involved: Joomla! is community developed software. [Join the community](https://volunteers.joomla.org). -* Documentation for [Developers](https://docs.joomla.org/Special:MyLanguage/Portal:Developers). +* Documentation for [Developers](https://manual.joomla.org/). * Documentation for [Web designers](https://docs.joomla.org/Special:MyLanguage/Web_designers). * Provide a translation for Joomla: [Joomla Crowdin Project](https://joomla.crowdin.com/cms) diff --git a/README.txt b/README.txt index 180ac5724832b..95c5488dace9e 100644 --- a/README.txt +++ b/README.txt @@ -66,7 +66,7 @@ Joomla! CMS™ * Where to request a feature? https://issues.joomla.org * How do you report a bug? https://docs.joomla.org/Special:MyLanguage/Filing_bugs_and_issues * Get Involved: Joomla! is a community developed software. Join the community at https://volunteers.joomla.org - * Documentation for Developers: https://docs.joomla.org/Special:MyLanguage/Portal:Developers + * Documentation for Developers: https://manual.joomla.org/ * Documentation for Web designers: https://docs.joomla.org/Special:MyLanguage/Web_designers Copyright: From da9ed62c9fa83ff3a8603b28338aaf5bad76324a Mon Sep 17 00:00:00 2001 From: Hannes Papenberg Date: Mon, 3 Feb 2025 10:11:20 +0100 Subject: [PATCH 14/16] Tag Router: Allow numeric/CSV IDs (Regression) (#44784) --- components/com_tags/src/Service/Router.php | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/components/com_tags/src/Service/Router.php b/components/com_tags/src/Service/Router.php index 9b337f52bfc85..06f7b2deb3dc0 100644 --- a/components/com_tags/src/Service/Router.php +++ b/components/com_tags/src/Service/Router.php @@ -278,14 +278,33 @@ public function parse(&$segments) $vars['view'] = array_shift($segments); } - $ids = []; + $ids = []; + $matchedAlias = false; if ($item && $item->query['view'] == 'tag') { $ids = $item->query['id']; } + // Iterate through all URL segments and try to parse tag IDs from them while (\count($segments)) { $id = array_shift($segments); + + // We have a numeric ID + if (!$matchedAlias && is_numeric($id)) { + $ids[] = $id; + + // We allow more than one numeric segment in the URL + continue; + } + + // We have a comma-separated list of IDs + if (!$matchedAlias && str_contains($id, ',')) { + $ids[] = $id; + + // We don't allow more than one list of IDs in a URL + break; + } + $slug = $this->fixSegment($id); // We did not find the segment as a tag in the DB @@ -294,7 +313,9 @@ public function parse(&$segments) break; } - $ids[] = $slug; + // We don't want to match numeric or comma-separated segments after we matched an alias + $matchedAlias = true; + $ids[] = $slug; } if (\count($ids)) { From 78818e8045035f6a42e6c226f25a30eb6864a008 Mon Sep 17 00:00:00 2001 From: Peter Martin Date: Mon, 3 Feb 2025 10:47:25 +0100 Subject: [PATCH 15/16] [4.4] Cache: Fix for counting the Number of Files correctly (#43986) Co-authored-by: Robert Deutz Co-authored-by: Hannes Papenberg --- libraries/src/Cache/Storage/FileStorage.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/src/Cache/Storage/FileStorage.php b/libraries/src/Cache/Storage/FileStorage.php index b5bd935ec0dce..5b6e2d4568576 100644 --- a/libraries/src/Cache/Storage/FileStorage.php +++ b/libraries/src/Cache/Storage/FileStorage.php @@ -158,6 +158,11 @@ public function getAll() $item = new CacheStorageHelper($folder); foreach ($files as $file) { + // Do not include index.html with the Number of Files + if ($file === 'index.html') { + continue; + } + $item->updateSize(filesize($path . '/' . $folder . '/' . $file)); } From a89c179f84833334ff5d196549959fcf7d2fd51f Mon Sep 17 00:00:00 2001 From: Elisa Foltyn Date: Mon, 3 Feb 2025 11:49:29 +0100 Subject: [PATCH 16/16] 5.2 dev Fix breadcrumbs color in light and darkmode, fix for 44134 (#44212) --- .../com_media/scss/components/_media-breadcrumb.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/media_source/com_media/scss/components/_media-breadcrumb.scss b/build/media_source/com_media/scss/components/_media-breadcrumb.scss index 4d26983eb3bc5..cb2076fba6280 100644 --- a/build/media_source/com_media/scss/components/_media-breadcrumb.scss +++ b/build/media_source/com_media/scss/components/_media-breadcrumb.scss @@ -31,8 +31,12 @@ } &:last-of-type { background-color: $breadcrumbs-current-bg; + a { + color: var(--body-color); + } + &::before, &::after { - border-inline-start-color: $breadcrumbs-current-bg; + border: none; } } &:hover {