[functional test][saved objects] update tests for additional copy saved objects to space (#74907)
Co-authored-by: Larry Gregory <lgregorydev@gmail.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
d56b792e9c
commit
5627ab3193
4 changed files with 100 additions and 44 deletions
|
@ -49,12 +49,13 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.savedObjects.checkImportSucceeded();
|
||||
await PageObjects.savedObjects.clickImportDone();
|
||||
|
||||
// get all the elements in the table, and index them by the 'title' visible text field
|
||||
const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title');
|
||||
log.debug("check that 'Log Agents' is in table as a visualization");
|
||||
expect(elements['Log Agents'].objectType).to.eql('visualization');
|
||||
expect(await PageObjects.savedObjects.getObjectTypeByTitle('Log Agents')).to.eql(
|
||||
'visualization'
|
||||
);
|
||||
|
||||
await PageObjects.savedObjects.clickRelationshipsByTitle('logstash-*');
|
||||
|
||||
await elements['logstash-*'].relationshipsElement.click();
|
||||
const flyout = keyBy(await PageObjects.savedObjects.getRelationshipFlyout(), 'title');
|
||||
log.debug(
|
||||
"check that 'Shared-Item Visualization AreaChart' shows 'logstash-*' as it's Parent"
|
||||
|
@ -150,8 +151,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('should not import saved objects linked to saved searches when saved search index pattern does not exist', async function () {
|
||||
const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title');
|
||||
await elements['logstash-*'].checkbox.click();
|
||||
await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*');
|
||||
await PageObjects.savedObjects.clickDelete();
|
||||
|
||||
await PageObjects.savedObjects.importFile(
|
||||
|
@ -182,8 +182,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
it('should import saved objects with index patterns when index patterns does not exists', async () => {
|
||||
// First, we need to delete the index pattern
|
||||
const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title');
|
||||
await elements['logstash-*'].checkbox.click();
|
||||
await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*');
|
||||
await PageObjects.savedObjects.clickDelete();
|
||||
|
||||
// Then, import the objects
|
||||
|
@ -321,8 +320,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.savedObjects.clickImportDone();
|
||||
|
||||
// Second, we need to delete the index pattern
|
||||
const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title');
|
||||
await elements['logstash-*'].checkbox.click();
|
||||
await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*');
|
||||
await PageObjects.savedObjects.clickDelete();
|
||||
|
||||
// Last, import a saved object connected to the saved search
|
||||
|
@ -353,8 +351,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
it('should import saved objects with index patterns when index patterns does not exists', async () => {
|
||||
// First, we need to delete the index pattern
|
||||
const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title');
|
||||
await elements['logstash-*'].checkbox.click();
|
||||
await PageObjects.savedObjects.clickCheckboxByTitle('logstash-*');
|
||||
await PageObjects.savedObjects.clickDelete();
|
||||
|
||||
// Then, import the objects
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { keyBy } from 'lodash';
|
||||
import { map as mapAsync } from 'bluebird';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
|
@ -34,6 +35,8 @@ export function SavedObjectsPageProvider({ getService, getPageObjects }: FtrProv
|
|||
await searchBox.clearValue();
|
||||
await searchBox.type(objectName);
|
||||
await searchBox.pressKeys(browser.keys.ENTER);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await this.waitTableIsLoaded();
|
||||
}
|
||||
|
||||
async importFile(path: string, overwriteAll = true) {
|
||||
|
@ -99,6 +102,56 @@ export function SavedObjectsPageProvider({ getService, getPageObjects }: FtrProv
|
|||
});
|
||||
}
|
||||
|
||||
async clickRelationshipsByTitle(title: string) {
|
||||
const table = keyBy(await this.getElementsInTable(), 'title');
|
||||
// should we check if table size > 0 and log error if not?
|
||||
if (table[title].menuElement) {
|
||||
log.debug(`we found a context menu element for (${title}) so click it`);
|
||||
await table[title].menuElement?.click();
|
||||
// Wait for context menu to render
|
||||
const menuPanel = await find.byCssSelector('.euiContextMenuPanel');
|
||||
await (await menuPanel.findByTestSubject('savedObjectsTableAction-relationships')).click();
|
||||
} else {
|
||||
log.debug(
|
||||
`we didn't find a menu element so should be a relastionships element for (${title}) to click`
|
||||
);
|
||||
// or the action elements are on the row without the menu
|
||||
await table[title].relationshipsElement?.click();
|
||||
}
|
||||
}
|
||||
|
||||
async clickCopyToSpaceByTitle(title: string) {
|
||||
const table = keyBy(await this.getElementsInTable(), 'title');
|
||||
// should we check if table size > 0 and log error if not?
|
||||
if (table[title].menuElement) {
|
||||
log.debug(`we found a context menu element for (${title}) so click it`);
|
||||
await table[title].menuElement?.click();
|
||||
// Wait for context menu to render
|
||||
const menuPanel = await find.byCssSelector('.euiContextMenuPanel');
|
||||
await (
|
||||
await menuPanel.findByTestSubject('savedObjectsTableAction-copy_saved_objects_to_space')
|
||||
).click();
|
||||
} else {
|
||||
log.debug(
|
||||
`we didn't find a menu element so should be a "copy to space" element for (${title}) to click`
|
||||
);
|
||||
// or the action elements are on the row without the menu
|
||||
await table[title].copySaveObjectsElement?.click();
|
||||
}
|
||||
}
|
||||
|
||||
async clickCheckboxByTitle(title: string) {
|
||||
const table = keyBy(await this.getElementsInTable(), 'title');
|
||||
// should we check if table size > 0 and log error if not?
|
||||
await table[title].checkbox.click();
|
||||
}
|
||||
|
||||
async getObjectTypeByTitle(title: string) {
|
||||
const table = keyBy(await this.getElementsInTable(), 'title');
|
||||
// should we check if table size > 0 and log error if not?
|
||||
return table[title].objectType;
|
||||
}
|
||||
|
||||
async getElementsInTable() {
|
||||
const rows = await testSubjects.findAll('~savedObjectsTableRow');
|
||||
return mapAsync(rows, async (row) => {
|
||||
|
@ -107,23 +160,45 @@ export function SavedObjectsPageProvider({ getService, getPageObjects }: FtrProv
|
|||
const objectType = await row.findByTestSubject('objectType');
|
||||
const titleElement = await row.findByTestSubject('savedObjectsTableRowTitle');
|
||||
// not all rows have inspect button - Advanced Settings objects don't
|
||||
let inspectElement;
|
||||
const innerHtml = await row.getAttribute('innerHTML');
|
||||
if (innerHtml.includes('Inspect')) {
|
||||
inspectElement = await row.findByTestSubject('savedObjectsTableAction-inspect');
|
||||
} else {
|
||||
inspectElement = null;
|
||||
// Advanced Settings has 2 actions,
|
||||
// data-test-subj="savedObjectsTableAction-relationships"
|
||||
// data-test-subj="savedObjectsTableAction-copy_saved_objects_to_space"
|
||||
// Some other objects have the ...
|
||||
// data-test-subj="euiCollapsedItemActionsButton"
|
||||
// Maybe some objects still have the inspect element visible?
|
||||
// !!! Also note that since we don't have spaces on OSS, the actions for the same object can be different depending on OSS or not
|
||||
let menuElement = null;
|
||||
let inspectElement = null;
|
||||
let relationshipsElement = null;
|
||||
let copySaveObjectsElement = null;
|
||||
const actions = await row.findByClassName('euiTableRowCell--hasActions');
|
||||
// getting the innerHTML and checking if it 'includes' a string is faster than a timeout looking for each element
|
||||
const actionsHTML = await actions.getAttribute('innerHTML');
|
||||
if (actionsHTML.includes('euiCollapsedItemActionsButton')) {
|
||||
menuElement = await row.findByTestSubject('euiCollapsedItemActionsButton');
|
||||
}
|
||||
const relationshipsElement = await row.findByTestSubject(
|
||||
if (actionsHTML.includes('savedObjectsTableAction-inspect')) {
|
||||
inspectElement = await row.findByTestSubject('savedObjectsTableAction-inspect');
|
||||
}
|
||||
if (actionsHTML.includes('savedObjectsTableAction-relationships')) {
|
||||
relationshipsElement = await row.findByTestSubject(
|
||||
'savedObjectsTableAction-relationships'
|
||||
);
|
||||
}
|
||||
if (actionsHTML.includes('savedObjectsTableAction-copy_saved_objects_to_space')) {
|
||||
copySaveObjectsElement = await row.findByTestSubject(
|
||||
'savedObjectsTableAction-copy_saved_objects_to_space'
|
||||
);
|
||||
}
|
||||
return {
|
||||
checkbox,
|
||||
objectType: await objectType.getAttribute('aria-label'),
|
||||
titleElement,
|
||||
title: await titleElement.getVisibleText(),
|
||||
menuElement,
|
||||
inspectElement,
|
||||
relationshipsElement,
|
||||
copySaveObjectsElement,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ export default function spaceSelectorFunctonalTests({
|
|||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['security', 'settings', 'copySavedObjectsToSpace']);
|
||||
|
||||
// TODO: Flakey again https://github.com/elastic/kibana/issues/44575#issuecomment-528864287
|
||||
describe.skip('Copy Saved Objects to Space', function () {
|
||||
describe('Copy Saved Objects to Space', function () {
|
||||
before(async () => {
|
||||
await esArchiver.load('spaces/copy_saved_objects');
|
||||
|
||||
|
@ -32,6 +31,7 @@ export default function spaceSelectorFunctonalTests({
|
|||
disabledFeatures: [],
|
||||
});
|
||||
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login(undefined, undefined, {
|
||||
expectSpaceSelector: true,
|
||||
});
|
||||
|
|
|
@ -15,31 +15,15 @@ export function CopySavedObjectsToSpacePageProvider({
|
|||
getPageObjects,
|
||||
}: FtrProviderContext) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const find = getService('find');
|
||||
const { savedObjects } = getPageObjects(['savedObjects']);
|
||||
const { savedObjects, common } = getPageObjects(['savedObjects', 'common']);
|
||||
|
||||
return {
|
||||
async openCopyToSpaceFlyoutForObject(objectName: string) {
|
||||
// This searchForObject narrows down the objects to those matching ANY of the words in the objectName.
|
||||
// Hopefully the one we want is on the first page of results.
|
||||
await savedObjects.searchForObject(objectName);
|
||||
|
||||
// Click action button to show context menu
|
||||
await find.clickByCssSelector(
|
||||
'table.euiTable tbody tr.euiTableRow td.euiTableRowCell:last-child .euiButtonIcon'
|
||||
);
|
||||
|
||||
// Wait for context menu to render
|
||||
await find.existsByCssSelector('.euiContextMenuPanel');
|
||||
|
||||
const actions = await find.allByCssSelector('.euiContextMenuItem');
|
||||
|
||||
for (const action of actions) {
|
||||
const actionText = await action.getVisibleText();
|
||||
if (actionText === 'Copy to space') {
|
||||
await action.click();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await common.sleep(1000);
|
||||
await savedObjects.clickCopyToSpaceByTitle(objectName);
|
||||
await testSubjects.existOrFail('copy-to-space-flyout');
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue