Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(test): ingestion related playwright #17674

Merged
merged 12 commits into from
Sep 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,15 @@ const uniqueID = uuid();

export const REDSHIFT = {
serviceType: 'Redshift',
serviceName: `redshift-ct-test-${uniqueID}`,
serviceName: `redshift-ct-test-with-%-${uniqueID}`,
tableName: 'raw_payments',
DBTTable: 'customers',
description: `This is Redshift-ct-test-${uniqueID} description`,
};

export const POSTGRES = {
serviceType: 'Postgres',
serviceName: `pw-postgres-test-${uuid()}`,
serviceName: `pw-postgres-test-with-%-${uniqueID}`,
tableName: 'order_items',
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
* limitations under the License.
*/

import test from '@playwright/test';
import test, { expect } from '@playwright/test';
import { POSTGRES, REDSHIFT } from '../../constant/service';
import { GlobalSettingOptions } from '../../constant/settings';
import AirflowIngestionClass from '../../support/entity/ingestion/AirflowIngestionClass';
import BigQueryIngestionClass from '../../support/entity/ingestion/BigQueryIngestionClass';
import KafkaIngestionClass from '../../support/entity/ingestion/KafkaIngestionClass';
Expand All @@ -23,8 +25,8 @@ import RedshiftWithDBTIngestionClass from '../../support/entity/ingestion/Redshi
import S3IngestionClass from '../../support/entity/ingestion/S3IngestionClass';
import SnowflakeIngestionClass from '../../support/entity/ingestion/SnowflakeIngestionClass';
import SupersetIngestionClass from '../../support/entity/ingestion/SupersetIngestionClass';
import { redirectToHomePage } from '../../utils/common';
import { settingClick } from '../../utils/sidebar';
import { INVALID_NAMES, redirectToHomePage } from '../../utils/common';
import { settingClick, SettingOptionsType } from '../../utils/sidebar';

const services = [
S3IngestionClass,
Expand All @@ -44,7 +46,10 @@ if (process.env.PLAYWRIGHT_IS_OSS) {
}

// use the admin user to login
test.use({ storageState: 'playwright/.auth/admin.json', trace: 'off' });
test.use({
storageState: 'playwright/.auth/admin.json',
trace: process.env.PLAYWRIGHT_IS_OSS ? 'off' : 'on-first-retry',
});

services.forEach((ServiceClass) => {
const service = new ServiceClass();
Expand All @@ -56,7 +61,10 @@ services.forEach((ServiceClass) => {
test.describe.serial(service.serviceType, { tag: '@ingestion' }, async () => {
test.beforeEach('Visit entity details page', async ({ page }) => {
await redirectToHomePage(page);
await settingClick(page, service.category);
await settingClick(
page,
service.category as unknown as SettingOptionsType
);
});

test(`Create & Ingest ${service.serviceType} service`, async ({ page }) => {
Expand All @@ -73,12 +81,48 @@ services.forEach((ServiceClass) => {
await service.updateScheduleOptions(page);
});

test.fixme(`Service specific tests`, async () => {
await service.runAdditionalTests(test);
});
if (
[POSTGRES.serviceType, REDSHIFT.serviceType].includes(service.serviceType)
) {
test.describe.serial(`Service specific tests`, async () => {
await service.runAdditionalTests(test);
});
}

test(`Delete ${service.serviceType} service`, async ({ page }) => {
await service.deleteService(page);
});
});
});

test.describe('Service form', () => {
test('name field should throw error for invalid name', async ({ page }) => {
await redirectToHomePage(page);
await settingClick(page, GlobalSettingOptions.DATABASES);
await page.click('[data-testid="add-service-button"]');
await page.click('[data-testid="Mysql"]');
await page.click('[data-testid="next-button"]');

await page.waitForSelector('[data-testid="service-name"]');
await page.click('[data-testid="next-button"]');

await expect(page.locator('#name_help')).toBeVisible();
await expect(page.locator('#name_help')).toHaveText('Name is required');

await page.fill(
'[data-testid="service-name"]',
INVALID_NAMES.WITH_SPECIAL_CHARS
);

await expect(page.locator('#name_help')).toBeVisible();
await expect(page.locator('#name_help')).toHaveText(
'Name must contain only letters, numbers, underscores, hyphens, periods, parenthesis, and ampersands.'
);

await page.fill('[data-testid="service-name"]', 'test-service');

await page.click('[data-testid="next-button"]');

await expect(page.getByTestId('step-icon-3')).toHaveClass(/active/);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class MetabaseIngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.Pipeline,
`pw-airflow-${uuid()}`,
`pw-airflow-with-%-${uuid()}`,
'Airflow',
'sample_lineage'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ class BigQueryIngestionClass extends ServiceBaseClass {
filterPattern: string;

constructor() {
super(Services.Database, `pw-bigquery-${uuid()}`, 'BigQuery', 'testtable');
super(
Services.Database,
`pw-bigquery-with-%-${uuid()}`,
'BigQuery',
'testtable'
);

this.filterPattern = 'testschema';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class KafkaIngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.Messaging,
`pw-kafka-${uuid()}`,
`pw-kafka-with-%-${uuid()}`,
'Kafka',
'__transaction_state'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class MetabaseIngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.Dashboard,
`pw-Metabase-${uuid()}`,
`pw-Metabase-with-%-${uuid()}`,
'Metabase',
'jaffle_shop dashboard'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class MlFlowIngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.MLModels,
`pw-Ml-Model-${uuid()}`,
`pw-Ml-Model-with-%-${uuid()}`,
'Mlflow',
'ElasticnetWineModel',
false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ class MysqlIngestionClass extends ServiceBaseClass {
name: string;
tableFilter: string[];
constructor() {
super(Services.Database, `pw-mysql-${uuid()}`, 'Mysql', 'bot_entity');
super(
Services.Database,
`pw-mysql-with-%-${uuid()}`,
'Mysql',
'bot_entity'
);
this.tableFilter = ['bot_entity', 'alert_entity', 'chart_entity'];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
* limitations under the License.
*/

import { Page } from '@playwright/test';
import {
Page,
PlaywrightTestArgs,
PlaywrightWorkerArgs,
TestType,
} from '@playwright/test';
import { POSTGRES } from '../../../constant/service';
import { redirectToHomePage } from '../../../utils/common';
import { visitEntityPage } from '../../../utils/entity';
Expand Down Expand Up @@ -72,7 +77,9 @@ class PostgresIngestionClass extends ServiceBaseClass {
await page.locator('#root\\/schemaFilterPattern\\/includes').press('Enter');
}

async runAdditionalTests(test) {
async runAdditionalTests(
test: TestType<PlaywrightTestArgs, PlaywrightWorkerArgs>
) {
if (process.env.PLAYWRIGHT_IS_OSS) {
test('Add Usage ingestion', async ({ page }) => {
await redirectToHomePage(page);
Expand Down Expand Up @@ -128,9 +135,10 @@ class PostgresIngestionClass extends ServiceBaseClass {

await page.getByRole('tab', { name: 'Queries' }).click();

await page.waitForSelector(
'[data-testid="queries-container"] >> text=selectQuery'
);
// Need to connect to postgres db to get the query log
// await page.waitForSelector(
// '[data-testid="queries-container"] >> text=selectQuery'
// );

await page.click('[data-testid="schema"]');
await page.waitForSelector('[data-testid="related-tables-data"]');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
* limitations under the License.
*/

import { expect, Page } from '@playwright/test';
import {
expect,
Page,
PlaywrightTestArgs,
PlaywrightWorkerArgs,
TestType,
} from '@playwright/test';
import { DBT, HTTP_CONFIG_SOURCE, REDSHIFT } from '../../../constant/service';
import { SidebarItem } from '../../../constant/sidebar';
import { redirectToHomePage } from '../../../utils/common';
Expand Down Expand Up @@ -79,7 +85,9 @@ class RedshiftWithDBTIngestionClass extends ServiceBaseClass {
await page.click('#root\\/includeViews');
}

async runAdditionalTests(test) {
async runAdditionalTests(
test: TestType<PlaywrightTestArgs, PlaywrightWorkerArgs>
) {
test('Add DBT ingestion', async ({ page }) => {
await redirectToHomePage(page);
await visitServiceDetailsPage(
Expand Down Expand Up @@ -153,16 +161,18 @@ class RedshiftWithDBTIngestionClass extends ServiceBaseClass {
await visitEntityPage({
page,
searchTerm: REDSHIFT.DBTTable,
dataTestId: `${REDSHIFT.serviceName}.${REDSHIFT.DBTTable}`,
dataTestId: `${REDSHIFT.serviceName}-${REDSHIFT.DBTTable}`,
});

// Verify tags
await page.waitForSelector('[data-testid="entity-tags"]');
const entityTagsText = await page.textContent(
'[data-testid="entity-tags"]'
);

expect(entityTagsText).toContain(DBT.tagName);
await expect(
page
.getByTestId('entity-right-panel')
.getByTestId('tags-container')
.getByTestId('entity-tags')
).toContainText(DBT.tagName);

// Verify DBT tab is present
await page.click('[data-testid="dbt"]');
Expand All @@ -186,25 +196,15 @@ class RedshiftWithDBTIngestionClass extends ServiceBaseClass {
await page.click('[data-testid="profiler"]');

await page.waitForSelector('[data-testid="profiler-tab-left-panel"]');
const profilerTabLeftPanelText = await page.textContent(
'[data-testid="profiler-tab-left-panel"]'
);
await page.getByRole('menuitem', { name: 'Data Quality' }).click();

expect(profilerTabLeftPanelText).toContain('Data Quality');

await page.waitForSelector(`[data-testid=${DBT.dataQualityTest1}]`);
const dataQualityTest1Text = await page.textContent(
`[data-testid=${DBT.dataQualityTest1}]`
await expect(page.getByTestId(DBT.dataQualityTest1)).toHaveText(
DBT.dataQualityTest1
);

expect(dataQualityTest1Text).toContain(DBT.dataQualityTest1);

await page.waitForSelector(`[data-testid=${DBT.dataQualityTest2}]`);
const dataQualityTest2Text = await page.textContent(
`[data-testid=${DBT.dataQualityTest2}]`
await expect(page.getByTestId(DBT.dataQualityTest1)).toHaveText(
DBT.dataQualityTest1
);

expect(dataQualityTest2Text).toContain(DBT.dataQualityTest2);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class S3IngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.Storage,
`pw-s3-storage-${uuid()}`,
`pw-s3-storage-with-%-${uuid()}`,
'S3',
'awsathena-database'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ import ServiceBaseClass from './ServiceBaseClass';
class SnowflakeIngestionClass extends ServiceBaseClass {
schema: string;
constructor() {
super(Services.Database, `pw-snowflake-${uuid()}`, 'Snowflake', 'CUSTOMER');
super(
Services.Database,
`pw-snowflake-with-%-${uuid()}`,
'Snowflake',
'CUSTOMER'
);
this.schema = 'TPCH_SF1000';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SupersetIngestionClass extends ServiceBaseClass {
constructor() {
super(
Services.Dashboard,
`pw-Superset-${uuid()}`,
`pw-Superset-with-%-${uuid()}`,
'Superset',
"World Bank's Data"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export const testConnection = async (page: Page) => {

await page.waitForSelector('[data-testid="success-badge"]', {
state: 'attached',
timeout: 2 * 60 * 1000,
timeout: 2.5 * 60 * 1000,
});

await expect(page.getByTestId('messag-text')).toContainText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
} from '../constant/settings';
import { SidebarItem, SIDEBAR_LIST_ITEMS } from '../constant/sidebar';

export type SettingOptionsType =
| keyof typeof SETTINGS_OPTIONS_PATH
| keyof typeof SETTING_CUSTOM_PROPERTIES_PATH;

export const clickOnLogo = async (page: Page) => {
await page.click('#openmetadata_logo > [data-testid="image"]');
await page.mouse.move(1280, 0); // Move mouse to top right corner
Expand All @@ -38,7 +42,7 @@ export const sidebarClick = async (page: Page, id: string) => {

export const settingClick = async (
page: Page,
dataTestId: string,
dataTestId: SettingOptionsType,
isCustomProperty?: boolean
) => {
let paths = SETTINGS_OPTIONS_PATH[dataTestId];
Expand Down
Loading