Fix #10454: Improve Search Relevancy, by adding functional scoring an… (#10455)

* Fix #10454: Improve Search Relevancy, by adding functional scoring and add ngram analyzer; Fix #10452: Enable Table and Column search by BOTH name and displayName

* fix stylecheck

* Undo changes in table example names

* remove ngram from teams & users

* Fix topic tags

* Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf (#10430)

* Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf

* Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf

* Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf

* Fix #10429: Kafka Sample data improvements and adding support for JSONSchema and Protobuf

* Added top level parsing and unit tests

* fix(ui): show schemaText and fields both

* fix no data placeholder for fields & schema text

* addressing comments

* fixed py checkstyle

---------

Co-authored-by: Onkar Ravgan <onkar.10r@gmail.com>
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>

* revert common_broker_source changes

* revert common_broker_source changes

* remove changes to user & team indexes

* fix team index

* fix glossary & tag index

* Fix to TopicIndex

* fix advance search pre-requisites cypress failure

* fix group advance search cy failures

---------

Co-authored-by: Nahuel <nahuel@getcollate.io>
Co-authored-by: Onkar Ravgan <onkar.10r@gmail.com>
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
Sriharsha Chintalapani 2023-03-09 08:07:08 -08:00 committed by GitHub
parent f27266628d
commit d9e4fbdebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 215 additions and 121 deletions

View File

@ -135,15 +135,15 @@
"tags": [],
"usageSummary": {
"dailyStats": {
"count": 100,
"count": 73,
"percentileRank": 45
},
"weeklyStats": {
"count": 100,
"count": 73,
"percentileRank": 45
},
"monthlyStats": {
"count": 100,
"count": 67,
"percentileRank": 45
},
"date": "2021-12-01"
@ -803,15 +803,15 @@
"tags": [],
"usageSummary": {
"dailyStats": {
"count": 100,
"count": 87,
"percentileRank": 45
},
"weeklyStats": {
"count": 100,
"count": 87,
"percentileRank": 45
},
"monthlyStats": {
"count": 100,
"count": 87,
"percentileRank": 45
},
"date": "2021-12-01"

View File

@ -26,6 +26,7 @@ public class DashboardIndex implements ElasticSearchIndex {
suggest.add(ElasticSearchSuggest.builder().input(dashboard.getDisplayName()).weight(10).build());
serviceSuggest.add(ElasticSearchSuggest.builder().input(dashboard.getService().getName()).weight(5).build());
ParseTags parseTags = new ParseTags(ElasticSearchIndexUtils.parseTags(dashboard.getTags()));
if (dashboard.getCharts() != null) {
for (EntityReference chart : dashboard.getCharts()) {
chartSuggest.add(ElasticSearchSuggest.builder().input(chart.getDisplayName()).weight(5).build());

View File

@ -281,6 +281,14 @@ class FlattenColumn {
List<TagLabel> tags;
}
@Getter
@Builder
class FlattenSchemaField {
String name;
String description;
List<TagLabel> tags;
}
class ParseTags {
TagLabel tierTag;
final List<TagLabel> tags;

View File

@ -3,9 +3,13 @@ package org.openmetadata.service.elasticsearch;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import org.openmetadata.schema.entity.data.Topic;
import org.openmetadata.schema.type.Field;
import org.openmetadata.schema.type.TagLabel;
import org.openmetadata.service.Entity;
import org.openmetadata.service.util.FullyQualifiedName;
import org.openmetadata.service.util.JsonUtils;
public class TopicIndex implements ElasticSearchIndex {
@ -20,6 +24,7 @@ public class TopicIndex implements ElasticSearchIndex {
Map<String, Object> doc = JsonUtils.getMap(topic);
List<TagLabel> tags = new ArrayList<>();
List<ElasticSearchSuggest> suggest = new ArrayList<>();
List<ElasticSearchSuggest> fieldSuggest = new ArrayList<>();
List<ElasticSearchSuggest> serviceSuggest = new ArrayList<>();
suggest.add(ElasticSearchSuggest.builder().input(topic.getFullyQualifiedName()).weight(5).build());
suggest.add(ElasticSearchSuggest.builder().input(topic.getName()).weight(10).build());
@ -28,12 +33,28 @@ public class TopicIndex implements ElasticSearchIndex {
if (topic.getTags() != null) {
tags.addAll(topic.getTags());
}
if (topic.getMessageSchema() != null
&& topic.getMessageSchema().getSchemaFields() != null
&& !topic.getMessageSchema().getSchemaFields().isEmpty()) {
List<FlattenSchemaField> flattenFields = new ArrayList<>();
parseSchemaFields(topic.getMessageSchema().getSchemaFields(), flattenFields, null);
for (FlattenSchemaField field : flattenFields) {
if (field.getTags() != null) {
tags.addAll(field.getTags());
}
fieldSuggest.add(ElasticSearchSuggest.builder().input(field.getName()).weight(5).build());
}
}
ParseTags parseTags = new ParseTags(tags);
doc.put("displayName", topic.getDisplayName() != null ? topic.getDisplayName() : topic.getName());
doc.put("tags", parseTags.tags);
doc.put("tier", parseTags.tierTag);
doc.put("followers", ElasticSearchIndexUtils.parseFollowers(topic.getFollowers()));
doc.put("suggest", suggest);
doc.put("field_suggest", fieldSuggest);
doc.put("service_suggest", serviceSuggest);
doc.put("entityType", Entity.TOPIC);
doc.put("serviceType", topic.getServiceType());
@ -41,4 +62,30 @@ public class TopicIndex implements ElasticSearchIndex {
doc.put("schemaType", topic.getMessageSchema() != null ? topic.getMessageSchema().getSchemaType() : null);
return doc;
}
private void parseSchemaFields(
List<Field> fields, List<FlattenSchemaField> flattenSchemaFields, String parentSchemaField) {
Optional<String> optParentField = Optional.ofNullable(parentSchemaField).filter(Predicate.not(String::isEmpty));
List<TagLabel> tags = new ArrayList<>();
for (Field field : fields) {
String fieldName = field.getName();
if (optParentField.isPresent()) {
fieldName = FullyQualifiedName.add(optParentField.get(), fieldName);
}
if (field.getTags() != null) {
tags = field.getTags();
}
FlattenSchemaField flattenSchemaField =
FlattenSchemaField.builder().name(fieldName).description(field.getDescription()).build();
if (!tags.isEmpty()) {
flattenSchemaField.tags = tags;
}
flattenSchemaFields.add(flattenSchemaField);
if (field.getChildren() != null) {
parseSchemaFields(field.getChildren(), flattenSchemaFields, field.getName());
}
}
}
}

View File

@ -17,6 +17,7 @@ import static javax.ws.rs.core.Response.Status.OK;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.Entity.FIELD_DESCRIPTION;
import static org.openmetadata.service.Entity.FIELD_DISPLAY_NAME;
import static org.openmetadata.service.Entity.FIELD_NAME;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
@ -43,6 +44,7 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.unit.TimeValue;
@ -51,7 +53,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchNoneQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
@ -84,10 +86,10 @@ public class SearchResource {
private RestHighLevelClient client;
private static final Integer MAX_AGGREGATE_SIZE = 50;
private static final Integer MAX_RESULT_HITS = 10000;
private static final String NAME = "name";
private static final String NAME_KEYWORD = "name.keyword";
private static final String DISPLAY_NAME = "displayName";
private static final String DISPLAY_NAME_KEYWORD = "displayName.keyword";
public static final String FIELD_DISPLAY_NAME_NGRAM = "displayName.ngram";
private static final String DESCRIPTION = "description";
private static final String UNIFIED = "unified";
@ -402,20 +404,27 @@ public class SearchResource {
private SearchSourceBuilder buildTableSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryStringBuilder =
QueryBuilders.queryStringQuery(query)
.field(FIELD_DISPLAY_NAME, 20.0f)
.field(FIELD_DESCRIPTION, 2.0f)
.field(FIELD_DISPLAY_NAME, 15.0f)
.field(FIELD_DISPLAY_NAME_NGRAM)
.field(FIELD_NAME, 15.0f)
.field(FIELD_DESCRIPTION, 1.0f)
.field("columns.name", 2.0f)
.field("columns.name.ngram")
.field("columns.displayName", 2.0f)
.field("columns.displayName.ngram")
.field("columns.description", 1.0f)
.field("columns.children.name", 2.0f)
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
FieldValueFactorFunctionBuilder boostScoreBuilder =
ScoreFunctionBuilders.fieldValueFactorFunction("usageSummary.weeklyStats.count").missing(1).factor(4);
ScoreFunctionBuilders.fieldValueFactorFunction("usageSummary.weeklyStats.count").missing(0).factor(0.2f);
FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions =
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(new MatchNoneQueryBuilder(), boostScoreBuilder)
new FunctionScoreQueryBuilder.FilterFunctionBuilder(boostScoreBuilder)
};
FunctionScoreQueryBuilder queryBuilder = QueryBuilders.functionScoreQuery(queryStringBuilder, functions);
queryBuilder.boostMode(CombineFunction.SUM);
HighlightBuilder.Field highlightTableName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME);
highlightTableName.highlighterType(UNIFIED);
HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(DESCRIPTION);
@ -446,8 +455,10 @@ public class SearchResource {
private SearchSourceBuilder buildTopicSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(FIELD_DISPLAY_NAME, 10.0f)
.field(FIELD_DESCRIPTION, 2.0f)
.field(FIELD_DISPLAY_NAME, 15.0f)
.field(FIELD_DISPLAY_NAME_NGRAM)
.field(FIELD_NAME, 15.0f)
.field(FIELD_DESCRIPTION, 1.0f)
.field("messageSchema.schemaFields.name", 2.0f)
.field("messageSchema.schemaFields.description", 1.0f)
.field("messageSchema.schemaFields.children.name", 2.0f)
@ -471,10 +482,12 @@ public class SearchResource {
private SearchSourceBuilder buildDashboardSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(FIELD_DISPLAY_NAME, 10.0f)
.field(FIELD_DESCRIPTION, 2.0f)
.field(FIELD_DISPLAY_NAME, 15.0f)
.field(FIELD_DISPLAY_NAME_NGRAM)
.field(FIELD_NAME, 15.0f)
.field(FIELD_DESCRIPTION, 1.0f)
.field("charts.name", 2.0f)
.field("charts.description")
.field("charts.description", 1.0f)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
HighlightBuilder.Field highlightDashboardName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME);
@ -499,10 +512,12 @@ public class SearchResource {
private SearchSourceBuilder buildPipelineSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(FIELD_DISPLAY_NAME, 10.0f)
.field(DESCRIPTION, 2.0f)
.field(FIELD_DISPLAY_NAME, 15.0f)
.field(FIELD_DISPLAY_NAME_NGRAM)
.field(FIELD_NAME, 15.0f)
.field(DESCRIPTION, 1.0f)
.field("tasks.name", 2.0f)
.field("tasks.description")
.field("tasks.description", 1.0f)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
HighlightBuilder.Field highlightPipelineName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME);
@ -525,10 +540,12 @@ public class SearchResource {
private SearchSourceBuilder buildMlModelSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(FIELD_DISPLAY_NAME, 10.0f)
.field(DESCRIPTION, 2.0f)
.field(FIELD_DISPLAY_NAME, 15.0f)
.field(FIELD_DISPLAY_NAME_NGRAM)
.field(FIELD_NAME, 15.0f)
.field(DESCRIPTION, 1.0f)
.field("mlFeatures.name", 2.0f)
.field("mlFeatures.description")
.field("mlFeatures.description", 1.0f)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
HighlightBuilder.Field highlightPipelineName = new HighlightBuilder.Field(FIELD_DISPLAY_NAME);
@ -575,7 +592,7 @@ public class SearchResource {
QueryBuilders.queryStringQuery(query)
.field(DISPLAY_NAME, 5.0f)
.field(DISPLAY_NAME_KEYWORD, 3.0f)
.field(NAME, 2.0f)
.field(FIELD_NAME, 2.0f)
.field(NAME_KEYWORD, 3.0f)
.fuzziness(Fuzziness.AUTO);
return searchBuilder(queryBuilder, null, from, size);
@ -586,7 +603,7 @@ public class SearchResource {
QueryBuilders.queryStringQuery(query)
.field(DISPLAY_NAME, 5.0f)
.field(DISPLAY_NAME_KEYWORD, 3.0f)
.field(NAME, 2.0f)
.field(FIELD_NAME, 2.0f)
.field(NAME_KEYWORD, 3.0f)
.fuzziness(Fuzziness.AUTO);
return searchBuilder(queryBuilder, null, from, size);
@ -595,12 +612,12 @@ public class SearchResource {
private SearchSourceBuilder buildGlossaryTermSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(NAME, 10.0f)
.field(FIELD_NAME, 10.0f)
.field(DESCRIPTION, 3.0f)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
HighlightBuilder.Field highlightGlossaryName = new HighlightBuilder.Field(NAME);
HighlightBuilder.Field highlightGlossaryName = new HighlightBuilder.Field(FIELD_NAME);
highlightGlossaryName.highlighterType(UNIFIED);
HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(FIELD_DESCRIPTION);
highlightDescription.highlighterType(UNIFIED);
@ -616,12 +633,12 @@ public class SearchResource {
private SearchSourceBuilder buildTagSearchBuilder(String query, int from, int size) {
QueryStringQueryBuilder queryBuilder =
QueryBuilders.queryStringQuery(query)
.field(NAME, 10.0f)
.field(FIELD_NAME, 10.0f)
.field(DESCRIPTION, 3.0f)
.defaultOperator(Operator.AND)
.fuzziness(Fuzziness.AUTO);
HighlightBuilder.Field highlightTagName = new HighlightBuilder.Field(NAME);
HighlightBuilder.Field highlightTagName = new HighlightBuilder.Field(FIELD_NAME);
highlightTagName.highlighterType(UNIFIED);
HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field(FIELD_DESCRIPTION);
highlightDescription.highlighterType(UNIFIED);

View File

@ -17,6 +17,11 @@
"lowercase",
"om_stemmer"
]
},
"om_ngram": {
"tokenizer": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"filter": {
@ -47,7 +52,13 @@
},
"displayName": {
"type": "text",
"analyzer": "om_analyzer"
"analyzer": "om_analyzer",
"fields": {
"ngram": {
"type": "text",
"analyzer": "om_ngram"
}
}
},
"description": {
"type": "text",
@ -92,6 +103,15 @@
}
}
},
"displayName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"fullyQualifiedName": {
"type": "text"
},

View File

@ -17,6 +17,11 @@
"lowercase",
"om_stemmer"
]
},
"om_ngram": {
"tokenizer": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"filter": {
@ -47,7 +52,13 @@
},
"displayName": {
"type": "text",
"analyzer": "om_analyzer"
"analyzer": "om_analyzer",
"fields": {
"ngram": {
"type": "text",
"analyzer": "om_ngram"
}
}
},
"description": {
"type": "text",

View File

@ -82,7 +82,12 @@
},
"displayName": {
"type": "text",
"analyzer": "om_analyzer"
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"description": {
"type": "text",

View File

@ -17,6 +17,11 @@
"lowercase",
"om_stemmer"
]
},
"om_ngram": {
"tokenizer": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"filter": {
@ -47,7 +52,13 @@
},
"displayName": {
"type": "text",
"analyzer": "om_analyzer"
"analyzer": "om_analyzer",
"fields": {
"ngram": {
"type": "text",
"analyzer": "om_ngram"
}
}
},
"description": {
"type": "text",

View File

@ -17,6 +17,11 @@
"lowercase",
"om_stemmer"
]
},
"om_ngram": {
"tokenizer": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"filter": {

View File

@ -17,6 +17,11 @@
"lowercase",
"om_stemmer"
]
},
"om_ngram": {
"tokenizer": "ngram",
"min_gram": 1,
"max_gram": 2
}
},
"filter": {
@ -47,7 +52,12 @@
},
"displayName": {
"type": "text",
"analyzer": "om_analyzer"
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"description": {
"type": "text",
@ -227,6 +237,9 @@
}
]
},
"field_suggest": {
"type": "completion"
},
"service_suggest": {
"type": "completion"
}

View File

@ -10,8 +10,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SEARCH_ENTITY_TABLE } from '../constants/constants';
import { MYSQL } from '../constants/service.constants';
import { interceptURL, verifyResponseStatusCode } from './common';
import {
interceptURL,
verifyResponseStatusCode,
visitEntityDetailsPage,
} from './common';
export const CONDITIONS_MUST = {
equalTo: {
@ -47,9 +52,9 @@ export const FIELDS = {
Owner: {
name: 'Owner',
testid: '[title="Owner"]',
searchTerm1: 'admin',
searchCriteriaFirstGroup: 'admin',
responseValueFirstGroup: `"displayName":"admin"`,
searchTerm1: 'Colin Ho',
searchCriteriaFirstGroup: 'Colin Ho',
responseValueFirstGroup: `"displayName":"Colin Ho"`,
searchCriteriaSecondGroup: 'Aaron Singh',
owner: true,
responseValueSecondGroup: 'Aaron Singh',
@ -249,45 +254,11 @@ export const checkmust_notPaths = (
};
export const addOwner = (searchTerm, ownerName) => {
cy.get(
'[data-testid="dropdown-profile"] > [data-testid="dropdown-item"] > :nth-child(1) > [data-testid="menu-button"]'
)
.should('exist')
.and('be.visible')
.click();
cy.get('[data-testid="user-name"]').should('exist').and('be.visible').click();
verifyResponseStatusCode('@userProfile', 200);
cy.get('[data-testid="hiden-layer"]').should('exist').click();
cy.get('[data-testid="edit-displayName"]')
.should('exist')
.and('be.visible')
.click();
cy.get('[data-testid="displayName"]')
.should('exist')
.and('be.visible')
.clear()
.type(ownerName);
cy.get('[data-testid="save-displayName"]')
.should('exist')
.and('be.visible')
.click();
cy.get('[data-testid="appbar-item-explore"]')
.should('exist')
.and('be.visible')
.click();
cy.get('#tabledatacard0-title')
.first()
.scrollIntoView()
.should('be.visible')
.click();
visitEntityDetailsPage(
SEARCH_ENTITY_TABLE.table_1.term,
SEARCH_ENTITY_TABLE.table_1.serviceName,
SEARCH_ENTITY_TABLE.table_1.entity
);
interceptURL(
'GET',
@ -307,7 +278,7 @@ export const addOwner = (searchTerm, ownerName) => {
interceptURL(
'GET',
`api/v1/search/query?q=*${searchTerm}*&from=0&size=*&index=*`,
`api/v1/search/query?q=*${encodeURI(searchTerm)}*&from=0&size=*&index=*`,
'searchOwner'
);
cy.get('[data-testid="searchInputText"]')
@ -328,6 +299,8 @@ export const addOwner = (searchTerm, ownerName) => {
.and('be.visible')
.click();
verifyResponseStatusCode('@tablePatch', 200);
cy.get('[data-testid="owner-link"]')
.scrollIntoView()
.invoke('text')
@ -337,17 +310,11 @@ export const addOwner = (searchTerm, ownerName) => {
};
export const addTier = (tier) => {
cy.get('[data-testid="appbar-item-explore"]')
.scrollIntoView()
.should('exist')
.and('be.visible')
.click();
cy.get('#tabledatacard0-title')
.first()
.scrollIntoView()
.should('be.visible')
.click();
visitEntityDetailsPage(
SEARCH_ENTITY_TABLE.table_2.term,
SEARCH_ENTITY_TABLE.table_2.serviceName,
SEARCH_ENTITY_TABLE.table_2.entity
);
cy.get('[data-testid="edit-Tier-icon"]')
.scrollIntoView()
@ -368,42 +335,29 @@ export const addTier = (tier) => {
};
export const addTag = (tag) => {
cy.intercept('/api/v1/testCase?fields=testCaseResult*').as('testCaseResults');
cy.intercept('/api/v1/feed?entityLink=*').as('entityLink');
visitEntityDetailsPage(
SEARCH_ENTITY_TABLE.table_3.term,
SEARCH_ENTITY_TABLE.table_3.serviceName,
SEARCH_ENTITY_TABLE.table_3.entity
);
cy.get('[data-testid="appbar-item-explore"]')
.should('exist')
.and('be.visible')
cy.get('[data-testid="tags"] > [data-testid="add-tag"]')
.eq(0)
.should('be.visible')
.scrollIntoView()
.click();
cy.get('#tabledatacard0-title')
.first()
cy.get('[data-testid="tag-selector"]').should('be.visible').click().type(tag);
cy.get('.ant-select-item-option-content').should('be.visible').click();
cy.get(
'[data-testid="tags-wrapper"] > [data-testid="tag-container"]'
).contains(tag);
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
cy.get('[data-testid="entity-tags"]')
.scrollIntoView()
.should('be.visible')
.click();
cy.wait(['@testCaseResults', '@entityLink']).then(() => {
cy.get('[data-testid="tags"] > [data-testid="add-tag"]')
.eq(0)
.should('be.visible')
.scrollIntoView()
.click();
cy.get('[data-testid="tag-selector"]')
.should('be.visible')
.click()
.type(tag);
cy.get('.ant-select-item-option-content').should('be.visible').click();
cy.get(
'[data-testid="tags-wrapper"] > [data-testid="tag-container"]'
).contains(tag);
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
cy.get('[data-testid="entity-tags"]')
.scrollIntoView()
.should('be.visible')
.contains(tag);
});
.contains(tag);
};
export const checkAddGroupWithOperator = (
@ -519,7 +473,9 @@ export const checkAddGroupWithOperator = (
interceptURL(
'GET',
`/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${searchCriteria_1}*&sort_field=_score&sort_order=desc`,
`/api/v1/search/query?q=&index=*&from=0&size=10&deleted=false&query_filter=*${encodeURI(
searchCriteria_1
)}*&sort_field=_score&sort_order=desc`,
'search'
);