Skip to content

Commit

Permalink
Unskips api key functional tests in MKI (elastic#196572)
Browse files Browse the repository at this point in the history
Closes elastic#186619

## Summary

Tested against a new QA project, the platform security api key
functional test now passes as expected.

Update: the serverless functional UI API key test has also been modified
to account for a non-empty start state, and to be non-destructive. If
any API keys exist prior to running this test, they will not interfere
with the test and they will remain after the test completes.

Flaky test runners:
-
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7184
- Security re-run
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/7195
  • Loading branch information
jeramysoucy authored Oct 21, 2024
1 parent 082a897 commit 492a9a4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export const ApiKeysTable: FunctionComponent<ApiKeysTableProps> = ({
color: 'danger',
onClick: (item) => onDelete([item]),
available: deletable,
'data-test-subj': 'apiKeysTableDeleteAction',
'data-test-subj': (item) => `apiKeysTableDeleteAction-${item.name}`,
},
],
});
Expand Down
18 changes: 16 additions & 2 deletions x-pack/test/functional/page_objects/api_keys_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,25 @@ export function ApiKeysPageProvider({ getService }: FtrProviderContext) {
return euiCallOutHeader.getVisibleText();
},

async isPromptPage() {
return await testSubjects.exists('apiKeysCreatePromptButton');
},

async getApiKeysFirstPromptTitle() {
const titlePromptElem = await find.byCssSelector('.euiEmptyPrompt .euiTitle');
return await titlePromptElem.getVisibleText();
},

async deleteApiKeyByName(apiKeyName: string) {
await testSubjects.click(`apiKeysTableDeleteAction-${apiKeyName}`);
await testSubjects.click('confirmModalConfirmButton');
await testSubjects.waitForDeleted(`apiKeyRowName-${apiKeyName}`);
},

async deleteAllApiKeyOneByOne() {
const hasApiKeysToDelete = await testSubjects.exists('apiKeysTableDeleteAction');
const hasApiKeysToDelete = await testSubjects.exists('*apiKeysTableDeleteAction');
if (hasApiKeysToDelete) {
const apiKeysToDelete = await testSubjects.findAll('apiKeysTableDeleteAction');
const apiKeysToDelete = await testSubjects.findAll('*apiKeysTableDeleteAction');
for (const element of apiKeysToDelete) {
await element.click();
await testSubjects.click('confirmModalConfirmButton');
Expand All @@ -113,6 +123,10 @@ export function ApiKeysPageProvider({ getService }: FtrProviderContext) {
await testSubjects.existOrFail(`apiKeyRowName-${apiKeyName}`);
},

async doesApiKeyExist(apiKeyName: string) {
return await testSubjects.exists(`apiKeyRowName-${apiKeyName}`);
},

async getMetadataSwitch() {
return await testSubjects.find('apiKeysMetadataSwitch');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,31 @@
*/

import expect from '@kbn/expect';
import { Client } from '@elastic/elasticsearch';
import { ToolingLog } from '@kbn/tooling-log';
import { FtrProviderContext } from '../../../ftr_provider_context';

async function clearAllApiKeys(esClient: Client, logger: ToolingLog) {
const existingKeys = await esClient.security.queryApiKeys();
if (existingKeys.count > 0) {
await Promise.all(
existingKeys.api_keys.map(async (key) => {
await esClient.security.invalidateApiKey({ ids: [key.id] });
})
);
} else {
logger.debug('No API keys to delete.');
}
}

export default ({ getPageObjects, getService }: FtrProviderContext) => {
const pageObjects = getPageObjects(['common', 'svlCommonPage', 'apiKeys']);
const browser = getService('browser');
const es = getService('es');
const log = getService('log');

describe('API keys', function () {
// TimeoutError: Waiting for element to be located By(css selector, [data-test-subj="apiKeysCreatePromptButton"]) Wait timed out after 10028ms
this.tags(['failsOnMKI']);
before(async () => {
await pageObjects.svlCommonPage.loginAsAdmin();
});

after(async () => {
await clearAllApiKeys(es, log);
});

it('should create and delete API keys correctly', async () => {
await pageObjects.common.navigateToUrl('management', 'security/api_keys', {
shouldUseHashForSubUrl: false,
});

const apiKeyName = 'Happy API Key';
await pageObjects.apiKeys.clickOnPromptCreateApiKey();
// name needs to be unique because we will confirm deletion by name
const apiKeyName = `API Key ${Date.now()}`;

// If there are any existing API keys (e.g. will occur on projects created with QAF),
// the table will be displayed. Otherwise, the empty prompt is displayed.
const isPromptPage = await pageObjects.apiKeys.isPromptPage();
if (isPromptPage) await pageObjects.apiKeys.clickOnPromptCreateApiKey();
else await pageObjects.apiKeys.clickOnTableCreateApiKey();

expect(await browser.getCurrentUrl()).to.contain('app/management/security/api_keys/create');
expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('Create API key');

Expand All @@ -61,7 +45,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
expect(await pageObjects.apiKeys.isApiKeyModalExists()).to.be(false);
expect(newApiKeyCreation).to.be(`Created API key '${apiKeyName}'`);

await pageObjects.apiKeys.deleteAllApiKeyOneByOne();
await pageObjects.apiKeys.ensureApiKeyExists(apiKeyName);
await pageObjects.apiKeys.deleteApiKeyByName(apiKeyName);
expect(await pageObjects.apiKeys.doesApiKeyExist(apiKeyName)).to.be(false);
});
});
};

0 comments on commit 492a9a4

Please sign in to comment.