Initial version of the new search interface (#27301)

* Initial version of the new search interface

* Fixing CI

* style tweaks

* tweaks to date picker in search

* change search input to button

* Addressing a lot of small problems

* Addressing current search visualization

* Fixing problem on filter autocompletion

* Adding some more fixes

* Tiny style ajustment

* Removing unnecessary slice call

* Adding search extensibility

* Improving the extensibility

* Fixing and refactoring a bit

* On clear click, clear the current search

* splitting components for simplicity

* tweaks to file ext search

* Addressing PR review comments and adding color to the extensions search icons

* Improving a bit the extension search

* Fixing CI

* Fixing some bugs

* Keep the focus on search input whenever we change the search type

* Adding SearchHint tests

* Adding search_box_type_selector tests

* Adding tests for the SearchBox component

* Adding tests for search box suggestions

* Adding SearchBoxInput tests

* Splitting extension suggestion component and provider

* ExtensionSuggestion tests

* Removing unneeded property

* Adding SearchBoxhints tests

* Adding tests for NewSearch component

* Adding tests for the extension suggestion provider

* Fixing linter errors

* Fixing tests

* Fixing linter errors

* Fixing linter errors

* Adding license check for plugins

* Addressing PR review comments

* Addressing PR review comments

* Addressing PR review comments

* Fixing tests

* Fixing some cypress tests

* More work around cypress tests for search

* Some accessibility changes

* more work on cypress tests

* fixing more cypress tests

* Fixing linter errors

* Fixing tests

* Fixing ctrl+f6 switching

* Fixing scrolling on small windows wheneve you are searching

* Improve editing in the middle of the search text

* Addressing some PR review comments

* Addressing some PR review comments

* Addressing some PR review comments

* Addressing some PR review comments

* Fixing tests and linter errors

* Fixingls tests and linter errors

* Fix type checks

* Clearer logic to render plugin or builtin suggestion

* Addressing PR review changes

* Addressing PR review changes

* Using selectors for plugin components

* Changing uppercase to lowercase on lists of components

* Updating tests

* Updating snapshots

* minor css tweaks

* minor css tweak

* Adding the search type and the clear button

* Fixing problem with the filetype selector

* fixing linter errors

* Some fixes

* More linter fixes

* Reverting prettier auto-formating

* Fixing CI

* Fixing CI

* Fixing chrome problem

* Fixing CI

* Addressing PR review comments

---------

Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
Co-authored-by: Christopher Speller <crspeller@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
Jesús Espino
2024-10-14 12:56:35 +02:00
коммит произвёл GitHub
родитель b7ccd745c8
Коммит 5f8bdba459
71 изменённых файлов: 2503 добавлений и 291 удалений

Просмотреть файл

@@ -52,7 +52,8 @@ describe('Verify Accessibility keyboard usability across different regions in th
postMessages(testChannel, otherUser, count);
// # Search for a term
cy.get('#searchBox').typeWithForce('hello').typeWithForce('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').typeWithForce('hello').typeWithForce('{enter}');
// # Change the focus to search results
cy.get('#searchContainer').within(() => {

Просмотреть файл

@@ -125,7 +125,8 @@ describe('Verify Quick Navigation support across different regions in the app',
it('MM-T1460_8 Verify Navigation Support in Search Results', () => {
// # Search for some text
cy.get('#searchBox').should('be.visible').type('hello {enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.visible').type('hello {enter}');
// # Change the focus to search results
cy.get('#searchContainer').within(() => {

Просмотреть файл

@@ -64,7 +64,8 @@ describe('Archived channels', () => {
// # Search for "Test archive reaction"
cy.get('body').type('{esc}');
cy.get('#searchBox').should('be.visible').type(messageText).type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.visible').type(messageText).type('{enter}');
// # Click on post dot menu so we can check for reaction icon
cy.clickPostDotMenu(postId, 'SEARCH');

Просмотреть файл

@@ -60,7 +60,8 @@ describe('archive tests while preventing viewing archived channels', () => {
cy.postMessage(getRandomId());
// # Search for the post from step 1')
cy.get('#searchBox').click().clear().type(`${messageText}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${messageText}{enter}`);
// * Post is returned by search, since it's not archived anymore
cy.get('#searchContainer').should('be.visible');
@@ -94,7 +95,8 @@ describe('archive tests while preventing viewing archived channels', () => {
cy.uiArchiveChannel();
// # Archive dialogue message reads "This will archive the channel from the team and make its contents inaccessible for all users" (Mobile dialogue makes no mention of the data will be accessible)
cy.get('#searchBox').click().clear().type(`${testArchivedMessage}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${testArchivedMessage}{enter}`);
// * Post is not returned by search
cy.get('#searchContainer').should('be.visible');
@@ -109,7 +111,8 @@ describe('archive tests while preventing viewing archived channels', () => {
cy.postMessage(messageText);
// # Search for the string of text from step 1
cy.get('#searchBox').click().clear().type(`${messageText}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${messageText}{enter}`);
// * Post is returned by search, since it's not archived anymore
cy.get('#searchContainer').should('be.visible');
@@ -127,7 +130,8 @@ describe('archive tests while preventing viewing archived channels', () => {
it('MM-T1710 archived channels are not listed on the "in:" autocomplete', () => {
// # Archive a channel and make a mental note of the channel name
// # Type "in:" and note the list of channels that appear
cy.get('#searchBox').click().clear().type(`in:${testChannel.name}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`in:${testChannel.name}`);
cy.findByTestId(testChannel.name).should('not.exist');
});
});

Просмотреть файл

@@ -41,10 +41,11 @@ describe('Leave an archived channel', () => {
cy.get('#channelInfoModalLabel span.icon__archive').should('not.exist');
// # Search for a post in an archived channel
cy.get('#searchBox').click().clear().type(`${testArchivedMessage}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${testArchivedMessage}{enter}`);
// # Open the archived channel by selecting Jump from search results and then selecting the link to move to the most recent posts in the channel
cy.get('#searchContainer').should('be.visible');
cy.uiGetSearchContainer().should('be.visible');
cy.get('a.search-item__jump').first().click();
@@ -111,10 +112,11 @@ describe('Leave an archived channel', () => {
const messageList = Array.from({length: 40}, (_, i) => `${i}. any - ${getRandomId()}`);
createArchivedChannel({prefix: 'archived-search-for'}, messageList).then(({name}) => {
// # Locate the post in a search
cy.get('#searchBox').click().clear().type(`${messageList[1]}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${messageList[1]}{enter}`);
// # Click jump to open an archive post in permalink view
cy.get('#searchContainer').should('be.visible');
cy.uiGetSearchContainer().should('be.visible');
cy.get('a.search-item__jump').first().click();
// * Archived channel is opened in permalink view

Просмотреть файл

@@ -96,7 +96,8 @@ describe('Leave an archived channel', () => {
cy.visit(previousChannel);
// # Search for content from an archived channel
cy.get('#searchBox').click().clear().type(`${messageD}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${messageD}{enter}`);
// # Open the channel from search results
cy.get('#searchContainer').should('be.visible');
@@ -107,7 +108,8 @@ describe('Leave an archived channel', () => {
cy.url().should('contain', `${testTeam.name}/channels/${archivedChannelD.name}`);
// # Search for content from a different archived channel
cy.get('#searchBox').click().clear().type(`${messageC}{enter}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(`${messageC}{enter}`);
// # Open the channel from search result by clicking Jump
cy.get('#searchContainer').should('be.visible').findByText('Jump').click().wait(TIMEOUTS.ONE_SEC);

Просмотреть файл

@@ -133,7 +133,8 @@ describe('Channel RHS', () => {
cy.postMessage(MESSAGES.SMALL);
// # Enter the search terms and hit enter to start the search
cy.get('#searchBox').clear().type(MESSAGES.TINY).type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type(MESSAGES.TINY).type('{enter}');
// * Verify that the search results is opened in RHS
verifyRHSisOpenAndHasTitle('Search Results');

Просмотреть файл

@@ -78,15 +78,18 @@ describe('Verify Accessibility Support in different input fields', () => {
});
}
cy.uiGetSearchContainer().click();
// * Verify Accessibility support in search input
cy.get('#searchBox').should('have.attr', 'aria-describedby', 'searchbar-help-popup').and('have.attr', 'aria-label', 'Search').focus();
cy.get('#searchbar-help-popup').should('be.visible').and('have.attr', 'role', 'tooltip');
cy.uiGetSearchBox().should('have.attr', 'aria-describedby', 'searchHints').and('have.attr', 'aria-label', 'Search');
cy.uiGetSearchBox().find('input').focus();
cy.get('#searchHints').should('be.visible');
// # Ensure User list is cached once in UI
cy.get('#searchBox').type('from:').wait(TIMEOUTS.FIVE_SEC);
cy.uiGetSearchBox().find('input').type('from:').wait(TIMEOUTS.FIVE_SEC);
// # Trigger the user autocomplete again
cy.get('#searchBox').clear().type('from:').wait(TIMEOUTS.FIVE_SEC).type('{downarrow}{downarrow}');
cy.uiGetSearchBox().find('input').clear().type('from:').wait(TIMEOUTS.FIVE_SEC).type('{downarrow}{downarrow}');
// * Verify Accessibility Support in search autocomplete
verifySearchAutocomplete(2);
@@ -100,10 +103,10 @@ describe('Verify Accessibility Support in different input fields', () => {
verifySearchAutocomplete(3);
// # Type the in: filter and ensure channel list is cached once
cy.get('#searchBox').clear().type('in:').wait(TIMEOUTS.FIVE_SEC);
cy.uiGetSearchBox().find('input').clear().type('in:').wait(TIMEOUTS.FIVE_SEC);
// # Trigger the channel autocomplete again
cy.get('#searchBox').clear().type('in:').wait(TIMEOUTS.FIVE_SEC).type('{downarrow}{downarrow}');
cy.uiGetSearchBox().find('input').clear().type('in:').wait(TIMEOUTS.FIVE_SEC).type('{downarrow}{downarrow}');
// * Verify Accessibility Support in search autocomplete
verifySearchAutocomplete(2, 'channel');
@@ -287,7 +290,7 @@ function getUserMentionAriaLabel(displayName) {
}
function verifySearchAutocomplete(index, type = 'user') {
cy.get('#search-autocomplete__popover').find('.suggestion-list__item').eq(index).should('be.visible').and('have.class', 'suggestion--selected').within((el) => {
cy.uiGetSearchBox().find('.suggestion-list__item').eq(index).should('be.visible').and('have.class', 'suggestion--selected').within((el) => {
if (type === 'user') {
cy.get('.suggestion-list__ellipsis').invoke('text').then((text) => {
const usernameLength = 12;

Просмотреть файл

@@ -78,10 +78,10 @@ describe('Guest Account - Guest User Experience', () => {
cy.sendDirectMessageToUser(guestUser, 'hello');
// # Search for the Guest User
cy.get('#searchBox').wait(TIMEOUTS.FIVE_SEC).type(`in:${guestUser.username}`);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').wait(TIMEOUTS.FIVE_SEC).type(`in:${guestUser.username}`);
// * Verify Guest Badge is not displayed at Search auto-complete
cy.get('#search-autocomplete__popover').should('be.visible');
cy.contains('.suggestion-list__item', guestUser.username).should('be.visible').within(($el) => {
cy.wrap($el).find('.Tag').should('not.exist');
});

Просмотреть файл

@@ -212,10 +212,10 @@ describe('Verify Guest User Identification in different screens', () => {
it('Verify Guest Badge not displayed in Search Autocomplete', () => {
// # Search for the Guest User
cy.get('#searchBox').type('from:');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').type('from:');
// * Verify Guest Badge is not displayed at Search auto-complete
cy.get('#search-autocomplete__popover').should('be.visible');
cy.contains('.suggestion-list__item', guestUser.username).scrollIntoView().should('be.visible').within(($el) => {
cy.wrap($el).find('.Tag').should('not.exist');
});

Просмотреть файл

@@ -67,7 +67,8 @@ describe('Incoming webhook', () => {
cy.postIncomingWebhook({url: incomingWebhook.url, data: payload});
cy.get('#searchBox').
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').
wait(TIMEOUTS.HALF_SEC).
typeWithForce('findme').
typeWithForce('{enter}');

Просмотреть файл

@@ -66,13 +66,13 @@ describe('Upload Files - Settings', () => {
});
// # Click on the search input
cy.uiGetSearchBox().click();
cy.uiGetSearchContainer().click();
// * Verify search hint does not have File button
cy.get('#searchbar-help-popup').find('.search-hint__search-type-selector button > .icon-file-text-outline').should('not.exist');
cy.get('#searchHints').find('.search-hint__search-type-selector button > .icon-file-text-outline').should('not.exist');
// # Search for posts
cy.get('#searchBox').type('sample').type('{enter}');
cy.uiGetSearchBox().find('input').type('sample').type('{enter}');
// * Verify search results do not have File button
cy.get('.files-tab').should('not.exist');

Просмотреть файл

@@ -42,7 +42,8 @@ describe('Keyboard Shortcuts', () => {
it('MM-T1250 CTRL/CMD+SHIFT+L - Set focus to center channel message box (with SEARCH RHS open)', () => {
// # Search
cy.get('#searchBox').click().type('test{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').type('test{enter}');
// * Wait for the RHS to open and the search results to appear
cy.contains('.sidebar--right__header', 'Search Results').should('be.visible');

Просмотреть файл

@@ -370,11 +370,12 @@ describe('Keyboard Shortcuts', () => {
it('MM-T1248 - CTRL/CMD+SHIFT+L - Set focus to center channel message box', () => {
// # Open search box to change focus
cy.get('#searchBox').click().should('be.focused').then(() => {
// # Type CTRL/CMD+SHIFT+L
cy.get('body').cmdOrCtrlShortcut('{shift}L');
cy.uiGetPostTextBox().should('be.focused');
});
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.focused');
// # Type CTRL/CMD+SHIFT+L
cy.get('body').cmdOrCtrlShortcut('{shift}L');
cy.uiGetPostTextBox().should('be.focused');
// # Post a message and open RHS
const message = `hello${Date.now()}`;

Просмотреть файл

@@ -718,7 +718,8 @@ describe('Messaging', () => {
cy.getLastPostId().then((postId) => {
// # Search for the posted message
cy.get('#searchBox').should('be.visible').type(messageX).type('{enter}').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.visible').type(messageX).type('{enter}').wait(TIMEOUTS.HALF_SEC);
// # Click on post dot menu so we can edit
cy.clickPostDotMenu(postId, 'SEARCH');

Просмотреть файл

@@ -54,7 +54,8 @@ describe('Message permalink', () => {
}
// # Search for a message in the current channel
cy.get('#searchBox').clear().type('in:town-square').type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type('in:town-square').wait(TIMEOUTS.HALF_SEC).type('{enter}{enter}');
// # Jump to first permalink view (most recent message)
cy.get('.search-item__jump').first().click();
@@ -71,7 +72,8 @@ describe('Message permalink', () => {
});
// # Search for a message in the current channel
cy.get('#searchBox').clear().type('in:town-square').type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').clear().type('in:town-square').wait(TIMEOUTS.HALF_SEC).type('{enter}{enter}');
// # Jump to first permalink view (most recent message)
cy.get('.search-item__jump').first().click();

Просмотреть файл

@@ -40,7 +40,8 @@ describe('Permalink message edit', () => {
cy.postMessage(searchWord);
// # Search for searchWord
cy.get('#searchBox').type(searchWord).type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').type(searchWord).type('{enter}');
// # Jump to permalink view
cy.get('.search-item__jump').first().click();
@@ -69,7 +70,8 @@ describe('Permalink message edit', () => {
cy.postMessage('hello');
// # Find searchWord and verify edited post
cy.get('#searchBox').should('be.visible').type(searchWord).type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.visible').type(searchWord).type('{enter}');
cy.get('.search-item__jump').first().click();
// # Check if url include the permalink

Просмотреть файл

@@ -186,7 +186,8 @@ describe('Post PreHeader', () => {
});
// # Search for the channel.
cy.get('#searchBox').type('test both pinned and saved {enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').type('test both pinned and saved {enter}');
// * Check that the post pre-header has both pinned and saved links in RHS search results
cy.get('#searchContainer').should('be.visible').within(() => {

Просмотреть файл

@@ -67,8 +67,10 @@ describe('Notifications', () => {
});
// # Enter "in:town-square" in the search bar and hit ENTER
cy.get('#searchBox').
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').
typeWithForce('in:town-square').
wait(TIMEOUTS.HALF_SEC).
typeWithForce('{enter}').
typeWithForce('{enter}');

Просмотреть файл

@@ -25,11 +25,13 @@ describe('Search', () => {
// * X should not be visible on empty input
cy.uiGetSearchContainer().find('.input-clear-x').should('not.exist');
cy.uiGetSearchContainer().click();
// # Write something on the input
cy.uiGetSearchBox().clear().type('abc');
cy.uiGetSearchBox().find('input').clear().type('abc');
// * The input should contain what we wrote
cy.uiGetSearchBox().should('have.value', 'abc');
cy.uiGetSearchBox().find('input').should('have.value', 'abc');
// * The X should be visible
// # Then click X to clear the input field
@@ -50,7 +52,7 @@ describe('Search', () => {
// * Verify search input field exists and not search button, as inputs contains placeholder not buttons/icons
// and then type in a search text
cy.uiGetSearchBox().click().wait(TIMEOUTS.HALF_SEC).type(searchText);
cy.uiGetSearchBox().click().wait(TIMEOUTS.HALF_SEC).type(searchText + '{enter}');
// # Click on the pinned post button from the header
cy.uiGetChannelPinButton().click();

Просмотреть файл

@@ -29,9 +29,11 @@ describe('Search', () => {
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().
type(`${term}{enter}`).
wait(TIMEOUTS.ONE_SEC).
clear();
cy.get('#searchbar-help-popup').should('be.visible');
wait(TIMEOUTS.ONE_SEC);
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().clear();
cy.get('#searchHints').should('be.visible');
cy.uiGetSearchContainer().type('{esc}');
// # Verify the Search side bar opens up
@@ -43,13 +45,17 @@ describe('Search', () => {
cy.uiGetRHS({visible: false});
// # Verify that the cleared search text does not appear on the search box
cy.uiGetSearchBox().should('be.empty');
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').should('be.empty');
cy.uiGetSearchContainer().type('{esc}');
// # Click the pin icon to open the pinned messages RHS
cy.uiGetChannelPinButton().click();
cy.uiGetRHS().should('contain', 'Pinned messages');
// # Verify that the Search term input box is still cleared and search term does not reappear when RHS opens
cy.uiGetSearchBox().and('be.empty');
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').and('be.empty');
cy.uiGetSearchContainer().type('{esc}');
});
});

Просмотреть файл

@@ -36,8 +36,11 @@ describe('Search', () => {
// # Post a message
cy.postMessage(testSearch);
cy.uiGetSearchContainer().click();
// # Search the world 'hello' that is generated by /test command
cy.get('#searchBox').click().type('hello{enter}').wait(TIMEOUTS.HALF_SEC).should('have.value', 'hello');
cy.uiGetSearchBox().find('input').type('hello{enter}').wait(TIMEOUTS.HALF_SEC);
cy.get('#search-items-container span').should('contain.text', 'hello');
// # RHS should be visible with search results
cy.get('#search-items-container').should('be.visible');
@@ -52,14 +55,10 @@ describe('Search', () => {
// # Jump to conversation
cy.wrap($result).get('a.search-item__jump').first().click();
// * Search query clear icon is still present
cy.get('.input-clear.visible').should('be.visible');
cy.uiGetSearchContainer().click();
// # Hover search query clear icon
cy.get('.input-clear-x').first().trigger('mouseover', {force: true}).then(($span) => {
// * Assert that tooltip has shown
cy.wrap($span).should('have.attr', 'aria-describedby', 'InputClearTooltip');
// # Click the clear query icon
cy.wrap($span).click({force: true});

Просмотреть файл

@@ -37,23 +37,23 @@ describe('Search', () => {
// # Post a message
cy.postMessage(searchWord);
cy.uiGetSearchContainer().click();
// * Search word in searchBox and validate searchWord
cy.get('#searchBox').click().type(searchWord + '{enter}').should('have.value', searchWord);
cy.uiGetSearchBox().find('input').type(searchWord + '{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('have.value', searchWord);
// # Click on "x" displayed on searchbox
cy.get('#searchbarContainer').should('be.visible').within(() => {
cy.get('#searchFormContainer').find('.input-clear-x').wait(TIMEOUTS.ONE_SEC).click({force: true});
cy.get('#searchbar-help-popup').should('be.visible');
cy.get('#searchBox').type('{esc}');
});
cy.uiGetSearchBox().find('.input-clear-x').wait(TIMEOUTS.ONE_SEC).click({force: true});
cy.uiGetSearchBox().find('#searchHints').should('be.visible');
cy.uiGetSearchBox().type('{esc}');
// # RHS should be visible with search results
cy.get('#search-items-container').should('be.visible');
// # Click on searchbox
cy.get('#searchbarContainer').should('be.visible').within(() => {
cy.get('#searchBox').click();
});
cy.uiGetSearchContainer().click();
assertSearchHintFilesOrMessages();
});
@@ -74,29 +74,28 @@ describe('Search', () => {
// # Visit town-square.
cy.visit(`/${testTeam.name}/channels/town-square`);
cy.uiGetSearchContainer().click();
// # Search for posts from that user
cy.get('#searchBox').click().type(testSearch, {force: true});
cy.uiGetSearchBox().find('input').type(testSearch, {force: true}).wait(TIMEOUTS.HALF_SEC);
// # Select user from suggestion list
cy.contains('.suggestion-list__item', `@${testUser.username}`).scrollIntoView().click({force: true});
// # Verify that search box has the updated query
cy.get('#searchBox').should('have.value', `FROM:${testUser.username} `);
cy.uiGetSearchBox().find('input').should('have.value', `FROM:${testUser.username} `);
// # Perform search
cy.get('#searchBox').click().type('{enter}').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().find('input').type('{enter}').wait(TIMEOUTS.HALF_SEC);
// * Assert that RHS should be visible with search results
cy.get('#search-items-container').should('be.visible');
// * Search query clear icon is still present
cy.get('.input-clear.visible').should('be.visible');
cy.uiGetSearchContainer().click();
// # Hover search query clear icon
cy.get('.input-clear-x').first().trigger('mouseover', {force: true}).then(($span) => {
// * Assert that tooltip has shown
cy.wrap($span).should('have.attr', 'aria-describedby', 'InputClearTooltip');
// # Click the clear query icon
cy.wrap($span).click({force: true});
@@ -111,15 +110,13 @@ describe('Search', () => {
cy.postMessage('hello');
// # Click on searchbox
cy.get('#searchbarContainer').should('be.visible').within(() => {
cy.get('input#searchBox').should('be.visible').click();
});
cy.uiGetSearchContainer().should('be.visible').click();
// * Check the contents in search options
assertSearchHintFilesOrMessages();
// # Search for search term in:
cy.get('#searchBox').click().type('in:');
cy.uiGetSearchBox().find('input').type('in:');
// # Select option from suggestion list
cy.get('.suggestion-list__item').first().click({force: true});
@@ -131,31 +128,31 @@ describe('Search', () => {
cy.get('.input-clear-x').first().click({force: true}).wait(TIMEOUTS.HALF_SEC);
// # Search for search term in:town-square{space}
cy.get('#searchBox').click().type('in:town-square ').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().find('input').type('in:town-square ').wait(TIMEOUTS.HALF_SEC);
// * Check the hint contents are now visible
assertSearchHint();
// # Clear search box
cy.get('.input-clear-x').first().click({force: true}).wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().get('.input-clear-x').first().click({force: true}).wait(TIMEOUTS.HALF_SEC);
// # Search for search term in:town-square{enter}
cy.get('#searchBox').click().type('in:town-square').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().find('input').type('in:town-square').wait(TIMEOUTS.HALF_SEC);
// * Assert that channel name displays appropriately
cy.get('.suggestion-list__item').first().should('contain.text', 'Town Square~town-square');
// # Press enter to register search term
cy.get('#searchBox').click().type('{enter}');
cy.uiGetSearchBox().find('input').type('{enter}');
// * Check the hint contents are now visible
assertSearchHint();
// * Assert that searchBox now includes a trailing space
cy.get('#searchBox').should('have.value', 'in:town-square ');
cy.uiGetSearchBox().find('input').should('have.value', 'in:town-square ');
// # Perform the search
cy.get('#searchBox').click().type('{enter}').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().find('input').type('{enter}').wait(TIMEOUTS.HALF_SEC);
// * Assert autocomplete list is gone
cy.get('.suggestion-list__item').should('not.exist');
@@ -167,8 +164,10 @@ describe('Search', () => {
// # Post message
cy.postMessage(testMessage);
cy.uiGetSearchContainer().click();
// # Search for `Hell*`
cy.get('input#searchBox').click().type('Hell*{enter}').wait(TIMEOUTS.HALF_SEC);
cy.uiGetSearchBox().find('input').type('Hell*{enter}').wait(TIMEOUTS.HALF_SEC);
// # RHS should be visible with search results
cy.get('#search-items-container').should('be.visible');
@@ -180,22 +179,9 @@ describe('Search', () => {
});
const assertSearchHintFilesOrMessages = () => {
cy.get('#searchbar-help-popup').should('be.visible').within(() => {
cy.get('div span').first().should('have.text', 'What are you searching for?');
cy.get('div button:first-child span').first().should('have.text', 'Messages');
cy.get('div button:last-child span').first().should('have.text', 'Files');
});
cy.get('#searchHints').should('be.visible');
};
const assertSearchHint = () => {
cy.get('#searchbar-help-popup').should('be.visible').within(() => {
cy.get('div span').first().should('have.text', 'Search options');
cy.get('div ul li').first().should('have.text', 'From:Messages from a user');
cy.get('div ul li').eq(1).should('have.text', 'In:Messages in a channel');
cy.get('div ul li').eq(2).should('have.text', 'On:Messages on a date');
cy.get('div ul li').eq(3).should('have.text', 'Before:Messages before a date');
cy.get('div ul li').eq(4).should('have.text', 'After:Messages after a date');
cy.get('div ul li').eq(5).should('have.text', '—Exclude search terms');
cy.get('div ul li').last().should('have.text', '""Messages with phrases');
});
cy.get('#searchHints').should('be.visible');
};

Просмотреть файл

@@ -36,7 +36,8 @@ describe('Search', () => {
cy.postMessage(message);
// # Search for "apple"
cy.get('#searchBox').should('be.visible').type(apple).type('{enter}');
cy.uiGetSearchContainer().click();
cy.uiGetSearchBox().find('input').should('be.visible').type(apple).type('{enter}');
// # Get last postId
cy.getLastPostId().as('lastPostId');
@@ -46,8 +47,10 @@ describe('Search', () => {
verifySearchResult(1, postId, message, apple);
});
cy.uiGetSearchContainer().click();
// * Type banana on search box but don't hit search
cy.get('#searchBox').clear({force: true}).type(banana, {force: true});
cy.uiGetSearchBox().find('input').clear({force: true}).type(banana, {force: true});
// * Search result should not change and remain as one result with highlight still on apple
cy.get('@lastPostId').then((postId) => {

Просмотреть файл

@@ -1,70 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @search
describe('Search', () => {
before(() => {
// # Login as test user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T4945_1 - Search bar popup should be visible when focus changes to one of its buttons', () => {
//# clicks on the search box
cy.uiGetSearchBox().click();
//* search bar popup should be visibl
cy.get('#searchbar-help-popup').should('be.visible');
//# moves the focus to the next button (in this case Messages)
cy.focused().tab();
//* search bar popup should be visible
cy.get('#searchbar-help-popup').should('be.visible');
});
it('MM-T4945_2 - Search bar popup should be hidden when focus is out of search bar items', () => {
//# clicks on the search box
cy.uiGetSearchBox().click();
//* search bar popup should be visibl
cy.get('#searchbar-help-popup').should('be.visible');
//# press tab three times to move focus out of the search bar componment
cy.focused().tab();
cy.focused().tab();
cy.focused().tab();
//* now the popup should be closed
cy.get('#searchbar-help-popup').should('not.be.visible');
});
it('MM-T4945_3 - Search bar popup should be open when focus back to search box', () => {
//# clicks on the search box
cy.uiGetSearchBox().click();
//* search bar popup should be visibl
cy.get('#searchbar-help-popup').should('be.visible');
//# moves the focus to the next button (in this case Messages)
cy.focused().tab();
//* search bar popup should be visible
cy.get('#searchbar-help-popup').should('be.visible');
//# moves the focus back to the search box
cy.focused().tab({shift: true});
//* search bar popup should still be visible
cy.get('#searchbar-help-popup').should('be.visible');
});
});

Просмотреть файл

@@ -51,25 +51,24 @@ describe('Search', () => {
// # Post a message
cy.postMessage(message);
cy.uiGetSearchContainer().should('be.visible').click();
//# Type "in:" text in search input
cy.get('#searchBox').type('in:');
cy.uiGetSearchBox().find('input').type('in:');
const sortedUsernames = groupMembers.
map((member) => member.username).
sort((a, b) => a.localeCompare(b, 'en', {numeric: true}));
//# Search group members in the menu
cy.get('#search-autocomplete__popover').should('be.visible').within(() => {
cy.findAllByTestId('listItem').contains(sortedUsernames.join(',')).click();
});
cy.uiGetSearchBox().find('.suggestion-list__main').contains(sortedUsernames.join(',')).click();
//# Press enter to select
cy.get('#searchBox').type('{enter}');
cy.uiGetSearchBox().find('input').type('{enter}');
//# Search for the message
cy.get('#searchbarContainer').should('be.visible').within(() => {
cy.get('#searchBox').clear().type(`${message}{enter}`);
});
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').clear().type(`${message}{enter}`);
// * Should return exactly one result from the group channel and matches the message
cy.findAllByTestId('search-item-container').should('be.visible').and('have.length', 1).within(() => {
@@ -89,25 +88,20 @@ describe('Search', () => {
cy.get('.post-image__thumbnail').should('be.visible');
cy.uiGetPostTextBox().clear().type('{enter}');
cy.uiGetSearchContainer().should('be.visible').click();
//# Type "in:" text in search input
cy.get('#searchBox').type('in:');
cy.uiGetSearchBox().find('input').type('in:');
const sortedUsernames = groupMembers.
map((member) => member.username).
sort((a, b) => a.localeCompare(b, 'en', {numeric: true}));
//# Search group members in the menu
cy.get('#search-autocomplete__popover').should('be.visible').within(() => {
cy.findAllByTestId('listItem').contains(sortedUsernames.join(',')).click();
});
//# Press enter to select
cy.get('#searchBox').type('{enter}');
cy.uiGetSearchBox().find('.suggestion-list__main').contains(sortedUsernames.join(',')).click();
//# Search for the message
cy.get('#searchbarContainer').should('be.visible').within(() => {
cy.get('#searchBox').type(' word-file{enter}');
});
cy.uiGetSearchBox().find('input').type('word-file{enter}');
// # Click the files tab
cy.get('.files-tab').should('be.visible').click();

Просмотреть файл

@@ -9,6 +9,8 @@
// Group: @channels @search @smoke @filesearch
import * as TIMEOUTS from '../../../fixtures/timeouts';
/**
* create new DM channel
* @param {String} text - DM channel name
@@ -19,7 +21,7 @@ function createNewDMChannel(channelname) {
cy.get('#selectItems input').typeWithForce(channelname);
cy.contains('.more-modal__description', channelname).click({force: true});
cy.get('#saveItems').click();
cy.get('#saveItems').click().wait(TIMEOUTS.ONE_SEC);
}
describe('Search in DMs', () => {
@@ -57,17 +59,19 @@ describe('Search in DMs', () => {
cy.get('.post-image__thumbnail').should('be.visible');
cy.uiGetPostTextBox().clear().type('{enter}');
cy.uiGetSearchContainer().should('be.visible').click();
// # Type `in:` in searchbox
cy.get('#searchBox').type('in:');
cy.uiGetSearchBox().find('input').type('in:');
// # Select user from suggestion list
cy.contains('.suggestion-list__item', `@${otherUser.username}`).scrollIntoView().click();
// # Validate searchbox contains the username
cy.get('#searchBox').should('have.value', 'in:@' + otherUser.username + ' ');
cy.uiGetSearchBox().find('input').should('have.value', 'in:@' + otherUser.username + ' ');
// # Press Enter in searchbox
cy.get('#searchBox').type('word-file.doc').type('{enter}');
cy.uiGetSearchBox().find('input').type('word-file').type('{enter}');
// # Click the files tab
cy.get('.files-tab').should('be.visible').click();

Просмотреть файл

@@ -59,16 +59,17 @@ describe('Search in DMs', () => {
cy.postMessage(message);
// # Type `in:` in searchbox
cy.get('#searchBox').type('in:');
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').type('in:');
// # Select user from suggestion list
cy.contains('.suggestion-list__item', `@${otherUser.username}`).scrollIntoView().click();
// # Validate searchbox contains the username
cy.get('#searchBox').should('have.value', 'in:@' + otherUser.username + ' ');
cy.uiGetSearchBox().find('input').should('have.value', 'in:@' + otherUser.username + ' ');
// # Press Enter in searchbox
cy.get('#searchBox').type(message).type('{enter}');
cy.uiGetSearchBox().find('input').type(message).type('{enter}');
// # Search message in each filtered result
cy.get('#search-items-container').find('.search-highlight').each(($el) => {

Просмотреть файл

@@ -1,58 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @autocomplete @search
describe('Autocomplete in the search box - scrolling', () => {
const usersCount = 15;
const timestamp = Date.now();
before(() => {
// # Create new team for tests
cy.apiCreateTeam(`search-${timestamp}`, `search-${timestamp}`).then(({team}) => {
// # Create pool of users for tests
for (let i = 0; i < usersCount; i++) {
cy.apiCreateUser().then(({user}) => {
cy.apiAddUserToTeam(team.id, user.id);
});
}
cy.visit(`/${team.name}/channels/off-topic`);
// # Post a new message to ensure page fully rendered before acting into the searchBox
cy.postMessage('hello');
});
});
it('MM-T4084 correctly scrolls when the user navigates through options with the keyboard', () => {
// # Type into the searchBox to show list of users
cy.get('#searchBox').type('from:');
cy.get('#search-autocomplete__popover .suggestion-list__item').first().as('firstItem');
cy.get('#search-autocomplete__popover .suggestion-list__item').last().as('lastItem');
// * Check that list is scrolled to top
cy.get('@firstItem').should('be.visible');
cy.get('@lastItem').should('not.be.visible');
// # Move to bottom of the list using keyboard
cy.get('body').type('{downarrow}'.repeat(usersCount));
// * Check that list is scrolled to bottom
cy.get('@firstItem').should('not.be.visible');
cy.get('@lastItem').should('be.visible');
// # Move to top of the list using keyboard
cy.get('body').type('{uparrow}'.repeat(usersCount));
// * Check that list is scrolled to top
cy.get('@firstItem').should('be.visible');
cy.get('@lastItem').should('not.be.visible');
});
});

Просмотреть файл

@@ -12,13 +12,13 @@ import {getRandomId} from '../../../utils';
export function searchAndValidate(query, expectedResults = []) {
// # Enter in search query, and hit enter
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().
clear().
wait(TIMEOUTS.HALF_SEC).
type(query).
wait(TIMEOUTS.HALF_SEC).
type('{enter}').
should('be.empty');
type('{enter}');
cy.get('#loadingSpinner').should('not.exist');

Просмотреть файл

@@ -53,49 +53,53 @@ describe('Search Date Filter', () => {
const today = Cypress.dayjs().format('YYYY-MM-DD');
// # Type before: in search field
cy.get('#searchBox').clear().type('before:');
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').clear().type('before:');
// * Day picker should be visible
cy.get('.DayPicker').
cy.get('.rdp').
as('dayPicker').
should('be.visible');
// # Select today's day
cy.get('@dayPicker').
find('.DayPicker-Day--today').click();
find('.rdp-day_today').click();
cy.get('@dayPicker').should('not.exist');
// * Verify date picker output gets put into field as expected date
cy.get('#searchBox').should('have.value', `before:${today} `);
cy.uiGetSearchBox().find('input').should('have.value', `before:${today} `);
// # Click "x" to the right of the search term
cy.get('#searchFormContainer').find('.input-clear-x').click({force: true});
cy.uiGetSearchBox().find('.input-clear-x').click({force: true});
// * The "x" to clear the search query has disappeared
cy.get('#searchBox').should('have.value', '');
cy.uiGetSearchBox().find('input').should('have.value', '');
cy.uiGetSearchContainer().should('be.visible').click();
});
it('MM-T3997 Backspace after last character of filter makes calendar reappear', () => {
const today = Cypress.dayjs().format('YYYY-MM-DD');
// # Type before: in search field
cy.get('#searchBox').clear().type('before:');
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').clear().type('before:');
// * Date picker should be visible
cy.get('.DayPicker').
cy.get('.rdp').
as('dayPicker').
should('be.visible');
// # Select today's day
cy.get('@dayPicker').
find('.DayPicker-Day--today').click();
find('.rdp-day_today').click();
// * Date picker should disappear
cy.get('@dayPicker').should('not.exist');
// # Hit backspace with focus right after the date
cy.get('#searchBox').
cy.uiGetSearchBox().find('input').
should('have.value', `before:${today} `).
focus().
type('{backspace}');
@@ -122,7 +126,8 @@ describe('Search Date Filter', () => {
const queryString = `on:${Cypress.dayjs().format('YYYY-MM-DD')} ${commonText}`;
// * Filter can be removed with keyboard
cy.get('#searchBox').
cy.uiGetSearchContainer().should('be.visible').click();
cy.uiGetSearchBox().find('input').
clear().
wait(TIMEOUTS.HALF_SEC).
type(queryString).
@@ -130,10 +135,10 @@ describe('Search Date Filter', () => {
should('have.value', '');
// # Enter query to search box and then click "x" to the right of the search term
cy.get('#searchBox').clear().wait(TIMEOUTS.HALF_SEC).type(queryString);
cy.get('#searchFormContainer').find('.input-clear-x').click({force: true});
cy.uiGetSearchBox().find('input').clear().wait(TIMEOUTS.HALF_SEC).type(queryString);
cy.uiGetSearchBox().find('.input-clear-x').click({force: true});
// * The "x" to clear the search query has disappeared
cy.get('#searchBox').should('have.value', '');
cy.uiGetSearchBox().find('input').should('have.value', '');
});
});

Просмотреть файл

@@ -5,7 +5,8 @@ import {ChainableT} from 'tests/types';
function uiSearchPosts(searchTerm: string) {
// # Enter the search terms and hit enter to start the search
cy.get('#searchBox').clear().type(searchTerm).type('{enter}');
cy.get('#searchFormContainer').should('be.visible').click();
cy.get('#searchBox').find('input').clear().type(searchTerm).type('{enter}');
// * Wait for the RHS to open and the search results to appear
cy.contains('.sidebar--right__header', 'Search Results').should('be.visible');