Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,202 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {expect, test} from '@mattermost/playwright-lib';

import {setupDemoPlugin} from '../../helpers';

test('should open /dialog and post submit confirmation on submit', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Demo Plugin channel
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog command
await channelsPage.centerView.postCreate.input.fill('/dialog');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens with title "Test Title"
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Test Title');

// 6. Fill required fields
// Display Name already has default "default text" — overwrite
await dialog.getByTestId('realnameinput').fill('Test Input');

// Email and Password are required
await dialog.getByTestId('someemailemail').fill('test@example.com');
await dialog.getByTestId('somepasswordpassword').fill('testpassword123');

// Number is required
await dialog.getByTestId('somenumbernumber').fill('42');

// Option Selector — required, no default (3rd combobox: User Selector, Channel Selector, Option Selector)
await dialog.getByRole('combobox').nth(2).click();
await channelsPage.page.getByRole('option', {name: 'Option1'}).click();

// Required checkboxes
await dialog.getByRole('checkbox', {name: 'Agree to the terms of service'}).check();
await dialog.getByRole('checkbox', {name: 'Agree to the annoying terms of service'}).check();

// Radio Option Selector — required
await dialog.getByRole('radio', {name: 'Option1'}).click();

// 7. Submit the dialog
await dialog.getByRole('button', {name: 'Submit'}).click();
await expect(dialog).not.toBeVisible();

// 8. Verify the submit post appears in the channel
// Note: "Interative" is a typo in the demo plugin — not a test error
await expect(
channelsPage.centerView.container.locator('p').filter({hasText: 'submitted an Interative Dialog'}),
).toBeVisible();
});

test('should post cancellation notification when /dialog is cancelled', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Demo Plugin channel
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog command
await channelsPage.centerView.postCreate.input.fill('/dialog');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Test Title');
await expect(dialog.getByRole('button', {name: 'Cancel'})).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Submit'})).toBeVisible();

// 6. Cancel the dialog
await dialog.getByRole('button', {name: 'Cancel'}).click();
await expect(dialog).not.toBeVisible();

// 7. Verify the cancellation post appears in the channel
// Note: "Interative" is a typo in the demo plugin — not a test error
await expect(
channelsPage.centerView.container.locator('p').filter({hasText: 'canceled an Interative Dialog'}),
).toBeVisible();
});

test('should show validation errors when required fields are submitted empty', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Demo Plugin channel
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog command
await channelsPage.centerView.postCreate.input.fill('/dialog');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Test Title');

// 6. Clear the Number field and submit
await dialog.getByTestId('somenumbernumber').clear();
await dialog.getByRole('button', {name: 'Submit'}).click();

// 7. Verify dialog stays open with validation errors
await expect(dialog).toBeVisible();
await expect(dialog.getByText('Please fix all field errors', {exact: true})).toBeVisible();
await expect(dialog.getByTestId('somenumber').getByText('This field is required.', {exact: true})).toBeVisible();
});

test('should show general error and keep dialog open on /dialog error submit', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Town Square
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog error command
await channelsPage.centerView.postCreate.input.fill('/dialog error');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens with title "Simple Dialog Test"
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Simple Dialog Test');
await expect(dialog.getByRole('button', {name: 'Cancel'})).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Submit Test'})).toBeVisible();

// 6. Fill the optional field and submit
await dialog.getByPlaceholder('Enter some text (optional)...').fill('sample test input');
await dialog.getByRole('button', {name: 'Submit Test'}).click();

// 7. Verify general error appears and dialog stays open
await expect(dialog.getByText('some error', {exact: true})).toBeVisible();
await expect(dialog).toBeVisible();
await expect(dialog.getByPlaceholder('Enter some text (optional)...')).toHaveValue('sample test input');
});

test('should show general error on /dialog error-no-elements confirm', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Town Square
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog error-no-elements command
await channelsPage.centerView.postCreate.input.fill('/dialog error-no-elements');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens with title "Sample Confirmation Dialog" and no form fields
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Sample Confirmation Dialog');
await expect(dialog.getByRole('button', {name: 'Cancel'})).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Confirm'})).toBeVisible();
await expect(dialog.getByRole('textbox')).not.toBeVisible();

// 6. Click Confirm
await dialog.getByRole('button', {name: 'Confirm'}).click();

// 7. Verify general error appears and dialog stays open
await expect(dialog.getByText('some error', {exact: true})).toBeVisible();
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Cancel'})).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Confirm'})).toBeVisible();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {expect, test} from '@mattermost/playwright-lib';

import {setupDemoPlugin} from '../../helpers';

test('should open /dialog date and post submit confirmation after selecting dates', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Town Square
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog date command
await channelsPage.centerView.postCreate.input.fill('/dialog date');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens with correct title
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Date & DateTime Test Dialog');

// 6. Verify field labels and Event Title default value
await expect(dialog.getByText('Meeting Date *', {exact: true})).toBeVisible();
await expect(dialog.getByText('Meeting Date & Time *', {exact: true})).toBeVisible();
await expect(dialog.getByText('Event Title *', {exact: true})).toBeVisible();
await expect(dialog.getByRole('textbox', {name: 'Event Title *'})).toHaveValue('Team Meeting');

// 7. Select a date using the Meeting Date picker
await dialog.getByRole('button', {name: /Select a meeting date/i}).click();
await expect(channelsPage.page.getByRole('grid')).toBeVisible();
// Click day 20 — reliably available in any month
await channelsPage.page.getByRole('grid').getByText('20', {exact: true}).click();

// 8. Select date and time using the Meeting Date & Time picker
await dialog
.getByRole('button', {name: /Date.*Today|Select a date/i})
.first()
.click();
await expect(channelsPage.page.getByRole('grid')).toBeVisible();
await channelsPage.page.getByRole('grid').getByText('22', {exact: true}).click();

// Select a time from the time picker
await dialog
.getByRole('button', {name: /Time|Select a time/i})
.first()
.click();
await channelsPage.page.getByRole('menuitem', {name: '3:00 PM'}).click();

// 9. Submit — button is labelled "Create Event"
await dialog.getByRole('button', {name: 'Create Event'}).click();
await expect(dialog).not.toBeVisible();

// 10. Verify submit post appears in the channel
await expect(
channelsPage.centerView.container.locator('p').filter({hasText: 'submitted a Date Dialog'}),
).toBeVisible();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {expect, test} from '@mattermost/playwright-lib';

import {setupDemoPlugin} from '../../helpers';

test('should update form fields dynamically when project type changes via /dialog field-refresh', async ({pw}) => {
// 1. Setup
const {adminClient, user, team} = await pw.initSetup();
await setupDemoPlugin(adminClient, pw);

// 2. Login
const {channelsPage} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();

// 3. Navigate to Town Square
await channelsPage.goto(team.name, 'town-square');
await channelsPage.toBeVisible();

// 4. Send /dialog field-refresh command
await channelsPage.centerView.postCreate.input.fill('/dialog field-refresh');
await channelsPage.centerView.postCreate.sendMessage();

// 5. Confirm dialog opens with title "Project Configuration"
const dialog = channelsPage.page.getByRole('dialog');
await expect(dialog).toBeVisible();
await expect(dialog.getByRole('heading', {level: 1})).toContainText('Project Configuration');

// 6. Verify initial state — only Project Type dropdown visible
await expect(dialog.getByText('Project Type *')).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Cancel'})).toBeVisible();
await expect(dialog.getByRole('button', {name: 'Create Project'})).toBeVisible();
await expect(dialog.getByText('Frontend Framework')).not.toBeVisible();
await expect(dialog.getByText('Platform')).not.toBeVisible();
await expect(dialog.getByText('API Type')).not.toBeVisible();

// 7. Select "Web Application" — new fields should appear
// Click the react-select control (not the hidden input) to open the dropdown
await dialog.locator('[class*="Select__control"], [class*="react-select__control"]').first().click();
await channelsPage.page.getByRole('option', {name: 'Web Application'}).click();

await expect(dialog.getByText('Frontend Framework *')).toBeVisible();
await expect(dialog.getByText('Enable PWA')).toBeVisible();
await expect(dialog.getByText('Project Name *')).toBeVisible();
await expect(dialog.getByText('Platform')).not.toBeVisible();
await expect(dialog.getByText('API Type')).not.toBeVisible();

// 8. Change to "Mobile Application" — fields update
await dialog.locator('[class*="Select__control"], [class*="react-select__control"]').first().click();
await channelsPage.page.getByRole('option', {name: 'Mobile Application'}).click();

await expect(dialog.getByText('Platform *')).toBeVisible();
await expect(dialog.getByText('Minimum OS Version *')).toBeVisible();
await expect(dialog.getByText('Project Name *')).toBeVisible();
await expect(dialog.getByText('Frontend Framework')).not.toBeVisible();
await expect(dialog.getByText('Enable PWA')).not.toBeVisible();
await expect(dialog.getByText('API Type')).not.toBeVisible();

// 9. Change to "API Service" — fields update again
await dialog.locator('[class*="Select__control"], [class*="react-select__control"]').first().click();
await channelsPage.page.getByRole('option', {name: 'API Service'}).click();

await expect(dialog.getByText('API Type *')).toBeVisible();
await expect(dialog.getByRole('radio', {name: 'REST API'})).toBeVisible();
await expect(dialog.getByRole('radio', {name: 'GraphQL API'})).toBeVisible();
await expect(dialog.getByRole('radio', {name: 'gRPC Service'})).toBeVisible();
await expect(dialog.getByText('Database *')).toBeVisible();
await expect(dialog.getByText('Project Name *')).toBeVisible();
await expect(dialog.getByText('Platform')).not.toBeVisible();
await expect(dialog.getByText('Minimum OS Version')).not.toBeVisible();

// 10. Fill required fields and submit
await dialog.getByPlaceholder('Enter project name...').fill('Test Project');
await dialog.getByRole('radio', {name: 'REST API'}).click();

// Select PostgreSQL from Database dropdown
await dialog.locator('[class*="Select__control"], [class*="react-select__control"]').last().click();
await channelsPage.page.getByRole('option', {name: 'PostgreSQL'}).click();

await dialog.getByRole('button', {name: 'Create Project'}).click();
await expect(dialog).not.toBeVisible();

// 11. Verify response post in the channel
await expect(
channelsPage.centerView.container.locator('p').filter({hasText: 'api project: Test Project'}),
).toBeVisible();
});
Loading
Loading