From 889ce000eb18bf60d3dc65ec0b39dbf705c7184b Mon Sep 17 00:00:00 2001 From: Sid Date: Thu, 21 Nov 2024 15:15:13 +0100 Subject: [PATCH] [API keys] Improve functional tests for API keys management page (#200110) Closes https://github.com/elastic/kibana/issues/200756 ## Summary Enhance existing functional tests for API Keys querying to test filters and toggles while querying API keys. ### Notes The following tests were added: - Toggling the following filters displays the correct keys - Personal, Managed, Cross cluster types - Active or expired keys - Filtering by username by clicking the dropdown list - Added test for querying using the search bar **but it is skipped** for now as we'd like to fix the behavior. Tracked by https://github.com/elastic/kibana/issues/195795 ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios= - [ ] The PR description includes the appropriate Release Notes section, and the correct `release_node:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Elastic Machine --- .../api_keys/api_keys_grid/api_keys_table.tsx | 7 + .../functional/apps/api_keys/home_page.ts | 129 ++++++++++++++++++ .../functional/page_objects/api_keys_page.ts | 29 ++++ 3 files changed, 165 insertions(+) diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_table.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_table.tsx index f536b5838bab..8ceff7f1460f 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_table.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_table.tsx @@ -274,6 +274,7 @@ export const ApiKeysTable: FunctionComponent = ({ = ({ que onFilterChange({ ...filters, type: filters.type === 'rest' ? undefined : 'rest' }); }} withNext={types.includes('cross_cluster') || types.includes('managed')} + data-test-subj="personalFilterButton" > = ({ que }); }} withNext={types.includes('managed')} + data-test-subj="crossClusterFilterButton" > = ({ que type: filters.type === 'managed' ? undefined : 'managed', }); }} + data-test-subj="managedFilterButton" > = ({ } }} withNext={true} + data-test-subj="activeFilterButton" > = ({ onFilterChange({ ...filters, expired: true }); } }} + data-test-subj="expiredFilterButton" > = ({ que numFilters={usernames.length} hasActiveFilters={numActiveFilters ? true : false} numActiveFilters={numActiveFilters} + data-test-subj="ownerFilterButton" > { ); }); }); + + describe('querying API keys', function () { + before(async () => { + await clearAllApiKeys(es, log); + await security.testUser.setRoles(['kibana_admin', 'test_api_keys']); + + await es.transport.request({ + method: 'POST', + path: '/_security/cross_cluster/api_key', + body: { + name: 'test_cross_cluster', + expiration: '1d', + access: { + search: [ + { + names: ['*'], + }, + ], + replication: [ + { + names: ['*'], + }, + ], + }, + }, + }); + + await es.security.createApiKey({ + name: 'my api key', + expiration: '1d', + role_descriptors: { + role_1: {}, + }, + metadata: { + managed: true, + }, + }); + + await es.security.createApiKey({ + name: 'Alerting: Managed', + expiration: '1d', + role_descriptors: { + role_1: {}, + }, + }); + + await es.security.createApiKey({ + name: 'test_api_key', + expiration: '1s', + role_descriptors: { + role_1: {}, + }, + }); + + await es.security.grantApiKey({ + api_key: { + name: 'test_user_api_key', + expiration: '1d', + }, + grant_type: 'password', + run_as: 'test_user', + username: 'elastic', + password: 'changeme', + }); + + await pageObjects.common.navigateToApp('apiKeys'); + }); + + after(async () => { + await security.testUser.restoreDefaults(); + await clearAllApiKeys(es, log); + }); + + it('active/expired filter buttons work as expected', async () => { + await pageObjects.apiKeys.clickExpiryFilters('active'); + await ensureApiKeysExist(['my api key', 'Alerting: Managed', 'test_cross_cluster']); + expect(await pageObjects.apiKeys.doesApiKeyExist('test_api_key')).to.be(false); + + await pageObjects.apiKeys.clickExpiryFilters('expired'); + await ensureApiKeysExist(['test_api_key']); + expect(await pageObjects.apiKeys.doesApiKeyExist('my api key')).to.be(false); + + // reset filter buttons + await pageObjects.apiKeys.clickExpiryFilters('expired'); + }); + + it('api key type filter buttons work as expected', async () => { + await pageObjects.apiKeys.clickTypeFilters('personal'); + + await ensureApiKeysExist(['test_api_key']); + + await pageObjects.apiKeys.clickTypeFilters('cross_cluster'); + + await ensureApiKeysExist(['test_cross_cluster']); + + await pageObjects.apiKeys.clickTypeFilters('managed'); + + await ensureApiKeysExist(['my api key', 'Alerting: Managed']); + + // reset filters by simulate clicking the managed filter button again + await pageObjects.apiKeys.clickTypeFilters('managed'); + }); + + it('username filter buttons work as expected', async () => { + await pageObjects.apiKeys.clickUserNameDropdown(); + expect( + await testSubjects.exists('userProfileSelectableOption-system_indices_superuser') + ).to.be(true); + expect(await testSubjects.exists('userProfileSelectableOption-test_user')).to.be(true); + + await testSubjects.click('userProfileSelectableOption-test_user'); + + await ensureApiKeysExist(['test_user_api_key']); + await testSubjects.click('userProfileSelectableOption-test_user'); + + await testSubjects.click('userProfileSelectableOption-system_indices_superuser'); + + await ensureApiKeysExist(['my api key', 'Alerting: Managed', 'test_cross_cluster']); + }); + + it.skip('search bar works as expected', async () => { + await pageObjects.apiKeys.setSearchBarValue('test_user_api_key'); + + await ensureApiKeysExist(['test_user_api_key']); + + await pageObjects.apiKeys.setSearchBarValue('"my api key"'); + await ensureApiKeysExist(['my api key']); + }); + }); }); }; diff --git a/x-pack/test/functional/page_objects/api_keys_page.ts b/x-pack/test/functional/page_objects/api_keys_page.ts index 9b196f70eeef..efff9930f10a 100644 --- a/x-pack/test/functional/page_objects/api_keys_page.ts +++ b/x-pack/test/functional/page_objects/api_keys_page.ts @@ -157,5 +157,34 @@ export function ApiKeysPageProvider({ getService }: FtrProviderContext) { const toast = await testSubjects.find('updateApiKeySuccessToast'); return toast.getVisibleText(); }, + + async clickExpiryFilters(type: 'active' | 'expired') { + const button = await testSubjects.find( + type === 'active' ? 'activeFilterButton' : 'expiredFilterButton' + ); + return button.click(); + }, + + async clickTypeFilters(type: 'personal' | 'managed' | 'cross_cluster') { + const buttonMap = { + personal: 'personalFilterButton', + managed: 'managedFilterButton', + cross_cluster: 'crossClusterFilterButton', + }; + + const button = await testSubjects.find(buttonMap[type]); + return button.click(); + }, + + async clickUserNameDropdown() { + const button = await testSubjects.find('ownerFilterButton'); + return button.click(); + }, + + async setSearchBarValue(query: string) { + const searchBar = await testSubjects.find('apiKeysSearchBar'); + await searchBar.clearValue(); + return searchBar.type(query); + }, }; }