Skip to content

Commit

Permalink
MINOR: supported all_index in search index configuration form (#16571)
Browse files Browse the repository at this point in the history
* supported all_index in search index configuration form

* allow clear in select widget

* supported tree select for the entities

* playwright test

* added env for the run application status test

* fix beta badge color, color of checkbox and changes as per comments

* minor fix

* fix sonar issue
  • Loading branch information
Ashish8689 authored Jul 9, 2024
1 parent 27f4d97 commit 15ae2d3
Show file tree
Hide file tree
Showing 12 changed files with 616 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@
"dashboardService",
"pipelineService",
"mlmodelService",
"storageService",
"metadataService",
"searchService",
"entityReportData",
"webAnalyticEntityViewReportData",
"webAnalyticUserActivityReportData",
"domain",
"storedProcedure",
"storageService",
"dataProduct",
"testCaseResolutionStatus"
],
Expand All @@ -47,4 +48,4 @@
"scheduleTimeline": "Custom",
"cronExpression": "0 0 * * *"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@
"dashboardService",
"pipelineService",
"mlmodelService",
"storageService",
"metadataService",
"searchService",
"entityReportData",
"webAnalyticEntityViewReportData",
"webAnalyticUserActivityReportData",
"domain",
"storedProcedure",
"storageService",
"dataProduct"
"dataProduct",
"testCaseResolutionStatus"
],
"recreateIndex": true,
"batchSize": "100",
"searchIndexMappingLanguage": "EN"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* Copyright 2024 Collate.
* 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 test, { expect, Page } from '@playwright/test';
import { GlobalSettingOptions } from '../../constant/settings';
import { getApiContext, redirectToHomePage } from '../../utils/common';
import { settingClick } from '../../utils/sidebar';

// use the admin user to login
test.use({ storageState: 'playwright/.auth/admin.json' });

const verifyApplicationTriggerToastData = async (page: Page) => {
await expect(page.getByRole('alert').first()).toHaveText(
/Application triggered successfully/
);

await page.getByLabel('close').first().click();
};

const verifyLastExecutionStatus = async (page: Page) => {
const { apiContext } = await getApiContext(page);

await expect
.poll(
async () => {
const response = await apiContext
.get(
'/api/v1/apps/name/SearchIndexingApplication/status?offset=0&limit=1'
)
.then((res) => res.json());

return response.data[0]?.status;
},
{
// Custom expect message for reporting, optional.
message: 'To get the last run execution status as success',
intervals: [30_000],
timeout: 300_000,
}
)
.toBe('success');

await page.reload();

await page.waitForSelector('[data-testid="app-run-history-table"]');

await expect(page.getByTestId('pipeline-status')).toContainText('Success');
};

const verifyLastExecutionRun = async (page: Page) => {
const response = await page.waitForResponse(
'/api/v1/apps/name/SearchIndexingApplication/status?offset=0&limit=1'
);

expect(response.status()).toBe(200);

const responseData = await response.json();
if (responseData.data.length > 0) {
expect(responseData.data).toHaveLength(1);

if (responseData.data[0].status === 'running') {
// wait for success status
await verifyLastExecutionStatus(page);
} else {
expect(responseData.data[0].status).toBe('success');
}
}
};

test('Search Index Application', async ({ page }) => {
await test.step('Visit Application page', async () => {
await redirectToHomePage(page);
await settingClick(page, GlobalSettingOptions.APPLICATIONS);
});

await test.step('Verify last execution run', async () => {
await page
.locator(
'[data-testid="search-indexing-application-card"] [data-testid="config-btn"]'
)
.click();
await verifyLastExecutionRun(page);
});

await test.step('Edit application', async () => {
await page.click('[data-testid="edit-button"]');
await page.click('[data-testid="cron-type"]');
await page.click('.rc-virtual-list [title="None"]');

const deployResponse = page.waitForResponse('/api/v1/apps/*');
await page.click('.ant-modal-body [data-testid="deploy-button"]');
await deployResponse;

await expect(page.getByRole('alert').first()).toHaveText(
/Schedule saved successfully/
);

await page.getByLabel('close').first().click();

expect(await page.innerText('[data-testid="schedule-type"]')).toContain(
'None'
);

await page.click('[data-testid="configuration"]');
await page.fill('#root\\/batchSize', '0');

await page.getByTitle('chart').getByLabel('close').click();

await page.click(
'[data-testid="select-widget"] > .ant-select-selector > .ant-select-selection-item'
);
await page.click('[data-testid="select-option-JP"]');

const responseAfterSubmit = page.waitForResponse('/api/v1/apps/*');
await page.click('[data-testid="submit-btn"]');
await responseAfterSubmit;

await expect(page.getByRole('alert').first()).toHaveText(
/Configuration saved successfully/
);

await page.getByLabel('close').first().click();
});

await test.step('Uninstall application', async () => {
await page.click('[data-testid="manage-button"]');
await page.click('[data-testid="uninstall-button-title"]');

const deleteRequest = page.waitForResponse(
'/api/v1/apps/name/SearchIndexingApplication?hardDelete=true'
);
await page.click('[data-testid="save-button"]');
await deleteRequest;

await expect(page.getByRole('alert').first()).toHaveText(
/Application uninstalled/
);

await page.getByLabel('close').first().click();

const card1 = page.locator(
'[data-testid="search-indexing-application-card"]'
);

expect(await card1.isVisible()).toBe(false);
});

await test.step('Install application', async () => {
await page.click('[data-testid="add-application"]');

// Verify response status code
const getMarketPlaceResponse = await page.waitForResponse(
'/api/v1/apps/marketplace?limit=*'
);

expect(getMarketPlaceResponse.status()).toBe(200);

await page.click(
'[data-testid="search-indexing-application-card"] [data-testid="config-btn"]'
);
await page.click('[data-testid="install-application"]');
await page.click('[data-testid="save-button"]');
await page.click('[data-testid="submit-btn"]');
await page.click('[data-testid="cron-type"]');
await page.click('.rc-virtual-list [title="None"]');

expect(await page.innerText('[data-testid="cron-type"]')).toContain('None');

const installApplicationResponse = page.waitForResponse('api/v1/apps');
await page.click('[data-testid="deploy-button"]');
await installApplicationResponse;

await expect(page.getByRole('alert').first()).toHaveText(
/Application installed successfully/
);

await page.getByLabel('close').first().click();

const card = page.locator(
'[data-testid="search-indexing-application-card"]'
);

expect(await card.isVisible()).toBe(true);
});

if (process.env.isOss) {
await test.step('Run application', async () => {
test.slow(true); // Test time shouldn't exceed while re-fetching the history API.

await page.click(
'[data-testid="search-indexing-application-card"] [data-testid="config-btn"]'
);

const triggerPipelineResponse = page.waitForResponse(
'/api/v1/apps/trigger/SearchIndexingApplication'
);
await page.click('[data-testid="run-now-button"]');

await triggerPipelineResponse;

await verifyApplicationTriggerToastData(page);

await page.reload();

await verifyLastExecutionRun(page);
});
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
*/
import { APIRequestContext, expect, Page } from '@playwright/test';
import {
ENTITY_PATH,
EntityTypeEndpoint,
ENTITY_PATH,
} from '../support/entity/Entity.interface';
import { UserClass } from '../support/user/UserClass';
import { uuid } from './common';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { DatabaseServiceType } from '../../../../../generated/entity/data/databa
import { MetadataServiceType } from '../../../../../generated/entity/services/metadataService';
import { MlModelServiceType } from '../../../../../generated/entity/services/mlmodelService';
import { PipelineServiceType } from '../../../../../generated/entity/services/pipelineService';
import { useApplicationStore } from '../../../../../hooks/useApplicationStore';
import { errorMsg, getServiceLogo } from '../../../../../utils/CommonUtils';
import ServiceUtilClassBase from '../../../../../utils/ServiceUtilClassBase';
import Searchbar from '../../../../common/SearchBarComponent/SearchBar.component';
Expand All @@ -44,7 +43,6 @@ const SelectServiceType = ({
onCancel,
onNext,
}: SelectServiceTypeProps) => {
const { theme } = useApplicationStore();
const { t } = useTranslation();
const [category, setCategory] = useState('');
const [connectorSearchTerm, setConnectorSearchTerm] = useState('');
Expand Down Expand Up @@ -146,11 +144,7 @@ const SelectServiceType = ({
{BETA_SERVICES.includes(
type as DatabaseServiceType | PipelineServiceType
) ? (
<Badge
className="service-beta-tag"
color={theme.primaryColor}
count={t('label.beta')}
/>
<Badge className="service-beta-tag" count={t('label.beta')} />
) : null}
</p>
</Button>
Expand Down
Loading

0 comments on commit 15ae2d3

Please sign in to comment.