MDL-84823 message: Fix ARIA attributes in popovers and messaging drawers

> ARIA Expanded
A disclosure is a widget that allows content to be
collapsed (hidden) or expanded (visible). It has two elements:
1. Disclosure button, and
2. Section of content whose visibility is controlled by the button.

ARIA Expanded must be applied to the disclosure button element
or the element with role="button" rather than the content.

> ARIA label
Move the icon title and aria-label as they are not
interactive elements to the toggle element.
The title attribute is helpful for the tooltip,
and the aria-label benefits the screen reader.
This commit is contained in:
meirzamoodle 2025-04-02 06:05:08 +07:00
parent b2b5e32058
commit e9034326c7
16 changed files with 39 additions and 30 deletions

View File

@ -5,6 +5,6 @@ define("core/drawer",["exports","jquery","core/pubsub","core/aria","core/drawer_
* @module core/drawer
* @copyright 2019 Jun Pataleta <jun@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),PubSub=_interopRequireWildcard(PubSub),Aria=_interopRequireWildcard(Aria),_drawer_events=_interopRequireDefault(_drawer_events);const show=root=>{root=(0,_jquery.default)(root),Aria.unhide(root.get()),root.removeClass("hidden"),root.attr("aria-expanded",!0),root.focus(),PubSub.publish(_drawer_events.default.DRAWER_SHOWN,root)},hide=root=>{(root=(0,_jquery.default)(root)).addClass("hidden"),root.attr("aria-expanded",!1),Aria.hide(root.get()),PubSub.publish(_drawer_events.default.DRAWER_HIDDEN,root)},isVisible=root=>!root.hasClass("hidden"),toggle=root=>{isVisible(root)?hide(root):show(root)};var _default={hide:hide,show:show,isVisible:isVisible,toggle:toggle,registerToggles:(root,toggleElements)=>{let openTrigger=null;toggleElements.attr("aria-expanded",isVisible(root)),toggleElements.on("click",(e=>{e.preventDefault();const wasVisible=isVisible(root);toggle(root),toggleElements.attr("aria-expanded",!wasVisible),wasVisible?openTrigger&&(openTrigger.focus(),openTrigger=null):openTrigger=toggleElements.filter(((index,element)=>element==e.target||element.contains(e.target)))}))},getDrawerRoot:contentRoot=>(contentRoot=(0,_jquery.default)(contentRoot)).closest('[data-region="right-hand-drawer"]')};return _exports.default=_default,_exports.default}));
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_jquery=_interopRequireDefault(_jquery),PubSub=_interopRequireWildcard(PubSub),Aria=_interopRequireWildcard(Aria),_drawer_events=_interopRequireDefault(_drawer_events);const show=root=>{root=(0,_jquery.default)(root),Aria.unhide(root.get()),root.removeClass("hidden"),root.focus(),PubSub.publish(_drawer_events.default.DRAWER_SHOWN,root)},hide=root=>{(root=(0,_jquery.default)(root)).addClass("hidden"),Aria.hide(root.get()),PubSub.publish(_drawer_events.default.DRAWER_HIDDEN,root)},isVisible=root=>!root.hasClass("hidden"),toggle=root=>{isVisible(root)?hide(root):show(root)};var _default={hide:hide,show:show,isVisible:isVisible,toggle:toggle,registerToggles:(root,toggleElements)=>{let openTrigger=null;toggleElements.attr("aria-expanded",isVisible(root)),toggleElements.on("click",(e=>{e.preventDefault();const wasVisible=isVisible(root);toggle(root),toggleElements.attr("aria-expanded",!wasVisible),wasVisible?openTrigger&&(openTrigger.focus(),openTrigger=null):openTrigger=toggleElements.filter(((index,element)=>element==e.target||element.contains(e.target)))}))},getDrawerRoot:contentRoot=>(contentRoot=(0,_jquery.default)(contentRoot)).closest('[data-region="right-hand-drawer"]')};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=drawer.min.js.map

View File

@ -1 +1 @@
{"version":3,"file":"drawer.min.js","sources":["../src/drawer.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Controls the drawer.\n *\n * @module core/drawer\n * @copyright 2019 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport * as PubSub from 'core/pubsub';\nimport * as Aria from 'core/aria';\nimport DrawerEvents from 'core/drawer_events';\n\n/**\n * Show the drawer.\n *\n * @param {Object} root The drawer container.\n */\nconst show = root => {\n // Ensure that it is a jQuery.\n root = $(root);\n\n Aria.unhide(root.get());\n root.removeClass('hidden');\n root.attr('aria-expanded', true);\n root.focus();\n\n PubSub.publish(DrawerEvents.DRAWER_SHOWN, root);\n};\n\n/**\n * Hide the drawer.\n *\n * @param {Object} root The drawer container.\n */\nconst hide = root => {\n // Ensure that it is a jQuery.\n root = $(root);\n\n root.addClass('hidden');\n root.attr('aria-expanded', false);\n Aria.hide(root.get());\n\n PubSub.publish(DrawerEvents.DRAWER_HIDDEN, root);\n};\n\n/**\n * Check if the drawer is visible.\n *\n * @param {Object} root The drawer container.\n * @return {boolean}\n */\nconst isVisible = (root) => {\n let isHidden = root.hasClass('hidden');\n return !isHidden;\n};\n\n/**\n * Toggle the drawer visibility.\n *\n * @param {Object} root The drawer container.\n */\nconst toggle = (root) => {\n if (isVisible(root)) {\n hide(root);\n } else {\n show(root);\n }\n};\n\n/**\n * Add event listeners to toggle the drawer.\n *\n * @param {Object} root The drawer container.\n * @param {Object} toggleElements The toggle elements.\n */\nconst registerToggles = (root, toggleElements) => {\n let openTrigger = null;\n toggleElements.attr('aria-expanded', isVisible(root));\n\n toggleElements.on('click', (e) => {\n e.preventDefault();\n const wasVisible = isVisible(root);\n toggle(root);\n toggleElements.attr('aria-expanded', !wasVisible);\n\n if (!wasVisible) {\n // Remember which trigger element opened the drawer.\n openTrigger = toggleElements.filter((index, element) => {\n return element == e.target || element.contains(e.target);\n });\n } else if (openTrigger) {\n // The drawer has gone from open to close so we need to set the focus back\n // to the element that openend it.\n openTrigger.focus();\n openTrigger = null;\n }\n });\n};\n\n/**\n * Find the root element of the drawer based on the using the drawer content root's ID.\n *\n * @param {Object} contentRoot The drawer content's root element.\n * @returns {*|jQuery}\n */\nconst getDrawerRoot = (contentRoot) => {\n contentRoot = $(contentRoot);\n return contentRoot.closest('[data-region=\"right-hand-drawer\"]');\n};\n\nexport default {\n hide: hide,\n show: show,\n isVisible: isVisible,\n toggle: toggle,\n registerToggles: registerToggles,\n getDrawerRoot: getDrawerRoot\n};\n"],"names":["show","root","Aria","unhide","get","removeClass","attr","focus","PubSub","publish","DrawerEvents","DRAWER_SHOWN","hide","addClass","DRAWER_HIDDEN","isVisible","hasClass","toggle","registerToggles","toggleElements","openTrigger","on","e","preventDefault","wasVisible","filter","index","element","target","contains","getDrawerRoot","contentRoot","closest"],"mappings":";;;;;;;mQAgCMA,KAAOC,OAETA,MAAO,mBAAEA,MAETC,KAAKC,OAAOF,KAAKG,OACjBH,KAAKI,YAAY,UACjBJ,KAAKK,KAAK,iBAAiB,GAC3BL,KAAKM,QAELC,OAAOC,QAAQC,uBAAaC,aAAcV,OAQxCW,KAAOX,QAETA,MAAO,mBAAEA,OAEJY,SAAS,UACdZ,KAAKK,KAAK,iBAAiB,GAC3BJ,KAAKU,KAAKX,KAAKG,OAEfI,OAAOC,QAAQC,uBAAaI,cAAeb,OASzCc,UAAad,OACAA,KAAKe,SAAS,UAS3BC,OAAUhB,OACRc,UAAUd,MACVW,KAAKX,MAELD,KAAKC,oBA6CE,CACXW,KAAMA,KACNZ,KAAMA,KACNe,UAAWA,UACXE,OAAQA,OACRC,gBAxCoB,CAACjB,KAAMkB,sBACvBC,YAAc,KAClBD,eAAeb,KAAK,gBAAiBS,UAAUd,OAE/CkB,eAAeE,GAAG,SAAUC,IACxBA,EAAEC,uBACIC,WAAaT,UAAUd,MAC7BgB,OAAOhB,MACPkB,eAAeb,KAAK,iBAAkBkB,YAEjCA,WAKMJ,cAGPA,YAAYb,QACZa,YAAc,MAPdA,YAAcD,eAAeM,QAAO,CAACC,MAAOC,UACjCA,SAAWL,EAAEM,QAAUD,QAAQE,SAASP,EAAEM,cA4B7DE,cAXmBC,cACnBA,aAAc,mBAAEA,cACGC,QAAQ"}
{"version":3,"file":"drawer.min.js","sources":["../src/drawer.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Controls the drawer.\n *\n * @module core/drawer\n * @copyright 2019 Jun Pataleta <jun@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport $ from 'jquery';\nimport * as PubSub from 'core/pubsub';\nimport * as Aria from 'core/aria';\nimport DrawerEvents from 'core/drawer_events';\n\n/**\n * Show the drawer.\n *\n * @param {Object} root The drawer container.\n */\nconst show = root => {\n // Ensure that it is a jQuery.\n root = $(root);\n\n Aria.unhide(root.get());\n root.removeClass('hidden');\n root.focus();\n\n PubSub.publish(DrawerEvents.DRAWER_SHOWN, root);\n};\n\n/**\n * Hide the drawer.\n *\n * @param {Object} root The drawer container.\n */\nconst hide = root => {\n // Ensure that it is a jQuery.\n root = $(root);\n\n root.addClass('hidden');\n Aria.hide(root.get());\n\n PubSub.publish(DrawerEvents.DRAWER_HIDDEN, root);\n};\n\n/**\n * Check if the drawer is visible.\n *\n * @param {Object} root The drawer container.\n * @return {boolean}\n */\nconst isVisible = (root) => {\n let isHidden = root.hasClass('hidden');\n return !isHidden;\n};\n\n/**\n * Toggle the drawer visibility.\n *\n * @param {Object} root The drawer container.\n */\nconst toggle = (root) => {\n if (isVisible(root)) {\n hide(root);\n } else {\n show(root);\n }\n};\n\n/**\n * Add event listeners to toggle the drawer.\n *\n * @param {Object} root The drawer container.\n * @param {Object} toggleElements The toggle elements.\n */\nconst registerToggles = (root, toggleElements) => {\n let openTrigger = null;\n toggleElements.attr('aria-expanded', isVisible(root));\n\n toggleElements.on('click', (e) => {\n e.preventDefault();\n const wasVisible = isVisible(root);\n toggle(root);\n toggleElements.attr('aria-expanded', !wasVisible);\n\n if (!wasVisible) {\n // Remember which trigger element opened the drawer.\n openTrigger = toggleElements.filter((index, element) => {\n return element == e.target || element.contains(e.target);\n });\n } else if (openTrigger) {\n // The drawer has gone from open to close so we need to set the focus back\n // to the element that openend it.\n openTrigger.focus();\n openTrigger = null;\n }\n });\n};\n\n/**\n * Find the root element of the drawer based on the using the drawer content root's ID.\n *\n * @param {Object} contentRoot The drawer content's root element.\n * @returns {*|jQuery}\n */\nconst getDrawerRoot = (contentRoot) => {\n contentRoot = $(contentRoot);\n return contentRoot.closest('[data-region=\"right-hand-drawer\"]');\n};\n\nexport default {\n hide: hide,\n show: show,\n isVisible: isVisible,\n toggle: toggle,\n registerToggles: registerToggles,\n getDrawerRoot: getDrawerRoot\n};\n"],"names":["show","root","Aria","unhide","get","removeClass","focus","PubSub","publish","DrawerEvents","DRAWER_SHOWN","hide","addClass","DRAWER_HIDDEN","isVisible","hasClass","toggle","registerToggles","toggleElements","openTrigger","attr","on","e","preventDefault","wasVisible","filter","index","element","target","contains","getDrawerRoot","contentRoot","closest"],"mappings":";;;;;;;mQAgCMA,KAAOC,OAETA,MAAO,mBAAEA,MAETC,KAAKC,OAAOF,KAAKG,OACjBH,KAAKI,YAAY,UACjBJ,KAAKK,QAELC,OAAOC,QAAQC,uBAAaC,aAAcT,OAQxCU,KAAOV,QAETA,MAAO,mBAAEA,OAEJW,SAAS,UACdV,KAAKS,KAAKV,KAAKG,OAEfG,OAAOC,QAAQC,uBAAaI,cAAeZ,OASzCa,UAAab,OACAA,KAAKc,SAAS,UAS3BC,OAAUf,OACRa,UAAUb,MACVU,KAAKV,MAELD,KAAKC,oBA6CE,CACXU,KAAMA,KACNX,KAAMA,KACNc,UAAWA,UACXE,OAAQA,OACRC,gBAxCoB,CAAChB,KAAMiB,sBACvBC,YAAc,KAClBD,eAAeE,KAAK,gBAAiBN,UAAUb,OAE/CiB,eAAeG,GAAG,SAAUC,IACxBA,EAAEC,uBACIC,WAAaV,UAAUb,MAC7Be,OAAOf,MACPiB,eAAeE,KAAK,iBAAkBI,YAEjCA,WAKML,cAGPA,YAAYb,QACZa,YAAc,MAPdA,YAAcD,eAAeO,QAAO,CAACC,MAAOC,UACjCA,SAAWL,EAAEM,QAAUD,QAAQE,SAASP,EAAEM,cA4B7DE,cAXmBC,cACnBA,aAAc,mBAAEA,cACGC,QAAQ"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -36,7 +36,6 @@ const show = root => {
Aria.unhide(root.get());
root.removeClass('hidden');
root.attr('aria-expanded', true);
root.focus();
PubSub.publish(DrawerEvents.DRAWER_SHOWN, root);
@ -52,7 +51,6 @@ const hide = root => {
root = $(root);
root.addClass('hidden');
root.attr('aria-expanded', false);
Aria.hide(root.get());
PubSub.publish(DrawerEvents.DRAWER_HIDDEN, root);

View File

@ -126,7 +126,7 @@ define(['jquery', 'core/str', 'core/custom_interaction_events'],
}
this.root.addClass('collapsed');
this.menuContainer.attr('aria-expanded', 'false');
this.menuToggle.attr('aria-expanded', 'false');
this.menuContainer.attr('aria-hidden', 'true');
this.updateButtonAriaLabel();
this.updateFocusItemTabIndex();
@ -147,7 +147,7 @@ define(['jquery', 'core/str', 'core/custom_interaction_events'],
}
this.root.removeClass('collapsed');
this.menuContainer.attr('aria-expanded', 'true');
this.menuToggle.attr('aria-expanded', 'true');
this.menuContainer.attr('aria-hidden', 'false');
this.updateButtonAriaLabel();
this.updateFocusItemTabIndex();

View File

@ -34,7 +34,6 @@
<div
id="{{$drawerid}}drawer-{{uniqid}}{{/drawerid}}"
class="{{$drawerclasses}}{{/drawerclasses}} drawer bg-white {{^show}}hidden{{/show}}"
aria-expanded="{{#show}}true{{/show}}{{^show}}false{{/show}}"
{{^show}}aria-hidden="true"{{/show}}
data-region="right-hand-drawer"
role="region"

View File

@ -38,18 +38,19 @@
data-region="popover-region">
<div class="popover-region-toggle nav-link icon-no-margin"
data-region="popover-region-toggle"
role="button"
aria-controls="popover-region-container-{{uniqid}}"
aria-haspopup="true"
aria-expanded="false"
aria-label="{{$togglelabel}}{{#str}}showpopovermenu{{/str}}{{/togglelabel}}"
tabindex="0">
title="{{$togglelabel}}{{#str}}showpopovermenu{{/str}}{{/togglelabel}}"
tabindex="0"
role="button">
{{$togglecontent}}{{/togglecontent}}
</div>
<div {{$containerattributes}}{{/containerattributes}}
id="popover-region-container-{{uniqid}}"
class="popover-region-container"
data-region="popover-region-container"
aria-expanded="false"
aria-hidden="true"
aria-label="{{$containerlabel}}{{/containerlabel}}"
role="region">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -456,11 +456,14 @@ function(
});
PubSub.subscribe(Events.TOGGLE_VISIBILITY, function(buttonid) {
const buttonElement = document.getElementById(buttonid);
if (isVisible(root)) {
hide(root);
buttonElement?.setAttribute('aria-expanded', false);
$(SELECTORS.JUMPTO).attr('tabindex', -1);
} else {
show(namespace, root);
buttonElement?.setAttribute('aria-expanded', true);
setJumpFrom(buttonid);
$(SELECTORS.JUMPTO).attr('tabindex', 0);
}
@ -481,7 +484,7 @@ function(
if (button) {
$('#' + button).focus();
}
PubSub.publish(Events.TOGGLE_VISIBILITY);
PubSub.publish(Events.TOGGLE_VISIBILITY, button);
});
PubSub.subscribe(Events.CREATE_CONVERSATION_WITH_USER, function(args) {

View File

@ -47,7 +47,7 @@
}}{{#unreadcount}} {{#str}} shownotificationwindowwithcount, message, {{.}} {{/str}} {{/unreadcount}} {{!
}}{{/togglelabel}}
{{$togglecontent}}
{{#pix}} i/notifications, core, {{#str}} togglenotificationmenu, message {{/str}} {{/pix}}
{{#pix}} i/notifications, core {{/pix}}
<div
class="count-container {{^unreadcount}}hidden{{/unreadcount}}"
data-region="count-container"

View File

@ -36,15 +36,23 @@
}}
<div class="popover-region collapsed" data-region="popover-region-messages">
<a id="message-drawer-toggle-{{uniqid}}" class="nav-link popover-region-toggle position-relative icon-no-margin" href="#"
role="button">
{{#pix}} t/message, core, {{#str}} togglemessagemenu, message {{/str}} {{/pix}}
<a
id="message-drawer-toggle-{{uniqid}}"
class="nav-link popover-region-toggle position-relative icon-no-margin"
href="#"
aria-label="{{#str}} togglemessagemenu, message {{/str}}"
title="{{#str}} togglemessagemenu, message {{/str}}"
role="button"
aria-expanded="false"
aria-describedby="unread-messages-count-{{uniqid}}"
>
{{#pix}} t/message, core {{/pix}}
<div
class="count-container {{^unreadcount}}hidden{{/unreadcount}}"
data-region="count-container"
>
<span aria-hidden="true">{{unreadcount}}</span>
<span class="visually-hidden">{{#str}} unreadconversations, core_message, {{unreadcount}} {{/str}}</span>
<span class="visually-hidden" id="unread-messages-count-{{uniqid}}">{{#str}} unreadconversations, core_message, {{unreadcount}} {{/str}}</span>
</div>
</a>
{{> core_message/message_jumpto }}

View File

@ -16,7 +16,7 @@ Feature: Message admin settings
Given the following config values are set as admin:
| messaging | 1 |
When I log in as "admin"
Then "Toggle messaging drawer" "icon" should exist
Then "Toggle messaging drawer" "button" should exist
And I navigate to "Users > Accounts > Browse list of users" in site administration
And I should see "User One"
And I follow "User One"

View File

@ -38,14 +38,14 @@ Feature: Unread messages
And I should see "##today##%d %B##" in the "New group" "core_message > Message conversation"
And I log out
And I log in as "student2"
And I should see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should see "1" in the "Toggle messaging drawer" "button"
And I open messaging
And I should see "1" in the "Group" "core_message > Message tab"
And "New group" "core_message > Message" should exist
And I should see "1" in the "New group" "core_message > Message"
And I select "New group" conversation in messaging
And I should see "Hi!" in the "New group" "core_message > Message conversation"
And I should not see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should not see "1" in the "Toggle messaging drawer" "button"
And I should not see "1" in the "Group" "core_message > Message tab"
And I should not see "1" in the "New group" "core_message > Message"
@ -55,14 +55,14 @@ Feature: Unread messages
| student1 | student2 | Hi! |
| student2 | student1 | What do you need? |
When I log in as "student1"
Then I should see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
Then I should see "1" in the "Toggle messaging drawer" "button"
And I open messaging
And I should see "1" in the "Private" "core_message > Message tab"
And "Student 2" "core_message > Message" should exist
And I should see "1" in the "Student 2" "core_message > Message"
And I select "Student 2" conversation in messaging
And I should see "Hi!" in the "Student 2" "core_message > Message conversation"
And I should not see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should not see "1" in the "Toggle messaging drawer" "button"
And I should not see "1" in the "Private" "core_message > Message tab"
And I should not see "1" in the "Student 2" "core_message > Message"
@ -75,13 +75,13 @@ Feature: Unread messages
| user | contact |
| student1 | student2 |
When I log in as "student1"
Then I should see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
Then I should see "1" in the "Toggle messaging drawer" "button"
And I open messaging
And I should see "1" in the "Starred" "core_message > Message tab"
And "Student 2" "core_message > Message" should exist
And I should see "1" in the "Student 2" "core_message > Message"
And I select "Student 2" conversation in messaging
And I should see "Hi!" in the "Student 2" "core_message > Message conversation"
And I should not see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should not see "1" in the "Toggle messaging drawer" "button"
And I should not see "1" in the "Starred" "core_message > Message tab"
And I should not see "1" in the "Student 2" "core_message > Message"

View File

@ -50,13 +50,13 @@ Feature: Message users in the summary report
Then I should see "Message sent to 2 people"
And I log out
And I log in as "student1"
And I should see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should see "1" in the "Toggle messaging drawer" "button"
And I log out
And I log in as "student3"
And I should see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should see "1" in the "Toggle messaging drawer" "button"
And I log out
And I log in as "student2"
And I should not see "1" in the "//*[@title='Toggle messaging drawer']/../*[@data-region='count-container']" "xpath_element"
And I should not see "1" in the "Toggle messaging drawer" "button"
@javascript
Scenario: Message all users