diff --git a/e2e/content-services/search_multiselect.e2e.ts b/e2e/content-services/search_multiselect.e2e.ts
new file mode 100644
index 0000000000..6fb16d51f1
--- /dev/null
+++ b/e2e/content-services/search_multiselect.e2e.ts
@@ -0,0 +1,253 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import TestConfig = require('../test.config');
+import AlfrescoApi = require('alfresco-js-api-node');
+
+import Util = require('../util/util');
+import resources = require('../util/resources');
+import CONSTANTS = require('../util/constants');
+import { UploadActions } from '../actions/ACS/upload.actions';
+
+import LoginPage = require('../pages/adf/loginPage');
+import SearchDialog = require('../pages/adf/dialog/searchDialog');
+import SearchResultPage = require('../pages/adf/searchResultsPage');
+import SearchFiltersPage = require('../pages/adf/searchFiltersPage');
+
+import AcsUserModel = require('../models/ACS/acsUserModel');
+import FileModel = require('../models/ACS/fileModel');
+
+describe('Search Component - Multi-Select Facet', () => {
+ let loginPage = new LoginPage();
+ let searchDialog = new SearchDialog();
+ let searchResultsPage = new SearchResultPage();
+ let uploadActions = new UploadActions();
+ let searchFiltersPage = new SearchFiltersPage();
+ let site;
+
+ beforeAll(() => {
+ this.alfrescoJsApi = new AlfrescoApi({
+ provider: 'ECM',
+ hostEcm: TestConfig.adf.url
+ });
+ });
+
+ describe('', () => {
+ let jpgFile, jpgFileSite, txtFile, txtFileSite;
+ let acsUser = new AcsUserModel();
+
+ let jpgFileInfo = new FileModel({
+ 'location': resources.Files.ADF_DOCUMENTS.JPG.file_location,
+ 'name': resources.Files.ADF_DOCUMENTS.JPG.file_name
+ });
+ let txtFileInfo = new FileModel({
+ 'location': resources.Files.ADF_DOCUMENTS.TXT_0B.file_location,
+ 'name': resources.Files.ADF_DOCUMENTS.TXT_0B.file_name
+ });
+
+ beforeAll(async (done) => {
+ await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword);
+
+ await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser);
+
+ await this.alfrescoJsApi.login(acsUser.id, acsUser.password);
+
+ site = await this.alfrescoJsApi.core.sitesApi.createSite({
+ title: Util.generateRandomString(8),
+ visibility: 'PUBLIC'
+ });
+
+ jpgFile = await uploadActions.uploadFile(this.alfrescoJsApi, jpgFileInfo.location, jpgFileInfo.name, '-my-');
+ await browser.driver.sleep(5000);
+
+ jpgFileSite = await uploadActions.uploadFile(this.alfrescoJsApi, jpgFileInfo.location, jpgFileInfo.name, site.entry.guid);
+ await browser.driver.sleep(5000);
+
+ txtFile = await uploadActions.uploadFile(this.alfrescoJsApi, txtFileInfo.location, txtFileInfo.name, '-my-');
+ await browser.driver.sleep(5000);
+
+ txtFileSite = await uploadActions.uploadFile(this.alfrescoJsApi, txtFileInfo.location, txtFileInfo.name, site.entry.guid);
+ await browser.driver.sleep(5000);
+
+ loginPage.loginToContentServicesUsingUserModel(acsUser);
+
+ searchDialog.checkSearchIconIsVisible();
+ searchDialog.clickOnSearchIcon();
+ searchDialog.enterTextAndPressEnter('file');
+
+ searchFiltersPage.checkSearchFiltersIsDisplayed();
+ searchFiltersPage.filterByCreator(acsUser.firstName, acsUser.lastName);
+
+ done();
+ });
+
+ afterAll(async (done) => {
+ Promise.all([
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, jpgFile.entry.id),
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, jpgFileSite.entry.id),
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, txtFile.entry.id),
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, txtFileSite.entry.id)
+ ]);
+ done();
+ });
+
+ it('[C280054] Multiple items can be selected from a search facet filter', () => {
+ searchFiltersPage.filterByFileType("Plain Text");
+
+ expect(searchResultsPage.numberOfResultsDisplayed()).toBe(2);
+ searchResultsPage.checkContentIsDisplayed(txtFile.entry.name);
+ searchResultsPage.checkContentIsDisplayed(txtFileSite.entry.name);
+
+ searchFiltersPage.filterByFileType("JPEG Image");
+
+ expect(searchResultsPage.numberOfResultsDisplayed()).toBe(4);
+ searchResultsPage.checkContentIsDisplayed(txtFile.entry.name);
+ searchResultsPage.checkContentIsDisplayed(txtFileSite.entry.name);
+ searchResultsPage.checkContentIsDisplayed(jpgFile.entry.name);
+ searchResultsPage.checkContentIsDisplayed(jpgFileSite.entry.name);
+ });
+ });
+
+ describe('', () => {
+ let jpgFile, txtFile;
+ let userUploadingTxt = new AcsUserModel();
+ let userUploadingImg = new AcsUserModel();
+
+ let jpgFileInfo = new FileModel({
+ 'location': resources.Files.ADF_DOCUMENTS.JPG.file_location,
+ 'name': resources.Files.ADF_DOCUMENTS.JPG.file_name
+ });
+ let txtFileInfo = new FileModel({
+ 'location': resources.Files.ADF_DOCUMENTS.TXT_0B.file_location,
+ 'name': resources.Files.ADF_DOCUMENTS.TXT_0B.file_name
+ });
+
+ beforeAll(async (done) => {
+ await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword);
+
+ await this.alfrescoJsApi.core.peopleApi.addPerson(userUploadingTxt);
+ await this.alfrescoJsApi.core.peopleApi.addPerson(userUploadingImg);
+
+ await this.alfrescoJsApi.login(userUploadingTxt.id, userUploadingTxt.password);
+
+ site = await this.alfrescoJsApi.core.sitesApi.createSite({
+ title: Util.generateRandomString(8),
+ visibility: 'PUBLIC'
+ });
+
+ await this.alfrescoJsApi.core.sitesApi.addSiteMember(site.entry.id, {
+ id: userUploadingImg.id,
+ role: CONSTANTS.CS_USER_ROLES.MANAGER
+ });
+
+ txtFile = await uploadActions.uploadFile(this.alfrescoJsApi, txtFileInfo.location, txtFileInfo.name, site.entry.guid);
+
+ await browser.driver.sleep(10000);
+
+ await this.alfrescoJsApi.login(userUploadingImg.id, userUploadingImg.password);
+
+ jpgFile = await uploadActions.uploadFile(this.alfrescoJsApi, jpgFileInfo.location, jpgFileInfo.name, site.entry.guid);
+
+ await browser.driver.sleep(10000);
+
+ loginPage.loginToContentServicesUsingUserModel(userUploadingImg);
+
+ searchDialog.checkSearchIconIsVisible();
+ searchDialog.clickOnSearchIcon();
+ searchDialog.enterTextAndPressEnter('file');
+
+ done();
+ });
+
+ afterAll(async (done) => {
+ await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword);
+
+ Promise.all([
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, jpgFile.entry.id),
+ uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, txtFile.entry.id)
+ ]);
+ done();
+ });
+
+ it('[C280056] Multiple items can be selected from multiple search facets', () => {
+ searchFiltersPage.checkSearchFiltersIsDisplayed();
+
+ searchFiltersPage.filterByFileType("Plain Text");
+ searchFiltersPage.filterByFileType("JPEG Image");
+
+ searchResultsPage.checkContentIsDisplayed(txtFile.entry.name);
+ searchResultsPage.checkContentIsDisplayed(jpgFile.entry.name);
+
+ searchFiltersPage.filterByCreator(userUploadingTxt.firstName, userUploadingTxt.lastName);
+ searchFiltersPage.filterByCreator(userUploadingImg.firstName, userUploadingImg.lastName);
+
+ expect(searchResultsPage.numberOfResultsDisplayed()).toBe(2);
+ searchResultsPage.checkContentIsDisplayed(txtFile.entry.name);
+ searchResultsPage.checkContentIsDisplayed(jpgFile.entry.name);
+ });
+ });
+
+ describe('', () => {
+ let txtFile;
+ let acsUser = new AcsUserModel();
+
+ let txtFileInfo = new FileModel({
+ 'location': resources.Files.ADF_DOCUMENTS.TXT_0B.file_location,
+ 'name': resources.Files.ADF_DOCUMENTS.TXT_0B.file_name
+ });
+
+ beforeAll(async (done) => {
+ await this.alfrescoJsApi.login(TestConfig.adf.adminEmail, TestConfig.adf.adminPassword);
+
+ await this.alfrescoJsApi.core.peopleApi.addPerson(acsUser);
+
+ await this.alfrescoJsApi.login(acsUser.id, acsUser.password);
+
+ site = await this.alfrescoJsApi.core.sitesApi.createSite({
+ title: Util.generateRandomString(8),
+ visibility: 'PUBLIC'
+ });
+
+ txtFile = await uploadActions.uploadFile(this.alfrescoJsApi, txtFileInfo.location, txtFileInfo.name, '-my-');
+ await browser.driver.sleep(10000);
+
+ loginPage.loginToContentServicesUsingUserModel(acsUser);
+
+ searchDialog.checkSearchIconIsVisible();
+ searchDialog.clickOnSearchIcon();
+ searchDialog.enterTextAndPressEnter('file');
+
+ searchFiltersPage.checkSearchFiltersIsDisplayed();
+
+ done();
+ });
+
+ afterAll(async (done) => {
+ await uploadActions.deleteFilesOrFolder(this.alfrescoJsApi, txtFile.entry.id);
+ done();
+ });
+
+ it('[C280058] The filter facets items number is updated when another filter facet item is selected', () => {
+ searchFiltersPage.filterByFileType("Plain Text");
+
+ searchFiltersPage.filterByCreator(acsUser.firstName, acsUser.lastName);
+
+ expect(searchResultsPage.numberOfResultsDisplayed()).toBe(1);
+ searchResultsPage.checkContentIsDisplayed(txtFile.entry.name);
+ });
+ });
+});
diff --git a/e2e/pages/adf/searchFiltersPage.js b/e2e/pages/adf/searchFiltersPage.js
new file mode 100644
index 0000000000..c07899b174
--- /dev/null
+++ b/e2e/pages/adf/searchFiltersPage.js
@@ -0,0 +1,100 @@
+/*!
+ * @license
+ * Copyright 2016 Alfresco Software, Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var Util = require('../../util/util');
+
+var SearchFiltersPage = function () {
+
+ var searchFilters = element(by.css("adf-search-filter"));
+ var fileTypeFilter = element(by.css("mat-expansion-panel[data-automation-id='expansion-panel-1:Type'"));
+ var searchFileTypeFilter = element(by.css("input[data-automation-id='facet-result-filter-1:Type'"));
+ var creatorFilter = element(by.css("mat-expansion-panel[data-automation-id='expansion-panel-3:Creator'"));
+ var searchCreatorFilter = element(by.css("input[data-automation-id='facet-result-filter-3:Creator'"));
+
+ this.checkSearchFiltersIsDisplayed = function () {
+ Util.waitUntilElementIsVisible(searchFilters);
+ };
+
+ this.checkFileTypeFilterIsDisplayed = function () {
+ Util.waitUntilElementIsVisible(fileTypeFilter);
+ };
+
+ this.checkSearchFileTypeFilterIsDisplayed = function () {
+ Util.waitUntilElementIsVisible(fileTypeFilter);
+ };
+
+ this.checkCreatorFilterIsDisplayed = function () {
+ Util.waitUntilElementIsVisible(creatorFilter);
+ };
+
+ this.checkSearchCreatorFilterIsDisplayed = function () {
+ Util.waitUntilElementIsVisible(searchCreatorFilter);
+ };
+
+ this.clickFileTypeFilter = function () {
+ Util.waitUntilElementIsClickable(fileTypeFilter);
+ return fileTypeFilter.click();
+ };
+
+ this.clickCreatorFilter = function () {
+ Util.waitUntilElementIsClickable(creatorFilter);
+ return creatorFilter.click();
+ };
+
+ this.searchInFileTypeFilter = function (fileType) {
+ Util.waitUntilElementIsClickable(searchFileTypeFilter);
+ searchFileTypeFilter.clear();
+ searchFileTypeFilter.sendKeys(fileType);
+ };
+
+ this.searchInCreatorFilter = function (creatorName) {
+ Util.waitUntilElementIsClickable(searchCreatorFilter);
+ searchCreatorFilter.clear();
+ searchCreatorFilter.sendKeys(creatorName);
+ };
+
+ this.selectFileType = function (fileType) {
+ let result = element(by.css(`mat-checkbox[data-automation-id='checkbox-1:Type-${fileType}']`));
+ Util.waitUntilElementIsClickable(result);
+ result.click();
+ };
+
+ this.selectCreator = function (creatorName) {
+ let result = element(by.css(`mat-checkbox[data-automation-id='checkbox-3:Creator-${creatorName}']`));
+ Util.waitUntilElementIsClickable(result);
+ result.click();
+ };
+
+ this.filterByFileType = function (fileType) {
+ this.checkFileTypeFilterIsDisplayed();
+ this.clickFileTypeFilter();
+
+ this.checkSearchFileTypeFilterIsDisplayed();
+ this.searchInFileTypeFilter(fileType);
+ this.selectFileType(fileType);
+ };
+
+ this.filterByCreator = function (creatorFirstName, creatorLastName) {
+ this.checkCreatorFilterIsDisplayed();
+ this.clickCreatorFilter();
+
+ this.checkSearchCreatorFilterIsDisplayed();
+ this.searchInCreatorFilter(`${creatorFirstName} ${creatorLastName}`);
+ this.selectCreator(`${creatorFirstName} ${creatorLastName}`);
+ };
+};
+module.exports = SearchFiltersPage;
diff --git a/lib/content-services/search/components/search-filter/search-filter.component.html b/lib/content-services/search/components/search-filter/search-filter.component.html
index 7258f17704..750b100038 100644
--- a/lib/content-services/search/components/search-filter/search-filter.component.html
+++ b/lib/content-services/search/components/search-filter/search-filter.component.html
@@ -2,6 +2,7 @@
@@ -16,7 +17,7 @@
-
+
{{ facetQueriesLabel | translate }}
@@ -25,6 +26,7 @@
-
+
{{ field.label }}
@@ -76,6 +79,7 @@