mirror of
https://github.com/mattermost/mattermost.git
synced 2026-02-03 20:40:00 -05:00
MM-63699 E2E/Playwright (accessibility): Notifications settings (#33969)
This commit is contained in:
parent
6b72b2f308
commit
b93245b679
16 changed files with 580 additions and 71 deletions
|
|
@ -5,3 +5,5 @@ playwright-report
|
|||
storage_state
|
||||
test-results
|
||||
results
|
||||
specs/**/*.yml
|
||||
specs/**/*.yaml
|
||||
|
|
|
|||
|
|
@ -27,3 +27,33 @@ export async function toBeFocusedWithFocusVisible(locator: Locator) {
|
|||
await expect(locator).toBeFocused();
|
||||
return locator.evaluate((element) => element.matches(':focus-visible'));
|
||||
}
|
||||
|
||||
export async function logFocusedElement(page: Page) {
|
||||
const focusedElementInfo = await page.evaluate(() => {
|
||||
const activeElement = document.activeElement;
|
||||
if (!activeElement) {
|
||||
return 'No element has focus';
|
||||
}
|
||||
|
||||
const tagName = activeElement.tagName.toLowerCase();
|
||||
const id = activeElement.id ? `#${activeElement.id}` : '(none)';
|
||||
const className = activeElement.className ? `.${Array.from(activeElement.classList).join('.')}` : '(none)';
|
||||
const role = activeElement.getAttribute('role') || '';
|
||||
const ariaLabel = activeElement.getAttribute('aria-label') || '';
|
||||
const text = activeElement.textContent?.slice(0, 50) || '';
|
||||
const htmlElement = activeElement as HTMLElement;
|
||||
|
||||
return {
|
||||
selector: `tag: ${tagName} | id: ${id} | class: ${className}`,
|
||||
role: role,
|
||||
ariaLabel: ariaLabel,
|
||||
text: text.length > 50 ? `${text}...` : text,
|
||||
nodeName: activeElement.nodeName,
|
||||
isVisible: htmlElement.offsetWidth > 0 && htmlElement.offsetHeight > 0,
|
||||
};
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Currently focused element:', focusedElementInfo);
|
||||
return focusedElementInfo;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,13 @@ import {
|
|||
initSetup,
|
||||
isOutsideRemoteUserHour,
|
||||
} from './server';
|
||||
import {toBeFocusedWithFocusVisible, hideDynamicChannelsContent, waitForAnimationEnd, waitUntil} from './test_action';
|
||||
import {
|
||||
toBeFocusedWithFocusVisible,
|
||||
hideDynamicChannelsContent,
|
||||
waitForAnimationEnd,
|
||||
waitUntil,
|
||||
logFocusedElement,
|
||||
} from './test_action';
|
||||
import {pages} from './ui/pages';
|
||||
import {matchSnapshot} from './visual';
|
||||
import {stubNotification, waitForNotification} from './mock_browser_api';
|
||||
|
|
@ -85,6 +91,7 @@ export class PlaywrightExtended {
|
|||
readonly hideDynamicChannelsContent;
|
||||
readonly waitForAnimationEnd;
|
||||
readonly waitUntil;
|
||||
readonly logFocusedElement;
|
||||
|
||||
// ./mock_browser_api
|
||||
readonly stubNotification;
|
||||
|
|
@ -141,6 +148,7 @@ export class PlaywrightExtended {
|
|||
this.hideDynamicChannelsContent = hideDynamicChannelsContent;
|
||||
this.waitForAnimationEnd = waitForAnimationEnd;
|
||||
this.waitUntil = waitUntil;
|
||||
this.logFocusedElement = logFocusedElement;
|
||||
|
||||
// unauthenticated page
|
||||
this.loginPage = new pages.LoginPage(page);
|
||||
|
|
|
|||
|
|
@ -7,10 +7,40 @@ type NotificationSettingsSection = 'keysWithHighlight' | 'keysWithNotification';
|
|||
|
||||
export default class NotificationsSettings {
|
||||
readonly container: Locator;
|
||||
readonly keysWithHighlightDesc: Locator;
|
||||
|
||||
readonly title;
|
||||
public id = '#notificationsSettings';
|
||||
readonly expandedSection;
|
||||
public expandedSectionId = '.section-max';
|
||||
|
||||
readonly learnMoreText;
|
||||
readonly desktopAndMobileEditButton;
|
||||
readonly desktopNotificationSoundEditButton;
|
||||
readonly emailEditButton;
|
||||
readonly keywordsTriggerNotificationsEditButton;
|
||||
readonly keywordsGetHighlightedEditButton;
|
||||
|
||||
readonly testNotificationButton;
|
||||
readonly troubleshootingDocsButton;
|
||||
|
||||
readonly keysWithHighlightDesc;
|
||||
|
||||
constructor(container: Locator) {
|
||||
this.container = container;
|
||||
|
||||
this.title = container.getByRole('heading', {name: 'Notifications', exact: true});
|
||||
this.expandedSection = container.locator(this.expandedSectionId);
|
||||
|
||||
this.learnMoreText = container.getByRole('link', {name: 'Learn more about notifications'});
|
||||
this.desktopAndMobileEditButton = container.locator('#desktopAndMobileEdit');
|
||||
this.desktopNotificationSoundEditButton = container.locator('#desktopNotificationSoundEdit');
|
||||
this.emailEditButton = container.locator('#emailEdit');
|
||||
this.keywordsTriggerNotificationsEditButton = container.locator('#keywordsAndMentionsEdit');
|
||||
this.keywordsGetHighlightedEditButton = container.locator('#keywordsAndHighlightEdit');
|
||||
|
||||
this.testNotificationButton = container.getByRole('button', {name: 'Send a test notification'});
|
||||
this.troubleshootingDocsButton = container.getByRole('button', {name: 'Troubleshooting docs '});
|
||||
|
||||
this.keysWithHighlightDesc = container.locator('#keywordsAndHighlightDesc');
|
||||
}
|
||||
|
||||
|
|
@ -18,10 +48,6 @@ export default class NotificationsSettings {
|
|||
await expect(this.container).toBeVisible();
|
||||
}
|
||||
|
||||
async getContainerId() {
|
||||
return 'notificationsSettings';
|
||||
}
|
||||
|
||||
async expandSection(section: NotificationSettingsSection) {
|
||||
if (section === 'keysWithHighlight') {
|
||||
await this.container.getByText('Keywords That Get Highlighted (without notifications)').click();
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@
|
|||
"check": "npm run lint && npm run prettier && npm run tsc && npm run lint:test-docs",
|
||||
"test": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test",
|
||||
"test:ci": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test --grep-invert @visual --project=chrome",
|
||||
"test:a11y-update-snapshots": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test specs/accessibility --project=chrome --grep @snapshots --update-snapshots --update-source-method=overwrite",
|
||||
"test:visual": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test --grep @visual",
|
||||
"test:update-snapshots": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test specs/visual --grep @visual --update-snapshots",
|
||||
"test:visual-update-snapshots": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test specs/visual --grep @visual --update-snapshots",
|
||||
"test:update-snapshots": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true playwright test --project=chrome --grep @snapshots --update-snapshots --update-source-method=overwrite",
|
||||
"test:slomo": "npm run build && cross-env PW_SNAPSHOT_ENABLE=true PW_SLOWMO=1000 playwright test",
|
||||
"percy:docker": "npm run build && cross-env PW_PERCY_ENABLE=true PERCY_BROWSER_EXECUTABLE='/ms-playwright/chromium-1169/chrome-linux/chrome' percy exec -- playwright test specs/visual --grep @visual --project=chrome --project=ipad",
|
||||
"codegen": "npm run build && cross-env playwright codegen $PW_BASE_URL",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ export default defineConfig({
|
|||
maxDiffPixelRatio: 0.0001,
|
||||
animations: 'disabled',
|
||||
},
|
||||
toMatchAriaSnapshot: {
|
||||
pathTemplate: '{testDir}/{testFilePath}-snapshots-a11y/{arg}{ext}',
|
||||
},
|
||||
},
|
||||
use: {
|
||||
baseURL: testConfig.baseURL,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,374 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {expect, test} from '@mattermost/playwright-lib';
|
||||
|
||||
test(
|
||||
'navigate on keyboard tab between interactive elements',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings']},
|
||||
async ({pw}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible and focus should be on the modal
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.container);
|
||||
|
||||
// # Press Tab and verify focus is on Close button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.closeButton);
|
||||
|
||||
// # Press Tab to move focus to Notifications tab
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.notificationsTab);
|
||||
|
||||
// # Press Tab to move focus to Learn more link
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.learnMoreText);
|
||||
|
||||
// # Press Tab to move focus to Desktop and mobile notifications button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.desktopAndMobileEditButton);
|
||||
|
||||
// # Press Tab to move focus to Desktop notification sounds button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.desktopNotificationSoundEditButton);
|
||||
|
||||
// # Press Tab to move focus to Email notifications button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.emailEditButton);
|
||||
|
||||
// # Press Tab to move focus to Keywords that trigger notifications button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.keywordsTriggerNotificationsEditButton);
|
||||
|
||||
// # Press Tab to move focus to Keywords that get highlighted (without notifications) button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.keywordsGetHighlightedEditButton);
|
||||
|
||||
// # Press Tab to move focus to Send a test notification button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.testNotificationButton);
|
||||
|
||||
// # Press Tab to move focus to Troubleshooting docs button
|
||||
await page.keyboard.press('Tab');
|
||||
await pw.toBeFocusedWithFocusVisible(notificationsSettings.troubleshootingDocsButton);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Notifications settings panel',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user, adminClient} = await pw.initSetup();
|
||||
const clientConfig = await adminClient.getClientConfig();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
// * Verify aria snapshot of Notifications settings tab
|
||||
await expect(settingsModal.notificationsSettings.container).toMatchAriaSnapshot(`
|
||||
- tabpanel "notifications":
|
||||
- heading "Notifications" [level=3]
|
||||
- link "Learn more about notifications":
|
||||
- /url: https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=${user.id}&sid=${clientConfig.DiagnosticId}&edition=enterprise&server_version=${clientConfig.Version}
|
||||
- img
|
||||
- heading "Desktop and mobile notifications Permission required" [level=4]:
|
||||
- img
|
||||
- button "Desktop and mobile notifications Permission required Edit"
|
||||
- text: Mentions, direct messages, and group messages
|
||||
- heading "Desktop notification sounds" [level=4]
|
||||
- button "Desktop notification sounds Edit"
|
||||
- text: "\\"Bing\\" for messages"
|
||||
- heading "Email notifications" [level=4]
|
||||
- button "Email notifications Edit"
|
||||
- heading "Keywords that trigger notifications" [level=4]
|
||||
- button "Keywords that trigger notifications Edit"
|
||||
- text: "\\"@${user.username}\\", \\"@channel\\", \\"@all\\", \\"@here\\""
|
||||
- heading "Keywords that get highlighted (without notifications)" [level=4]
|
||||
- button "Keywords that get highlighted (without notifications) Edit"
|
||||
- heading "Troubleshooting notifications" [level=4]
|
||||
- paragraph: Not receiving notifications? Start by sending a test notification to all your devices to check if they’re working as expected. If issues persist, explore ways to solve them with troubleshooting steps.
|
||||
- button "Send a test notification"
|
||||
- button "Troubleshooting docs "
|
||||
`);
|
||||
|
||||
// * Analyze the Notifications settings panel for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page, {disableColorContrast: true})
|
||||
.include(settingsModal.notificationsSettings.id)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Desktop and mobile notifications section',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Click Edit on Desktop and mobile notifications section
|
||||
await notificationsSettings.desktopAndMobileEditButton.click();
|
||||
|
||||
// * Verify aria snapshot of Desktop and mobile notifications section when expanded
|
||||
await notificationsSettings.expandedSection.waitFor();
|
||||
await expect(notificationsSettings.expandedSection).toMatchAriaSnapshot({
|
||||
name: 'desktop_and_mobile_section.yml',
|
||||
});
|
||||
|
||||
// # Analyze the expanded section for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page)
|
||||
.include(notificationsSettings.expandedSectionId)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Desktop notification sounds section',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Click Edit on Desktop notification sounds section
|
||||
await notificationsSettings.desktopNotificationSoundEditButton.click();
|
||||
|
||||
// * Verify aria snapshot of Desktop notification sounds section when expanded
|
||||
await notificationsSettings.expandedSection.waitFor();
|
||||
await expect(notificationsSettings.expandedSection).toMatchAriaSnapshot({
|
||||
name: 'desktop_notification_sounds_section.yml',
|
||||
});
|
||||
|
||||
// # Analyze the expanded section for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page)
|
||||
.include(notificationsSettings.expandedSectionId)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Email notifications section',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Click Edit on Email notifications section
|
||||
await notificationsSettings.emailEditButton.click();
|
||||
|
||||
// * Verify aria snapshot of Email notifications section when expanded
|
||||
await notificationsSettings.expandedSection.waitFor();
|
||||
await expect(notificationsSettings.expandedSection).toMatchAriaSnapshot({
|
||||
name: 'email_notifications_section.yml',
|
||||
});
|
||||
|
||||
// # Analyze the expanded section for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page)
|
||||
.include(notificationsSettings.expandedSectionId)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Keywords that trigger notifications section',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Click Edit on Keywords that trigger notifications section
|
||||
await notificationsSettings.keywordsTriggerNotificationsEditButton.click();
|
||||
|
||||
// * Verify aria snapshot of Keywords that trigger notifications section when expanded
|
||||
await notificationsSettings.expandedSection.waitFor();
|
||||
await expect(notificationsSettings.expandedSection).toMatchAriaSnapshot(`
|
||||
- heading "Keywords that trigger notifications" [level=4]
|
||||
- group "Keywords that trigger notifications":
|
||||
- checkbox "Your case-sensitive first name \\"${user.first_name}\\""
|
||||
- text: Your case-sensitive first name "${user.first_name}"
|
||||
- checkbox "Your non case-sensitive username \\"${user.username}\\""
|
||||
- text: Your non case-sensitive username "${user.username}"
|
||||
- checkbox "Channel-wide mentions \\"@channel\\", \\"@all\\", \\"@here\\"" [checked]
|
||||
- text: Channel-wide mentions "@channel", "@all", "@here"
|
||||
- checkbox "Other non case-sensitive words, press Tab or use commas to separate keywords:"
|
||||
- text: "Other non case-sensitive words, press Tab or use commas to separate keywords:"
|
||||
- log
|
||||
- combobox "Keywords that trigger notifications"
|
||||
- text: Notifications are triggered when someone sends a message that includes your username ("@${user.username}") or any of the options selected above.
|
||||
- separator
|
||||
- alert
|
||||
- button "Save"
|
||||
- button "Cancel"
|
||||
`);
|
||||
|
||||
// # Analyze the expanded section for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page)
|
||||
.include(notificationsSettings.expandedSectionId)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'accessibility scan and aria-snapshot of Keywords that get highlighted (without notifications) section',
|
||||
{tag: ['@accessibility', '@settings', '@notification_settings', '@snapshots']},
|
||||
async ({pw, axe}) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
|
||||
const notificationsSettings = settingsModal.notificationsSettings;
|
||||
|
||||
// # Click Edit on Keywords that get highlighted (without notifications) section
|
||||
await notificationsSettings.keywordsGetHighlightedEditButton.click();
|
||||
|
||||
// * Verify aria snapshot of Keywords that get highlighted (without notifications) section when expanded
|
||||
await notificationsSettings.expandedSection.waitFor();
|
||||
await expect(notificationsSettings.expandedSection).toMatchAriaSnapshot({
|
||||
name: 'keywords_that_get_highlighted_section.yml',
|
||||
});
|
||||
|
||||
// # Analyze the expanded section for accessibility issues
|
||||
const accessibilityScanResults = await axe
|
||||
.builder(page)
|
||||
.include(notificationsSettings.expandedSectionId)
|
||||
.analyze();
|
||||
|
||||
// * Should have no violation
|
||||
expect(accessibilityScanResults.violations).toHaveLength(0);
|
||||
},
|
||||
);
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
- heading "Desktop and mobile notifications" [level=4]
|
||||
- text:
|
||||
- heading "Browser notification permission was denied" [level=4]
|
||||
- paragraph: You're missing important message and call notifications from Mattermost. To start receiving notifications, please enable notifications for Mattermost in your browser settings.
|
||||
- button "How to enable notifications"
|
||||
- group "Send notifications for:":
|
||||
- radio "All new messages"
|
||||
- radio "Mentions, direct messages, and group messages" [checked]
|
||||
- text: Mentions, direct messages, and group messages
|
||||
- radio "Nothing"
|
||||
- checkbox "Notify me about replies to threads I'm following" [checked]
|
||||
- text: Notify me about replies to threads I'm following
|
||||
- separator
|
||||
- checkbox "Use different settings for my mobile devices"
|
||||
- text: "Use different settings for my mobile devices Trigger mobile notifications when I am:"
|
||||
- log
|
||||
- text: Online, away, or offline
|
||||
- combobox "Trigger mobile notifications when I am:"
|
||||
- separator
|
||||
- alert
|
||||
- button "Save"
|
||||
- button "Cancel"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
- heading "Desktop notification sounds" [level=4]
|
||||
- checkbox "Message notification sound" [checked]
|
||||
- text: Message notification sound
|
||||
- log
|
||||
- text: Bing
|
||||
- combobox "Message notification sound"
|
||||
- separator
|
||||
- alert
|
||||
- button "Save"
|
||||
- button "Cancel"
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
- heading "Email notifications" [level=4]
|
||||
- group:
|
||||
- group:
|
||||
- radio "On" [checked]
|
||||
- text: "On"
|
||||
- radio "Off"
|
||||
- text: "Off"
|
||||
- text: When enabled, email notifications are sent for mentions and direct messages when you are offline or away for more than 5 minutes.
|
||||
- separator
|
||||
- group:
|
||||
- checkbox "Notify me about replies to threads I’m following" [checked]
|
||||
- text: Notify me about replies to threads I’m following
|
||||
- separator
|
||||
- alert
|
||||
- button "Save"
|
||||
- button "Cancel"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
- heading "Keywords that get highlighted (without notifications)" [level=4]
|
||||
- text: "Enter non case-sensitive keywords, press Tab or use commas to separate them: option , selected.Select is focused ,type to refine list, press Down to open the menu, press left to focus selected values"
|
||||
- log
|
||||
- combobox
|
||||
- text: These keywords will be shown to you with a highlight when anyone sends a message that includes them.
|
||||
- separator
|
||||
- alert
|
||||
- button "Save"
|
||||
- button "Cancel"
|
||||
|
|
@ -8,7 +8,7 @@ import {expect, test} from '@mattermost/playwright-lib';
|
|||
*/
|
||||
test(
|
||||
'displays intro to channel view for regular user',
|
||||
{tag: ['@visual', '@channel_page']},
|
||||
{tag: ['@visual', '@channel_page', '@snapshots']},
|
||||
async ({pw, browserName, viewport}, testInfo) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
|
|
|||
|
|
@ -6,73 +6,80 @@ import {expect, test} from '@mattermost/playwright-lib';
|
|||
/**
|
||||
* @objective Capture snapshots of settings modal and key focused elements on keyboard navigation
|
||||
*/
|
||||
test('settings modal visual check', {tag: ['@visual', '@settings']}, async ({pw, browserName, viewport}, testInfo) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
test(
|
||||
'settings modal visual check',
|
||||
{tag: ['@visual', '@settings', '@snapshots']},
|
||||
async ({pw, browserName, viewport}, testInfo) => {
|
||||
// # Create and sign in a new user
|
||||
const {user} = await pw.initSetup();
|
||||
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
// # Log in a user in new browser context
|
||||
const {page, channelsPage} = await pw.testBrowser.login(user);
|
||||
const globalHeader = channelsPage.globalHeader;
|
||||
const settingsModal = channelsPage.settingsModal;
|
||||
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
// # Visit a default channel page
|
||||
await channelsPage.goto();
|
||||
await channelsPage.toBeVisible();
|
||||
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
// # Set focus to Settings button and press Enter
|
||||
await globalHeader.settingsButton.focus();
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// * Settings modal should be visible and focus should be on the modal
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.container);
|
||||
// * Settings modal should be visible and focus should be on the modal
|
||||
await expect(settingsModal.container).toBeVisible();
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.container);
|
||||
|
||||
const testArgs = {page, browserName, viewport};
|
||||
await pw.hideDynamicChannelsContent(page);
|
||||
await pw.matchSnapshot({...testInfo, title: `${testInfo.title}`}, {...testArgs, locator: settingsModal.content});
|
||||
const testArgs = {page, browserName, viewport};
|
||||
await pw.hideDynamicChannelsContent(page);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title}`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
|
||||
// # Press Tab to move focus to Close button
|
||||
await page.keyboard.press('Tab');
|
||||
// * Verify focus is on Close button
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.closeButton);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} close button`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
// # Press Tab to move focus to Close button
|
||||
await page.keyboard.press('Tab');
|
||||
// * Verify focus is on Close button
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.closeButton);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} close button`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
|
||||
// # Press Tab to move focus to Notifications tab
|
||||
await page.keyboard.press('Tab');
|
||||
// * Verify focus is on Notifications tab and Notifications Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.notificationsTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} notifications tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
// # Press Tab to move focus to Notifications tab
|
||||
await page.keyboard.press('Tab');
|
||||
// * Verify focus is on Notifications tab and Notifications Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.notificationsTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} notifications tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
|
||||
// # Press arrow down key to move focus to Display tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Display tab and Display Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.displayTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} display tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
// # Press arrow down key to move focus to Display tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Display tab and Display Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.displayTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} display tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
|
||||
// # Press arrow down key to move focus to Sidebar tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Sidebar tab and Sidebar Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.sidebarTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} sidebar tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
// # Press arrow down key to move focus to Sidebar tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Sidebar tab and Sidebar Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.sidebarTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} sidebar tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
|
||||
// # Press arrow down key to move focus to Advanced tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Advanced tab and Advanced Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.advancedTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} advanced tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
});
|
||||
// # Press arrow down key to move focus to Advanced tab
|
||||
await page.keyboard.press('ArrowDown');
|
||||
// * Verify focus is on Advanced tab and Advanced Settings panel is visible
|
||||
await pw.toBeFocusedWithFocusVisible(settingsModal.advancedTab);
|
||||
await pw.matchSnapshot(
|
||||
{...testInfo, title: `${testInfo.title} advanced tab`},
|
||||
{...testArgs, locator: settingsModal.content},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {test} from '@mattermost/playwright-lib';
|
|||
*/
|
||||
test(
|
||||
'landing page visual check',
|
||||
{tag: ['@visual', '@landing_page']},
|
||||
{tag: ['@visual', '@landing_page', '@snapshots']},
|
||||
async ({pw, page, browserName, viewport}, testInfo) => {
|
||||
// # Go to landing login page
|
||||
await pw.landingLoginPage.goto();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {test} from '@mattermost/playwright-lib';
|
|||
*/
|
||||
test(
|
||||
'login page visual check',
|
||||
{tag: ['@visual', '@login_page']},
|
||||
{tag: ['@visual', '@login_page', '@snapshots']},
|
||||
async ({pw, page, browserName, viewport}, testInfo) => {
|
||||
// # Set up the page not to redirect to the landing page
|
||||
await pw.hasSeenLandingPage();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {test} from '@mattermost/playwright-lib';
|
|||
*/
|
||||
test(
|
||||
'signup page visual check',
|
||||
{tag: ['@visual', '@signup_email_page']},
|
||||
{tag: ['@visual', '@signup_email_page', '@snapshots']},
|
||||
async ({pw, page, browserName, viewport}, testInfo) => {
|
||||
// # Set up the page not to redirect to the landing page
|
||||
await pw.hasSeenLandingPage();
|
||||
|
|
|
|||
Loading…
Reference in a new issue