-
diff --git a/datahub-web-react/src/app/ingest/source/builder/NameSourceStep.tsx b/datahub-web-react/src/app/ingest/source/builder/NameSourceStep.tsx
index ff37572057e21..f4c048bcaf0d2 100644
--- a/datahub-web-react/src/app/ingest/source/builder/NameSourceStep.tsx
+++ b/datahub-web-react/src/app/ingest/source/builder/NameSourceStep.tsx
@@ -244,6 +244,7 @@ export const NameSourceStep = ({ state, updateState, prev, submit }: StepProps)
Previous
0)}
onClick={() => onClickCreate(false)}
>
diff --git a/datahub-web-react/src/app/ingest/source/builder/RecipeBuilder.tsx b/datahub-web-react/src/app/ingest/source/builder/RecipeBuilder.tsx
index 4ddeb7b492595..bee9b04cee100 100644
--- a/datahub-web-react/src/app/ingest/source/builder/RecipeBuilder.tsx
+++ b/datahub-web-react/src/app/ingest/source/builder/RecipeBuilder.tsx
@@ -86,10 +86,20 @@ function RecipeBuilder(props: Props) {
{sourceConfigs?.displayName} Recipe
- switchViews(true)}>
+ switchViews(true)}
+ data-testid="recipe-builder-form-button"
+ >
Form
- switchViews(false)}>
+ switchViews(false)}
+ data-testid="recipe-builder-yaml-button"
+ >
YAML
@@ -114,7 +124,9 @@ function RecipeBuilder(props: Props) {
Previous
- Next
+
+ Next
+
>
)}
diff --git a/metadata-ingestion/src/datahub/ingestion/source/aws/glue.py b/metadata-ingestion/src/datahub/ingestion/source/aws/glue.py
index e5dff786b71d1..aa7e5aa352a3e 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/aws/glue.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/aws/glue.py
@@ -221,6 +221,7 @@ def report_table_dropped(self, table: str) -> None:
SourceCapability.DELETION_DETECTION,
"Enabled by default when stateful ingestion is turned on.",
)
+@capability(SourceCapability.LINEAGE_COARSE, "Enabled by default")
class GlueSource(StatefulIngestionSourceBase):
"""
Note: if you also have files in S3 that you'd like to ingest, we recommend you use Glue's built-in data catalog. See [here](../../../../docs/generated/ingestion/sources/s3.md) for a quick guide on how to set up a crawler on Glue and ingest the outputs with DataHub.
diff --git a/metadata-ingestion/src/datahub/ingestion/source/bigquery_v2/bigquery.py b/metadata-ingestion/src/datahub/ingestion/source/bigquery_v2/bigquery.py
index 552612f877b9a..692d8c4f81bb6 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/bigquery_v2/bigquery.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/bigquery_v2/bigquery.py
@@ -153,6 +153,7 @@ def cleanup(config: BigQueryV2Config) -> None:
)
@capability(SourceCapability.DESCRIPTIONS, "Enabled by default")
@capability(SourceCapability.LINEAGE_COARSE, "Optionally enabled via configuration")
+@capability(SourceCapability.LINEAGE_FINE, "Optionally enabled via configuration")
@capability(
SourceCapability.USAGE_STATS,
"Enabled by default, can be disabled via configuration `include_usage_statistics`",
diff --git a/metadata-ingestion/src/datahub/ingestion/source/kafka_connect.py b/metadata-ingestion/src/datahub/ingestion/source/kafka_connect.py
index 5fae0ee5215a3..1a1e012e80633 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/kafka_connect.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/kafka_connect.py
@@ -1096,6 +1096,7 @@ def transform_connector_config(
@config_class(KafkaConnectSourceConfig)
@support_status(SupportStatus.CERTIFIED)
@capability(SourceCapability.PLATFORM_INSTANCE, "Enabled by default")
+@capability(SourceCapability.LINEAGE_COARSE, "Enabled by default")
class KafkaConnectSource(StatefulIngestionSourceBase):
config: KafkaConnectSourceConfig
report: KafkaConnectSourceReport
diff --git a/metadata-ingestion/src/datahub/ingestion/source/looker/looker_source.py b/metadata-ingestion/src/datahub/ingestion/source/looker/looker_source.py
index 8297a0aa8efa7..a3df977582ca4 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/looker/looker_source.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/looker/looker_source.py
@@ -103,6 +103,11 @@
@capability(
SourceCapability.OWNERSHIP, "Enabled by default, configured using `extract_owners`"
)
+@capability(SourceCapability.LINEAGE_COARSE, "Supported by default")
+@capability(
+ SourceCapability.LINEAGE_FINE,
+ "Enabled by default, configured using `extract_column_level_lineage`",
+)
@capability(
SourceCapability.USAGE_STATS,
"Enabled by default, configured using `extract_usage_history`",
@@ -1128,7 +1133,6 @@ def get_workunit_processors(self) -> List[Optional[MetadataWorkUnitProcessor]]:
def emit_independent_looks_mcp(
self, dashboard_element: LookerDashboardElement
) -> Iterable[MetadataWorkUnit]:
-
yield from auto_workunit(
stream=self._make_chart_metadata_events(
dashboard_element=dashboard_element,
diff --git a/metadata-ingestion/src/datahub/ingestion/source/metabase.py b/metadata-ingestion/src/datahub/ingestion/source/metabase.py
index fb4512893feb1..24145d60210ff 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/metabase.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/metabase.py
@@ -80,6 +80,7 @@ def remove_trailing_slash(cls, v):
@config_class(MetabaseConfig)
@support_status(SupportStatus.CERTIFIED)
@capability(SourceCapability.PLATFORM_INSTANCE, "Enabled by default")
+@capability(SourceCapability.LINEAGE_COARSE, "Supported by default")
class MetabaseSource(Source):
"""
This plugin extracts Charts, dashboards, and associated metadata. This plugin is in beta and has only been tested
diff --git a/metadata-ingestion/src/datahub/ingestion/source/metadata/lineage.py b/metadata-ingestion/src/datahub/ingestion/source/metadata/lineage.py
index 1c0c809c16a60..f33c6e0edae3d 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/metadata/lineage.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/metadata/lineage.py
@@ -23,11 +23,17 @@
from datahub.ingestion.api.common import PipelineContext
from datahub.ingestion.api.decorators import (
SupportStatus,
+ capability,
config_class,
platform_name,
support_status,
)
-from datahub.ingestion.api.source import MetadataWorkUnitProcessor, Source, SourceReport
+from datahub.ingestion.api.source import (
+ MetadataWorkUnitProcessor,
+ Source,
+ SourceCapability,
+ SourceReport,
+)
from datahub.ingestion.api.source_helpers import (
auto_status_aspect,
auto_workunit_reporter,
@@ -121,6 +127,8 @@ def version_must_be_1(cls, v):
@platform_name("File Based Lineage")
@config_class(LineageFileSourceConfig)
@support_status(SupportStatus.CERTIFIED)
+@capability(SourceCapability.LINEAGE_COARSE, "Specified in the lineage file.")
+@capability(SourceCapability.LINEAGE_FINE, "Specified in the lineage file.")
@dataclass
class LineageFileSource(Source):
"""
diff --git a/metadata-ingestion/src/datahub/ingestion/source/mode.py b/metadata-ingestion/src/datahub/ingestion/source/mode.py
index a000c66a406c2..c46b56da422d9 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/mode.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/mode.py
@@ -98,6 +98,7 @@ class HTTPError429(HTTPError):
@config_class(ModeConfig)
@support_status(SupportStatus.CERTIFIED)
@capability(SourceCapability.PLATFORM_INSTANCE, "Enabled by default")
+@capability(SourceCapability.LINEAGE_COARSE, "Supported by default")
class ModeSource(Source):
"""
diff --git a/metadata-ingestion/src/datahub/ingestion/source/nifi.py b/metadata-ingestion/src/datahub/ingestion/source/nifi.py
index ac1e03812db3b..bc05edbb3c623 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/nifi.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/nifi.py
@@ -26,11 +26,12 @@
from datahub.ingestion.api.common import PipelineContext
from datahub.ingestion.api.decorators import (
SupportStatus,
+ capability,
config_class,
platform_name,
support_status,
)
-from datahub.ingestion.api.source import Source, SourceReport
+from datahub.ingestion.api.source import Source, SourceCapability, SourceReport
from datahub.ingestion.api.workunit import MetadataWorkUnit
from datahub.metadata.schema_classes import (
DataFlowInfoClass,
@@ -360,6 +361,7 @@ def report_dropped(self, ent_name: str) -> None:
@platform_name("NiFi", id="nifi")
@config_class(NifiSourceConfig)
@support_status(SupportStatus.CERTIFIED)
+@capability(SourceCapability.LINEAGE_COARSE, "Supported. See docs for limitations")
class NifiSource(Source):
"""
This plugin extracts the following:
diff --git a/metadata-ingestion/src/datahub/ingestion/source/powerbi/powerbi.py b/metadata-ingestion/src/datahub/ingestion/source/powerbi/powerbi.py
index 52bcef66658c8..4611a8eed4782 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/powerbi/powerbi.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/powerbi/powerbi.py
@@ -264,7 +264,6 @@ def extract_lineage(
)
if len(upstream) > 0:
-
upstream_lineage_class: UpstreamLineageClass = UpstreamLineageClass(
upstreams=upstream,
fineGrainedLineages=cll_lineage or None,
@@ -1139,6 +1138,10 @@ def report_to_datahub_work_units(
SourceCapability.OWNERSHIP,
"Disabled by default, configured using `extract_ownership`",
)
+@capability(
+ SourceCapability.LINEAGE_COARSE,
+ "Enabled by default, configured using `extract_lineage`.",
+)
@capability(
SourceCapability.LINEAGE_FINE,
"Disabled by default, configured using `extract_column_level_lineage`. ",
diff --git a/metadata-ingestion/src/datahub/ingestion/source/sql_queries.py b/metadata-ingestion/src/datahub/ingestion/source/sql_queries.py
index bce4d1ec76e6e..fcf97e461967c 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/sql_queries.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/sql_queries.py
@@ -20,11 +20,17 @@
from datahub.ingestion.api.common import PipelineContext
from datahub.ingestion.api.decorators import (
SupportStatus,
+ capability,
config_class,
platform_name,
support_status,
)
-from datahub.ingestion.api.source import MetadataWorkUnitProcessor, Source, SourceReport
+from datahub.ingestion.api.source import (
+ MetadataWorkUnitProcessor,
+ Source,
+ SourceCapability,
+ SourceReport,
+)
from datahub.ingestion.api.source_helpers import auto_workunit_reporter
from datahub.ingestion.api.workunit import MetadataWorkUnit
from datahub.ingestion.graph.client import DataHubGraph
@@ -83,6 +89,8 @@ def compute_stats(self) -> None:
@platform_name("SQL Queries")
@config_class(SqlQueriesSourceConfig)
@support_status(SupportStatus.TESTING)
+@capability(SourceCapability.LINEAGE_COARSE, "Parsed from SQL queries")
+@capability(SourceCapability.LINEAGE_FINE, "Parsed from SQL queries")
class SqlQueriesSource(Source):
# TODO: Documentation
urns: Optional[Set[str]]
diff --git a/metadata-ingestion/src/datahub/ingestion/source/superset.py b/metadata-ingestion/src/datahub/ingestion/source/superset.py
index 14bc4242d2a91..e491a1e8b82fa 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/superset.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/superset.py
@@ -142,6 +142,7 @@ def get_filter_name(filter_obj):
@capability(
SourceCapability.DELETION_DETECTION, "Optionally enabled via stateful_ingestion"
)
+@capability(SourceCapability.LINEAGE_COARSE, "Supported by default")
class SupersetSource(StatefulIngestionSourceBase):
"""
This plugin extracts the following:
diff --git a/metadata-ingestion/src/datahub/ingestion/source/tableau.py b/metadata-ingestion/src/datahub/ingestion/source/tableau.py
index bad7ae49d325e..4bc40b0aac964 100644
--- a/metadata-ingestion/src/datahub/ingestion/source/tableau.py
+++ b/metadata-ingestion/src/datahub/ingestion/source/tableau.py
@@ -452,6 +452,10 @@ class TableauSourceReport(StaleEntityRemovalSourceReport):
@capability(SourceCapability.OWNERSHIP, "Requires recipe configuration")
@capability(SourceCapability.TAGS, "Requires recipe configuration")
@capability(SourceCapability.LINEAGE_COARSE, "Enabled by default")
+@capability(
+ SourceCapability.LINEAGE_FINE,
+ "Enabled by default, configure using `extract_column_level_lineage`",
+)
class TableauSource(StatefulIngestionSourceBase):
platform = "tableau"
@@ -533,7 +537,7 @@ def fetch_projects():
path=[],
)
# Set parent project name
- for project_id, project in all_project_map.items():
+ for _project_id, project in all_project_map.items():
if (
project.parent_id is not None
and project.parent_id in all_project_map
diff --git a/metadata-io/src/main/java/com/linkedin/metadata/search/elasticsearch/indexbuilder/MappingsBuilder.java b/metadata-io/src/main/java/com/linkedin/metadata/search/elasticsearch/indexbuilder/MappingsBuilder.java
index 1edc77bbd214c..35cef71edd953 100644
--- a/metadata-io/src/main/java/com/linkedin/metadata/search/elasticsearch/indexbuilder/MappingsBuilder.java
+++ b/metadata-io/src/main/java/com/linkedin/metadata/search/elasticsearch/indexbuilder/MappingsBuilder.java
@@ -133,7 +133,7 @@ private static Map getMappingsForField(@Nonnull final Searchable
} else if (fieldType == FieldType.DATETIME) {
mappingForField.put(TYPE, ESUtils.DATE_FIELD_TYPE);
} else if (fieldType == FieldType.OBJECT) {
- mappingForField.put(TYPE, ESUtils.DATE_FIELD_TYPE);
+ mappingForField.put(TYPE, ESUtils.OBJECT_FIELD_TYPE);
} else {
log.info("FieldType {} has no mappings implemented", fieldType);
}
diff --git a/metadata-io/src/test/java/com/linkedin/metadata/timeseries/search/TimeseriesAspectServiceTestBase.java b/metadata-io/src/test/java/com/linkedin/metadata/timeseries/search/TimeseriesAspectServiceTestBase.java
index 026465dc925e7..1362a0f69eff2 100644
--- a/metadata-io/src/test/java/com/linkedin/metadata/timeseries/search/TimeseriesAspectServiceTestBase.java
+++ b/metadata-io/src/test/java/com/linkedin/metadata/timeseries/search/TimeseriesAspectServiceTestBase.java
@@ -889,6 +889,7 @@ public void testCountByFilterAfterDelete() throws InterruptedException {
@Test(groups = {"getAggregatedStats"}, dependsOnGroups = {"upsert"})
public void testGetIndexSizes() {
List result = _elasticSearchTimeseriesAspectService.getIndexSizes();
+ //CHECKSTYLE:OFF
/*
Example result:
{aspectName=testentityprofile, sizeMb=52.234,
@@ -897,9 +898,10 @@ public void testGetIndexSizes() {
indexName=es_timeseries_aspect_service_test_testentitywithouttests_testentityprofileaspect_v1, entityName=testentitywithouttests}
*/
// There may be other indices in there from other tests, so just make sure that index for entity + aspect is in there
- assertTrue(result.size() > 1);
+ //CHECKSTYLE:ON
+ assertTrue(result.size() > 0);
assertTrue(
result.stream().anyMatch(idxSizeResult -> idxSizeResult.getIndexName().equals(
- "es_timeseries_aspect_service_test_testentitywithouttests_testentityprofileaspect_v1")));
+ "es_timeseries_aspect_service_test_testentity_testentityprofileaspect_v1")));
}
}
diff --git a/metadata-io/src/test/java/io/datahubproject/test/search/SearchTestContainer.java b/metadata-io/src/test/java/io/datahubproject/test/search/SearchTestContainer.java
index adbb8188744c6..34aa6978f742f 100644
--- a/metadata-io/src/test/java/io/datahubproject/test/search/SearchTestContainer.java
+++ b/metadata-io/src/test/java/io/datahubproject/test/search/SearchTestContainer.java
@@ -5,7 +5,9 @@
import java.time.Duration;
public interface SearchTestContainer {
- String SEARCH_JAVA_OPTS = "-Xms64m -Xmx400m -XX:MaxDirectMemorySize=368435456";
+
+ String SEARCH_JAVA_OPTS = "-Xms446m -Xmx446m -XX:MaxDirectMemorySize=368435456";
+
Duration STARTUP_TIMEOUT = Duration.ofMinutes(5); // usually < 1min
GenericContainer> startContainer();
diff --git a/smoke-test/tests/containers/containers_test.py b/smoke-test/tests/containers/containers_test.py
index 3ea6661247b9c..227645a87d30a 100644
--- a/smoke-test/tests/containers/containers_test.py
+++ b/smoke-test/tests/containers/containers_test.py
@@ -227,7 +227,7 @@ def test_update_container(frontend_session, ingest_cleanup_data):
"ownerUrn": new_owner,
"resourceUrn": container_urn,
"ownerEntityType": "CORP_USER",
- "type": "urn:li:ownershipType:__system__technical_owner",
+ "ownershipTypeUrn": "urn:li:ownershipType:__system__technical_owner"
}
},
}
diff --git a/smoke-test/tests/cypress/cypress/e2e/glossary/glossary_navigation.js b/smoke-test/tests/cypress/cypress/e2e/glossary/glossary_navigation.js
index f52e4d3984a88..aeceaf99be889 100644
--- a/smoke-test/tests/cypress/cypress/e2e/glossary/glossary_navigation.js
+++ b/smoke-test/tests/cypress/cypress/e2e/glossary/glossary_navigation.js
@@ -17,8 +17,7 @@ describe("glossary sidebar navigation test", () => {
cy.waitTextVisible("Created Term Group!");
cy.waitTextVisible("Create Glossary Term");
cy.enterTextInTestId("create-glossary-entity-modal-name", glossaryTerm);
- cy.clickOptionWithTestId("glossary-entity-modal-create-button");
- cy.waitTextVisible("Created Glossary Term!");
+ cy.clickOptionWithTestId("glossary-entity-modal-create-button").wait(3000);
cy.get('[data-testid="glossary-browser-sidebar"]').contains(glossaryTerm).click().wait(3000);
cy.openThreeDotDropdown();
cy.clickOptionWithTestId("entity-menu-move-button")
diff --git a/smoke-test/tests/cypress/cypress/e2e/mutations/edit_documentation.js b/smoke-test/tests/cypress/cypress/e2e/mutations/edit_documentation.js
index 83b66e2cb2549..5f9758a35ca0e 100644
--- a/smoke-test/tests/cypress/cypress/e2e/mutations/edit_documentation.js
+++ b/smoke-test/tests/cypress/cypress/e2e/mutations/edit_documentation.js
@@ -10,20 +10,20 @@ describe("edit documentation and link to dataset", () => {
cy.visit(
"/dataset/urn:li:dataset:(urn:li:dataPlatform:hive,SampleCypressHiveDataset,PROD)/Schema"
);
- cy.get("[role='tab']").contains("Documentation").click();
+ cy.openEntityTab("Documentation");
cy.waitTextVisible("my hive dataset");
cy.waitTextVisible("Sample doc");
- cy.clickOptionWithText("Edit");
+ cy.clickOptionWithTestId("edit-documentation-button");
cy.focused().clear();
cy.focused().type(documentation_edited);
- cy.get("button").contains("Save").click();
+ cy.clickOptionWithTestId("description-editor-save-button");
cy.waitTextVisible("Description Updated");
cy.waitTextVisible(documentation_edited);
//return documentation to original state
- cy.clickOptionWithText("Edit");
+ cy.clickOptionWithTestId("edit-documentation-button");
cy.focused().clear().wait(1000);
cy.focused().type("my hive dataset");
- cy.get("button").contains("Save").click();
+ cy.clickOptionWithTestId("description-editor-save-button");
cy.waitTextVisible("Description Updated");
cy.waitTextVisible("my hive dataset");
});
@@ -33,21 +33,21 @@ describe("edit documentation and link to dataset", () => {
cy.visit(
"/dataset/urn:li:dataset:(urn:li:dataPlatform:hive,SampleCypressHiveDataset,PROD)/Schema"
);
- cy.get("[role='tab']").contains("Documentation").click();
+ cy.openEntityTab("Documentation");
cy.contains("Sample doc").trigger("mouseover", { force: true });
cy.get('[data-icon="delete"]').click();
cy.waitTextVisible("Link Removed");
- cy.get("button").contains("Add Link").click().wait(1000);
- cy.get('[role="dialog"] #addLinkForm_url').type(wrong_url);
+ cy.clickOptionWithTestId("add-link-button").wait(1000);
+ cy.enterTextInTestId("add-link-modal-url", wrong_url);
cy.waitTextVisible("This field must be a valid url.");
cy.focused().clear();
cy.waitTextVisible("A URL is required.");
- cy.focused().type(correct_url);
+ cy.enterTextInTestId("add-link-modal-url", correct_url);
cy.ensureTextNotPresent("This field must be a valid url.");
- cy.get("#addLinkForm_label").type("Sample doc");
- cy.get('[role="dialog"] button').contains("Add").click();
+ cy.enterTextInTestId("add-link-modal-label", "Sample doc");
+ cy.clickOptionWithTestId("add-link-modal-add-button");
cy.waitTextVisible("Link Added");
- cy.get("[role='tab']").contains("Documentation").click();
+ cy.openEntityTab("Documentation");
cy.get(`[href='${correct_url}']`).should("be.visible");
});
@@ -55,18 +55,18 @@ describe("edit documentation and link to dataset", () => {
cy.loginWithCredentials();
cy.visit("/domain/urn:li:domain:marketing/Entities");
cy.waitTextVisible("SampleCypressKafkaDataset");
- cy.get("button").contains("Add Link").click().wait(1000);
- cy.get('[role="dialog"] #addLinkForm_url').type(wrong_url);
+ cy.clickOptionWithTestId("add-link-button").wait(1000);
+ cy.enterTextInTestId("add-link-modal-url", wrong_url);
cy.waitTextVisible("This field must be a valid url.");
cy.focused().clear();
cy.waitTextVisible("A URL is required.");
- cy.focused().type(correct_url);
+ cy.enterTextInTestId("add-link-modal-url", correct_url);
cy.ensureTextNotPresent("This field must be a valid url.");
- cy.get("#addLinkForm_label").type("Sample doc");
- cy.get('[role="dialog"] button').contains("Add").click();
+ cy.enterTextInTestId("add-link-modal-label", "Sample doc");
+ cy.clickOptionWithTestId("add-link-modal-add-button");
cy.waitTextVisible("Link Added");
- cy.get("[role='tab']").contains("Documentation").click();
- cy.waitTextVisible("Edit");
+ cy.openEntityTab("Documentation");
+ cy.get("[data-testid='edit-documentation-button']").should("be.visible");
cy.get(`[href='${correct_url}']`).should("be.visible");
cy.contains("Sample doc").trigger("mouseover", { force: true });
cy.get('[data-icon="delete"]').click();
@@ -83,14 +83,14 @@ describe("edit documentation and link to dataset", () => {
cy.waitTextVisible("Foo field description has changed");
cy.focused().clear().wait(1000);
cy.focused().type(documentation_edited);
- cy.get("button").contains("Update").click();
+ cy.clickOptionWithTestId("description-modal-update-button");
cy.waitTextVisible("Updated!");
cy.waitTextVisible(documentation_edited);
cy.waitTextVisible("(edited)");
cy.get("tbody [data-icon='edit']").first().click({ force: true });
cy.focused().clear().wait(1000);
cy.focused().type("Foo field description has changed");
- cy.get("button").contains("Update").click();
+ cy.clickOptionWithTestId("description-modal-update-button");
cy.waitTextVisible("Updated!");
cy.waitTextVisible("Foo field description has changed");
cy.waitTextVisible("(edited)");
diff --git a/smoke-test/tests/cypress/cypress/e2e/mutations/ingestion_source.js b/smoke-test/tests/cypress/cypress/e2e/mutations/ingestion_source.js
new file mode 100644
index 0000000000000..6c5dd77810644
--- /dev/null
+++ b/smoke-test/tests/cypress/cypress/e2e/mutations/ingestion_source.js
@@ -0,0 +1,68 @@
+
+const number = Math.floor(Math.random() * 100000);
+const accound_id = `account${number}`;
+const warehouse_id = `warehouse${number}`;
+const username = `user${number}`;
+const password = `password${number}`;
+const role = `role${number}`;
+const ingestion_source_name = `ingestion source ${number}`;
+
+describe("ingestion source creation flow", () => {
+ it("create a ingestion source using ui, verify ingestion source details saved correctly, remove ingestion source", () => {
+ // Go to ingestion page, create a snowflake source
+ cy.loginWithCredentials();
+ cy.goToIngestionPage();
+ cy.clickOptionWithTestId("create-ingestion-source-button");
+ cy.clickOptionWithText("Snowflake");
+ cy.waitTextVisible("Snowflake Recipe");
+ cy.get("#account_id").type(accound_id);
+ cy.get("#warehouse").type(warehouse_id);
+ cy.get("#username").type(username);
+ cy.get("#password").type(password);
+ cy.focused().blur();
+ cy.get("#role").type(role);
+
+ // Verify yaml recipe is generated correctly
+ cy.clickOptionWithTestId("recipe-builder-yaml-button");
+ cy.waitTextVisible("account_id");
+ cy.waitTextVisible(accound_id);
+ cy.waitTextVisible(warehouse_id);
+ cy.waitTextVisible(username);
+ cy.waitTextVisible(password);
+ cy.waitTextVisible(role);
+
+ // Finish creating source
+ cy.clickOptionWithTestId("recipe-builder-next-button");
+ cy.waitTextVisible("Configure an Ingestion Schedule");
+ cy.clickOptionWithTestId("ingestion-schedule-next-button");
+ cy.waitTextVisible("Give this ingestion source a name.");
+ cy.get('[data-testid="source-name-input"]').type(ingestion_source_name);
+ cy.clickOptionWithTestId("ingestion-source-save-button");
+ cy.waitTextVisible("Successfully created ingestion source!").wait(5000)
+ cy.waitTextVisible(ingestion_source_name);
+ cy.get('[data-testid="ingestion-source-table-status"]').contains("Pending...").should("be.visible");
+
+ // Verify ingestion source details are saved correctly
+ cy.get('[data-testid="ingestion-source-table-edit-button"]').first().click();
+ cy.waitTextVisible("Edit Ingestion Source");
+ cy.get("#account_id").should("have.value", accound_id);
+ cy.get("#warehouse").should("have.value", warehouse_id);
+ cy.get("#username").should("have.value", username);
+ cy.get("#password").should("have.value", password);
+ cy.get("#role").should("have.value", role);
+ cy.get("button").contains("Next").click();
+ cy.waitTextVisible("Configure an Ingestion Schedule");
+ cy.clickOptionWithTestId("ingestion-schedule-next-button");
+ cy.get('[data-testid="source-name-input"]').clear().type(ingestion_source_name + " EDITED");
+ cy.clickOptionWithTestId("ingestion-source-save-button");
+ cy.waitTextVisible("Successfully updated ingestion source!");
+ cy.waitTextVisible(ingestion_source_name + " EDITED");
+
+ // Remove ingestion source
+ cy.get('[data-testid="delete-button"]').first().click();
+ cy.waitTextVisible("Confirm Ingestion Source Removal");
+ cy.get("button").contains("Yes").click();
+ cy.waitTextVisible("Removed ingestion source.");
+ cy.ensureTextNotPresent(ingestion_source_name + " EDITED")
+ })
+});
\ No newline at end of file
diff --git a/smoke-test/tests/cypress/cypress/e2e/mutations/managing_secrets.js b/smoke-test/tests/cypress/cypress/e2e/mutations/managing_secrets.js
index 466bb2ef0757e..77fd63b9cae02 100644
--- a/smoke-test/tests/cypress/cypress/e2e/mutations/managing_secrets.js
+++ b/smoke-test/tests/cypress/cypress/e2e/mutations/managing_secrets.js
@@ -8,23 +8,24 @@ const ingestion_source_name = `ingestion source ${number}`;
describe("managing secrets for ingestion creation", () => {
it("create a secret, create ingestion source using a secret, remove a secret", () => {
+ // Navigate to the manage ingestion page → secrets
cy.loginWithCredentials();
- //navigate to the manage ingestion page → secrets
cy.goToIngestionPage();
- cy.clickOptionWithText("Secrets");
- //create a new secret
- cy.clickOptionWithText("Create new secret");
- cy.get('[role="dialog"]').contains("Create a new Secret").should("be.visible");
- cy.get('[role="dialog"] #name').type(`secretname${number}`);
- cy.get('[role="dialog"] #value').type(`secretvalue${number}`);
- cy.get('[role="dialog"] #description').type(`secretdescription${number}`);
- cy.get('#createSecretButton').click();
+ cy.openEntityTab("Secrets");
+
+ // Create a new secret
+ cy.clickOptionWithTestId("create-secret-button");
+ cy.enterTextInTestId('secret-modal-name-input', `secretname${number}`);
+ cy.enterTextInTestId('secret-modal-value-input', `secretvalue${number}`);
+ cy.enterTextInTestId('secret-modal-description-input', `secretdescription${number}`);
+ cy.clickOptionWithTestId("secret-modal-create-button");
cy.waitTextVisible("Successfully created Secret!");
cy.waitTextVisible(`secretname${number}`);
- cy.waitTextVisible(`secretdescription${number}`).wait(5000)//prevent issue with missing secret
- //create an ingestion source using a secret
+ cy.waitTextVisible(`secretdescription${number}`).wait(5000)
+
+ // Create an ingestion source using a secret
cy.goToIngestionPage();
- cy.clickOptionWithText("Create new source");
+ cy.get("#ingestion-create-source").click();
cy.clickOptionWithText("Snowflake");
cy.waitTextVisible("Snowflake Recipe");
cy.get("#account_id").type(accound_id);
@@ -40,11 +41,12 @@ describe("managing secrets for ingestion creation", () => {
cy.waitTextVisible("Give this ingestion source a name.");
cy.get('[data-testid="source-name-input"]').type(ingestion_source_name);
cy.get("button").contains("Save").click();
- cy.waitTextVisible("Successfully created ingestion source!").wait(5000)//prevent issue with missing form data
+ cy.waitTextVisible("Successfully created ingestion source!").wait(5000)
cy.waitTextVisible(ingestion_source_name);
cy.get("button").contains("Pending...").should("be.visible");
- //remove a secret
- cy.clickOptionWithText("Secrets");
+
+ // Remove a secret
+ cy.openEntityTab("Secrets");
cy.waitTextVisible(`secretname${number}`);
cy.get('[data-icon="delete"]').first().click();
cy.waitTextVisible("Confirm Secret Removal");
@@ -52,14 +54,16 @@ describe("managing secrets for ingestion creation", () => {
cy.waitTextVisible("Removed secret.");
cy.ensureTextNotPresent(`secretname${number}`);
cy.ensureTextNotPresent(`secretdescription${number}`);
- //remove ingestion source
+
+ // Remove ingestion source
cy.goToIngestionPage();
cy.get('[data-testid="delete-button"]').first().click();
cy.waitTextVisible("Confirm Ingestion Source Removal");
cy.get("button").contains("Yes").click();
cy.waitTextVisible("Removed ingestion source.");
cy.ensureTextNotPresent(ingestion_source_name)
- //verify secret is not present during ingestion source creation for password dropdown
+
+ // Verify secret is not present during ingestion source creation for password dropdown
cy.clickOptionWithText("Create new source");
cy.clickOptionWithText("Snowflake");
cy.waitTextVisible("Snowflake Recipe");
@@ -68,13 +72,13 @@ describe("managing secrets for ingestion creation", () => {
cy.get("#username").type(username);
cy.get("#password").click().wait(1000);
cy.ensureTextNotPresent(`secretname${number}`);
- //verify secret can be added during ingestion source creation and used successfully
+
+ // Verify secret can be added during ingestion source creation and used successfully
cy.clickOptionWithText("Create Secret");
- cy.get('[role="dialog"]').contains("Create a new Secret").should("be.visible");
- cy.get('[role="dialog"] #name').type(`secretname${number}`);
- cy.get('[role="dialog"] #value').type(`secretvalue${number}`);
- cy.get('[role="dialog"] #description').type(`secretdescription${number}`);
- cy.get('#createSecretButton').click();
+ cy.enterTextInTestId('secret-modal-name-input', `secretname${number}`)
+ cy.enterTextInTestId('secret-modal-value-input', `secretvalue${number}`)
+ cy.enterTextInTestId('secret-modal-description-input', `secretdescription${number}`)
+ cy.clickOptionWithTestId("secret-modal-create-button");
cy.waitTextVisible("Created secret!");
cy.get("#role").type(role);
cy.get("button").contains("Next").click();
@@ -86,6 +90,7 @@ describe("managing secrets for ingestion creation", () => {
cy.waitTextVisible("Successfully created ingestion source!").wait(5000)//prevent issue with missing form data
cy.waitTextVisible(ingestion_source_name);
cy.get("button").contains("Pending...").should("be.visible");
+
//Remove ingestion source and secret
cy.goToIngestionPage();
cy.get('[data-testid="delete-button"]').first().click();