Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XWIKI-16216: Allow users to rebind the shortcuts from their user profile UI #2981

Draft
wants to merge 57 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
1d33e79
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Feb 23, 2024
e540a4e
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Feb 23, 2024
36df3bf
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Feb 27, 2024
48d8e87
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Feb 28, 2024
c6de222
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 1, 2024
84e0582
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 1, 2024
32ec4c0
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Mar 1, 2024
37ab413
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 1, 2024
147e445
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Mar 11, 2024
8c358d7
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 11, 2024
204252e
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 11, 2024
b2ba4c6
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 11, 2024
3e97dd9
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Mar 12, 2024
d395e5d
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 12, 2024
bacc686
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 13, 2024
124df66
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 13, 2024
a04cfbf
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Mar 13, 2024
84a9a1d
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Apr 16, 2024
9396c6c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Apr 16, 2024
72af963
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Apr 22, 2024
c894b16
Merge branch 'master' into XWIKI-16216
Sereza7 Apr 22, 2024
9ee324b
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Jun 7, 2024
8be9ead
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Jun 18, 2024
d7fa7e1
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jun 18, 2024
83be0b8
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jun 18, 2024
3e0960c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jun 18, 2024
09c3e7d
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jun 25, 2024
1b1aac7
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jul 10, 2024
835b4c7
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Jul 26, 2024
ca85cc5
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Jul 31, 2024
1228086
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 1, 2024
101d891
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 1, 2024
ef8513a
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Oct 1, 2024
091679c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 1, 2024
6e3a355
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 1, 2024
74ffe8e
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 1, 2024
fa9d562
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 2, 2024
bc3af80
Update xwiki-platform-core/xwiki-platform-user/xwiki-platform-user-pr…
Sereza7 Oct 2, 2024
6bb5cf7
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 2, 2024
754813c
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Oct 4, 2024
74f90d2
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 4, 2024
67e337c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 4, 2024
45dcafa
XWIKI-22280: Object editor dropdowns are not keyboard accessible
Sereza7 Oct 7, 2024
2d2757c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 8, 2024
26dfb55
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 8, 2024
b67ddc1
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 8, 2024
bbc63a0
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 23, 2024
fbcd0f6
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 23, 2024
031d727
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 23, 2024
2b2ac2e
Merge branch 'xwiki:master' into XWIKI-16216
Sereza7 Oct 29, 2024
150f1e6
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 29, 2024
72e7f89
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 29, 2024
90f8096
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Oct 29, 2024
ac1e5f6
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Nov 8, 2024
9b4344c
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Nov 8, 2024
53b57b4
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Nov 8, 2024
3edd13a
XWIKI-16216: Allow users to rebind the shortcuts from their user prof…
Sereza7 Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@
## Override keyboard shortcut (if any)
##
#if ($keyboardShortcutsEnabled && "$!extraShortcut" != "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this condition still correct? It isn't possible to set a shortcut value if $extraShortcut is empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this in ac1e5f6 👍
Thank you for noticing, the logic here was off.

shortcut.remove("$extraShortcut");
shortcut.add("$extraShortcut", function() { XWiki.displayDocExtra("${extraAnchor}", "${extraTemplate}", true); }, { 'disable_in_input':true });
#set ($extraShortcutWithUserPreferences = "#getShortcutValue($extraShortcut)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this is correct? From what I understand, #getShortcutValue expects a translation key but as this used directly in shortcut.remove, I assume that $extraShortcut is the actual shortcut and not a translation key. Did you verify this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for noticing this 👍
I fixed this implementation in ac1e5f6

I tested this new version locally and it worked properly with unset shortcuts (empty) and regular edited values

shortcut.remove("$extraShortcutWithUserPreferences");
shortcut.add("$extraShortcutWithUserPreferences", function() { XWiki.displayDocExtra("${extraAnchor}", "${extraTemplate}", true); }, { 'disable_in_input':true });
Sereza7 marked this conversation as resolved.
Show resolved Hide resolved
#end
#end
document.observe("dom:loaded", extraInit, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@
#macro(submitButton $name $shortcut $value $class)
<input class="btn $!class" type="submit" name="$name"#if($keyboardShortcutsEnabled) title="$shortcut"#end value="$value"/>
#end
#**
* Returns the escaped value of the shortcut. This value can be set in two ways: via user preferences and wiki level translation
Sereza7 marked this conversation as resolved.
Show resolved Hide resolved
* keys. If there are both, the user preference will take priority.
* @param userPreferenceName The id of the user preference that is listed in XWikiUsersDocumentInitializer.java
* e.g. `shortcut_developer_usertype`
* @param translationKey The key of the translation containing the wiki level defined shortcut.
* e.g. `core.shortcuts.developer.user.type`
* @since 16.9.0-rc-1
*#
#macro(getShortcutValue $translationKey)
#set ($shortcutPreferenceObject = $xwiki.getDocument($xcontext.getUser()).getObject('XWiki.UserPreferenceShortcutsClass', 'translationKey', $translationKey))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call is quite expensive. This gets the document from the cache and performs a full clone of it. This seems particularly dangerous as this macro is likely called in a loop with all shortcuts and this might happen in every request (not sure if there is further caching).

I wonder if it wouldn't make sense to introduce a script service for it. This could help in two ways:

  1. It could avoid the clone of the document.
  2. It/a separate component could contain a cache of the shortcuts, making it even cheaper to get all shortcuts.

An alternative to an extra cache could also be a way to simply get all shortcuts in the script service to avoid repeatedly calling the method when a larger number of shortcut values is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it wouldn't make sense to introduce a script service for it. This could help in two ways:

  • It could avoid the clone of the document.
  • It/a separate component could contain a cache of the shortcuts, making it even cheaper to get all shortcuts.

Isn't the main reason for it to be cheaper that we avoid cloning the doc? AFAIK 1. is not an issue except for the performance gain described in 2.

An alternative to an extra cache could also be a way to simply get all shortcuts in the script service to avoid repeatedly calling the method when a larger number of shortcut values is needed.

👍 If we set up a script service, might as well make the most of it and make ourselves some shortcuts :)
From what I understood, it could also be done in addition to a cache.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talking about performance without having actual numbers (from profiling) is hard. It's a feeling of me that this could impact the performance, but it would be best to perform some actual profiling to see how bad it really is. I assume that adding a script service to get all shortcuts should already be a huge win. Adding a cache then adds quite some complexity that might not be warranted. A possibility could also be to cache shortcuts just for the current request in the context.

Copy link
Contributor Author

@Sereza7 Sereza7 Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When looking on making a script service, I found $crtUserDoc. It's in our velocity scripting doc and from what I understand, it would solve most of the performance issue with this. Currently, it's not used at all in XS, but it seems like our situation here is exactly why it's available.

EDIT With manual testing, this seemed to work properly /EDIT

This'd mean that there's still one getObject call for each shortcut, but as far as I understand, this is not as much of a performance issue as the getDocument.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposed the improvement in bbc63a0 .
Do you think a script service is still useful in light of this new knowledge?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While a script service could certainly make things a bit cleaner, the performance should indeed be okay that way. The clone happens only once this way the first time an object is accessed.

#if("$!shortcutPreferenceObject"!='')$escapetool.javascript($escapetool.xml($shortcutPreferenceObject.value))##
#{else}$escapetool.javascript($escapetool.xml($services.localization.render($translationKey)))##
Sereza7 marked this conversation as resolved.
Show resolved Hide resolved
#end
#end
#**
* Displays a submit button for the editor. This macro calls submitButton,
* composing all its parameters based on the action's identifier and the
Expand All @@ -74,7 +89,9 @@
* @param class The class to use.
*#
#macro(editActionButton $action $resourceIdentifier $class)
#submitButton("action_${action}", $services.localization.render("core.shortcuts.edit.${resourceIdentifier}"), $services.localization.render($resourceIdentifier), $class)
#set ($translationKey = "core.shortcuts.edit.${resourceIdentifier}")
#set ($shortcut = "#getShortcutValue($translationKey)")
#submitButton("action_${action}", $shortcut, $services.localization.render($resourceIdentifier), $class)
Sereza7 marked this conversation as resolved.
Show resolved Hide resolved
<input type="hidden" name="xaction" value="$escapetool.xml($action)" />
#end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@
<script>
//<![CDATA[
#if ($hasEdit && !$isReadOnly)
shortcut.add("$services.localization.render('core.shortcuts.view.edit')", function() {
shortcut.add("#getShortcutValue('core.shortcuts.view.edit')", function() {
var editLink = $('tmEdit').down('a');
// Make sure the shortcut doesn't work when the edit link is disabled.
if (editLink && !editLink.classList.contains('disabled')) {
Expand All @@ -482,22 +482,22 @@
}
}, {'disable_in_input': true});
#if($isAdvancedUser)
shortcut.add("$services.localization.render('core.shortcuts.view.wiki')",function() { location.href=$('tmEditWiki').href; }, { 'disable_in_input':true });
shortcut.add("$services.localization.render('core.shortcuts.view.wysiwyg')",function() { location.href=$('tmEditWysiwyg').href; }, { 'disable_in_input':true });
shortcut.add("$services.localization.render('core.shortcuts.view.inline')",function() { location.href=$('tmEditInline').href; }, { 'disable_in_input':true });
shortcut.add("$services.localization.render('core.shortcuts.view.rights')",function() { var editRights = $('tmEditRights'); location.href= editRights ? editRights.href : "$xwiki.getURL($spacePreferencesDocumentReference, 'admin', 'category=1')";}, { 'disable_in_input':true });
shortcut.add("$services.localization.render('core.shortcuts.view.objects')",function() { location.href=$('tmEditObject').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.wiki')",function() { location.href=$('tmEditWiki').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.wysiwyg')",function() { location.href=$('tmEditWysiwyg').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.inline')",function() { location.href=$('tmEditInline').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.rights')",function() { var editRights = $('tmEditRights'); location.href= editRights ? editRights.href : "$xwiki.getURL($spacePreferencesDocumentReference, 'admin', 'category=1')";}, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.objects')",function() { location.href=$('tmEditObject').href; }, { 'disable_in_input':true });
#if($hasAdmin)
shortcut.add("$services.localization.render('core.shortcuts.view.class')",function() { location.href=$('tmEditClass').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.class')",function() { location.href=$('tmEditClass').href; }, { 'disable_in_input':true });
#end
#end
#end
#if ($canDelete && $displayAdminMenu)
shortcut.add("$services.localization.render('core.shortcuts.view.delete')",function() { location.href=$('tmActionDelete').href; }, { 'disable_in_input':true });
shortcut.add("$services.localization.render('core.shortcuts.view.rename')",function() { location.href=$('tmActionRename').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.delete')",function() { location.href=$('tmActionDelete').href; }, { 'disable_in_input':true });
shortcut.add("#getShortcutValue('core.shortcuts.view.rename')",function() { location.href=$('tmActionRename').href; }, { 'disable_in_input':true });
#end
#if ($canView && $displayMoreActionsMenu)
shortcut.add("$services.localization.render('core.shortcuts.view.code')", function() { location.href = $('tmViewSource').href; }, { 'disable_in_input': true });
shortcut.add("#getShortcutValue('core.shortcuts.view.code')", function() { location.href = $('tmViewSource').href; }, { 'disable_in_input': true });
#end
//]]>
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,16 @@
req.send(null);
};

// Append developer shortcuts for toggeling userType and hiddenDocuments in the current user profile
shortcut.add("$services.localization.render('core.shortcuts.developer.user.type')", function() {
// Append developer shortcuts for toggling userType and hiddenDocuments in the current user profile
shortcut.add("#getShortcutValue('core.shortcuts.developer.user.type')", function() {
developerShortcutsRestCall("${request.contextPath}/rest/currentuser/properties/usertype/next",
"$escapetool.javascript($services.localization.render('core.shortcuts.developer.user.type.error'))");
}, {'type': shortcut.type.SEQUENCE, 'disable_in_input': true });
}, {'type': #if("$!xwiki.getDocument($xcontext.getUser()).getObject('XWiki.UserPreferenceShortcutsClass', 'translationKey', 'core.shortcuts.developer.user.type')"!='')shortcut.type.SIMPLE#{else}shortcut.type.SEQUENCE#end, 'disable_in_input': true });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call seems quite expensive. See also my comment about performance above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed partially in bbc63a0
Does this look like a good enough solution?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as written above, this looks okay from a performance point of view.


shortcut.add("$services.localization.render('core.shortcuts.developer.user.displayHiddenDocs')", function () {
shortcut.add("#getShortcutValue('core.shortcuts.developer.user.displayHiddenDocs')", function () {
developerShortcutsRestCall("${request.contextPath}/rest/currentuser/properties/displayHiddenDocuments/next",
"$escapetool.javascript($services.localization.render('core.shortcuts.developer.user.displayHiddenDocs.error'))");
}, {'type': shortcut.type.SEQUENCE, 'disable_in_input': true });
}, {'type': #if("$!xwiki.getDocument($xcontext.getUser()).getObject('XWiki.UserPreferenceShortcutsClass', 'translationKey', 'core.shortcuts.developer.user.displayHiddenDocs')"!='')shortcut.type.SIMPLE#{else}shortcut.type.SEQUENCE#end, 'disable_in_input': true });
//]]>
#end
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import org.xwiki.test.docker.junit5.TestReference;
import org.xwiki.test.docker.junit5.UITest;
import org.xwiki.test.ui.TestUtils;
import org.xwiki.test.ui.po.CommentsTab;
import org.xwiki.test.ui.po.HistoryPane;
import org.xwiki.test.ui.po.InformationPane;
import org.xwiki.test.ui.po.ViewPage;
import org.xwiki.test.ui.po.editor.EditPage;
import org.xwiki.user.test.po.ChangeAvatarPage;
Expand Down Expand Up @@ -97,6 +99,8 @@ class UserProfileIT

private static final String TEXT_EDITOR = "Text";

private static final String NEW_SHORTCUT_VALUE = "B";

private static final String DEFAULT_EDITOR = "Text (Default)";

private static final String SIMPLE_USER = "Simple";
Expand All @@ -116,6 +120,7 @@ public void setUp(TestUtils setup, TestReference testReference)
this.userName = testReference.getLastSpaceReference().getName();
setup.loginAsSuperAdmin();
setup.rest().deletePage("XWiki", this.userName);
// We make sure the user is in advanced mode so that they can use view mode shortcuts
setup.createUserAndLogin(this.userName, DEFAULT_PASSWORD);

// At first edition the Dashboard is saving the doc to insert a new object, so we need to be sure
Expand Down Expand Up @@ -251,12 +256,54 @@ void changeDefaultEditor()
assertEquals(DEFAULT_EDITOR, preferencesPage.getDefaultEditor());
}

/** Functionality check: changing the shortcut for the default edit mode. */
@Test
@Order(5)
void changeShortcutViewEdit(TestUtils setup)
{
ProfileUserProfilePage userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
PreferencesUserProfilePage preferencesPage = userProfilePage.switchToPreferences();


// Setting to Advanced user, so that the view shortcuts are enabled
PreferencesEditPage preferencesEditPage = preferencesPage.editPreferences();
preferencesEditPage.setAdvancedUserType();
preferencesEditPage.clickSaveAndView();

// Overriding the default shortcut value (E)
userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
preferencesPage = userProfilePage.switchToPreferences();
preferencesEditPage = preferencesPage.editPreferences();
preferencesEditPage.setShortcutViewEdit(NEW_SHORTCUT_VALUE);
preferencesEditPage.clickSaveAndView();

userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
preferencesPage = userProfilePage.switchToPreferences();
assertEquals(NEW_SHORTCUT_VALUE, preferencesPage.getViewEditShortcut());

// Testing that the updated shortcut preference works as intended
setup.getDriver().addPageNotYetReloadedMarker();
setup.getDriver().createActions().sendKeys(NEW_SHORTCUT_VALUE).perform();
setup.getDriver().waitUntilPageIsReloaded();
// The edit shortcut sends us to the profile section, whatever the section we were in was.
ProfileEditPage profileEditPage = new ProfileEditPage();
// We make sure we can find a field on this page (aka we didn't cast this erroneously)
assertEquals("", profileEditPage.getUserFirstName());

userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
preferencesPage = userProfilePage.switchToPreferences();
preferencesEditPage = preferencesPage.editPreferences();
// Reset the preference
preferencesEditPage.setShortcutViewEdit("");
preferencesEditPage.clickSaveAndView();
}

/**
* Check that the content of the first comment isn't used as the "About" information in the user profile. See
* XAADMINISTRATION-157.
*/
@Test
@Order(5)
@Order(6)
void commentDoesntOverrideAboutInformation(TestUtils setup)
{
ProfileUserProfilePage userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
Expand All @@ -273,7 +320,7 @@ void commentDoesntOverrideAboutInformation(TestUtils setup)
}

@Test
@Order(6)
@Order(7)
void ensureDashboardUIAddAnObjectAtFirstEdit()
{
ProfileUserProfilePage userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
Expand All @@ -283,7 +330,7 @@ void ensureDashboardUIAddAnObjectAtFirstEdit()
}

@Test
@Order(7)
@Order(8)
void verifyGroupTab(TestUtils setup)
{
GroupsUserProfilePage preferencesPage = GroupsUserProfilePage.gotoPage(this.userName);
Expand All @@ -297,7 +344,7 @@ void verifyGroupTab(TestUtils setup)
}

@Test
@Order(8)
@Order(9)
void toggleEnableDisable(TestUtils setup)
{
ProfileUserProfilePage userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
Expand Down Expand Up @@ -332,7 +379,7 @@ void toggleEnableDisable(TestUtils setup)
}

@Test
@Order(9)
@Order(10)
void disabledUserTest(TestUtils setup, TestReference testReference)
{
setup.loginAsSuperAdmin();
Expand All @@ -353,4 +400,50 @@ void disabledUserTest(TestUtils setup, TestReference testReference)
assertFalse(viewPage.exists());
assertTrue(gotException);
}

@Test
@Order(11)
void changeShortcutInformation(TestUtils setup, TestReference testReference)
{
ProfileUserProfilePage userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
PreferencesUserProfilePage preferencesPage = userProfilePage.switchToPreferences();

// Setting to Advanced user, so that the view shortcuts are enabled
PreferencesEditPage preferencesEditPage = preferencesPage.editPreferences();
preferencesEditPage.setAdvancedUserType();
preferencesEditPage.clickSaveAndView();

// Overriding the default shortcut value (I)
userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
preferencesPage = userProfilePage.switchToPreferences();
preferencesEditPage = preferencesPage.editPreferences();
preferencesEditPage.setShortcutInformation(NEW_SHORTCUT_VALUE);
preferencesEditPage.clickSaveAndView();

ViewPage viewPage = setup.createPage(testReference, "one **two** three", "");
InformationPane infoPane = viewPage.openInformationDocExtraPane();
CommentsTab commentsPane = viewPage.openCommentsDocExtraPane();
assertTrue(commentsPane.isOpened());
assertFalse(infoPane.isOpened());
// We try using the default shortcut. We expect it to not work, that is, to still have the commentsTab opened.
setup.getDriver().createActions().sendKeys("i").perform();
assertTrue(commentsPane.isOpened());
assertFalse(infoPane.isOpened());
// We now use the user preference defined shortcut to open it instead.
setup.getDriver().createActions().sendKeys(NEW_SHORTCUT_VALUE).perform();
viewPage.waitForDocExtraPaneActive("information");
assertFalse(commentsPane.isOpened());
assertTrue(infoPane.isOpened());
// We try using the default shortcut to get back to the comments tab. We expect this one to work without change.
viewPage.useShortcutKeyForCommentPane();
assertTrue(commentsPane.isOpened());
assertFalse(infoPane.isOpened());

// Reset the preference
userProfilePage = ProfileUserProfilePage.gotoPage(this.userName);
preferencesPage = userProfilePage.switchToPreferences();
preferencesEditPage = preferencesPage.editPreferences();
preferencesEditPage.setShortcutInformation("");
preferencesEditPage.clickSaveAndView();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package org.xwiki.user.test.po;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
Expand All @@ -36,6 +37,12 @@ public class PreferencesEditPage extends EditPage
@FindBy(id = "XWiki.XWikiUsers_0_timezone")
private WebElement timezone;

@FindBy(id = "XWiki.XWikiUsers_0_shortcut_view_edit")
private WebElement shortcutViewEdit;

@FindBy(id = "XWiki.XWikiUsers_0_shortcut_view_information")
private WebElement shortcutInformation;

public void setSimpleUserType()
{
Select select = new Select(this.userType);
Expand Down Expand Up @@ -81,4 +88,26 @@ public void setTimezone(String value)
this.timezone.clear();
this.timezone.sendKeys(value);
}

public void setShortcutViewEdit(String shortcutValue)
{
getDriver().scrollTo(this.shortcutViewEdit);
this.shortcutViewEdit.clear();
this.shortcutViewEdit.sendKeys(shortcutValue);
if (!shortcutValue.equals("")) {
getDriver().waitUntilElementHasNonEmptyAttributeValue(By.id("XWiki.XWikiUsers_0_shortcut_view_edit"),
"value");
}
}

public void setShortcutInformation(String shortcutValue)
{
getDriver().scrollTo(this.shortcutInformation);
this.shortcutInformation.clear();
this.shortcutInformation.sendKeys(shortcutValue);
if (!shortcutValue.equals("")) {
getDriver().waitUntilElementHasNonEmptyAttributeValue(By.id("XWiki.XWikiUsers_0_shortcut_view_information"),
"value");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public class PreferencesUserProfilePage extends AbstractUserProfilePage
@FindBy(xpath = "//div[@id='preferencesPane']/div[1]/div//dd[@data-user-property = 'editor']")
private WebElement defaultEditorToUse;

@FindBy(xpath = "//div[@id='preferencesPane']/div[1]/div/dl[5]/dd[1]")
private WebElement viewEditShortcut;

@FindBy(xpath = "//a[@id='changePassword']")
private WebElement changePassword;

Expand All @@ -66,6 +69,11 @@ public String getTimezone()
return this.timezone.getText();
}

public String getViewEditShortcut()
{
return this.viewEditShortcut.getText();
}

public PreferencesEditPage editPreferences()
{
getDriver().addPageNotYetReloadedMarker();
Expand Down
Loading