mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-08 05:46:24 +02:00
Merge remote-tracking branch 'remotes/from/ce/main'
This commit is contained in:
commit
bb5ed03b4c
101
ui/e2e/tests/superuser/access/entities.spec.ts
Normal file
101
ui/e2e/tests/superuser/access/entities.spec.ts
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('entities workflow', async ({ page }) => {
|
||||
await test.step('should display entities page', async () => {
|
||||
await page.goto('dashboard');
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Entities' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Entities', exact: true })).toContainText('Entities');
|
||||
await expect(page.getByRole('heading', { name: 'No entities yet' })).toContainText('No entities yet');
|
||||
await expect(page.getByText('A list of entities in this')).toContainText(
|
||||
'A list of entities in this namespace will be listed here. Create your first entity to get started.'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('create policy', async () => {
|
||||
await page.getByRole('link', { name: 'ACL Policies' }).click();
|
||||
await page.getByRole('link', { name: 'Create ACL policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('test-policy');
|
||||
await page.getByRole('radio', { name: 'Code editor' }).check();
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Policy editor' })
|
||||
.fill('path "auth/token/lookup-self" { capabilities = ["read"]}');
|
||||
await page.getByRole('button', { name: 'Create policy' }).click();
|
||||
await page.getByRole('link', { name: 'Entities' }).click();
|
||||
});
|
||||
|
||||
await test.step('create entity', async () => {
|
||||
await page.getByRole('link', { name: 'Create entity' }).click();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('entity-1');
|
||||
await page.getByRole('textbox', { name: 'Key' }).fill('hello');
|
||||
await page.getByRole('textbox', { name: 'Value' }).fill('world');
|
||||
await page.locator('.ember-basic-dropdown-trigger').first().click();
|
||||
await page.locator('.ember-power-select-option', { hasText: 'test-policy' }).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
});
|
||||
|
||||
await test.step('should display entity detail page', async () => {
|
||||
await expect(page.getByRole('heading', { name: 'entity-' })).toContainText('entity-1');
|
||||
await page.locator('div:nth-child(2) > .column.is-flex-center').click();
|
||||
await expect(page.getByText('Name entity-')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('should display correct entity information on each tab', async () => {
|
||||
// Aliases tab
|
||||
await expect(page.getByRole('link', { name: 'Aliases' })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Aliases' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'No entity aliases for entity-1 yet' })).toBeVisible();
|
||||
|
||||
// Policies tab
|
||||
await expect(page.getByRole('link', { name: 'Policies', exact: true })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Policies', exact: true }).click();
|
||||
await expect(page.locator('section')).toContainText('test-policy');
|
||||
await page.getByRole('button', { name: 'Identity policy management' }).click();
|
||||
await page.getByRole('link', { name: 'View policy', exact: true }).click();
|
||||
await page.getByText('Vault ACL policies test-policy test-policy Download policy').click();
|
||||
await expect(page.getByText('Vault ACL policies test-policy test-policy Download policy')).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Entities' }).click();
|
||||
await page.getByRole('link', { name: 'entity-1', exact: true }).click();
|
||||
|
||||
// Groups tab
|
||||
await expect(page.getByRole('link', { name: 'Groups' }).nth(1)).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Groups' }).nth(1).click();
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'entity-1 is not a member of any groups.' })
|
||||
).toBeVisible();
|
||||
|
||||
// Metadata tab
|
||||
await page.getByRole('link', { name: 'Metadata' }).click();
|
||||
await expect(page.getByText('hello world')).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: 'Metadata' })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('create and view aliases', async () => {
|
||||
await page.getByRole('link', { name: 'Add alias' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Create Entity Alias for' })).toBeVisible();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('alias-1');
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await expect(page.locator('.hds-page-header__title-wrapper')).toBeVisible();
|
||||
|
||||
await page.getByRole('link', { name: 'Edit entity alias' }).click();
|
||||
await expect(page.locator('.hds-page-header__title-wrapper')).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Entity aliases' }).click();
|
||||
await expect(page.getByRole('link', { name: 'alias-1', exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('cleanup by deleting entities if it was not deleted in previous step', async () => {
|
||||
await page.getByLabel('navigation for entities').getByRole('link', { name: 'Entities' }).click();
|
||||
await page.getByRole('button', { name: 'Identity management options' }).click();
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'No entities yet' })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Aliases' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'No entity aliases yet' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
87
ui/e2e/tests/superuser/access/groups.spec.ts
Normal file
87
ui/e2e/tests/superuser/access/groups.spec.ts
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('groups workflow', async ({ page }) => {
|
||||
await test.step('should display groups page', async () => {
|
||||
await page.goto('dashboard');
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Groups' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Groups', exact: true })).toContainText('Groups');
|
||||
await expect(page.getByRole('heading', { name: 'No groups yet' })).toContainText('No groups yet');
|
||||
await expect(page.getByText('A list of groups in this')).toContainText(
|
||||
'A list of groups in this namespace will be listed here. Create your first group to get started.'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('create policy', async () => {
|
||||
await page.getByRole('link', { name: 'ACL Policies' }).click();
|
||||
await page.getByRole('link', { name: 'Create ACL policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('test-policy');
|
||||
await page.getByRole('radio', { name: 'Code editor' }).check();
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Policy editor' })
|
||||
.fill('path "auth/token/lookup-self" { capabilities = ["read"]}');
|
||||
await page.getByRole('button', { name: 'Create policy' }).click();
|
||||
await page.getByRole('link', { name: 'Groups' }).click();
|
||||
});
|
||||
|
||||
await test.step('create group', async () => {
|
||||
await page.getByRole('link', { name: 'Create group' }).click();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('group-1');
|
||||
await page.getByRole('textbox', { name: 'Key' }).fill('hello');
|
||||
await page.getByRole('textbox', { name: 'Value' }).fill('world');
|
||||
await page.locator('.ember-basic-dropdown-trigger').first().click();
|
||||
await page.locator('.ember-power-select-option', { hasText: 'test-policy' }).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
});
|
||||
|
||||
await test.step('should display group detail page', async () => {
|
||||
await expect(page.getByRole('heading', { name: 'group-' })).toContainText('group-1');
|
||||
await page.locator('div:nth-child(2) > .column.is-flex-center').click();
|
||||
await expect(page.getByText('Name group-')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('should display correct group information on each tab', async () => {
|
||||
// Policies tab
|
||||
await expect(page.getByRole('link', { name: 'Policies', exact: true })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Policies', exact: true }).click();
|
||||
await expect(page.locator('section')).toContainText('test-policy');
|
||||
await page.getByRole('button', { name: 'Identity policy management' }).click();
|
||||
await page.getByRole('link', { name: 'View policy', exact: true }).click();
|
||||
await page.getByText('Vault ACL policies test-policy test-policy Download policy').click();
|
||||
await expect(page.getByText('Vault ACL policies test-policy test-policy Download policy')).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Groups' }).click();
|
||||
await page.getByRole('link', { name: 'group-1', exact: true }).click();
|
||||
|
||||
// Members tab
|
||||
await expect(page.getByRole('link', { name: 'Members' })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Members' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'No members in this group yet' })).toBeVisible();
|
||||
|
||||
// Parent groups tab
|
||||
await expect(page.getByRole('link', { name: 'Parent groups' })).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Parent groups' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'This group has no parent' })).toBeVisible();
|
||||
|
||||
// Metadata tab
|
||||
await page.getByRole('link', { name: 'Metadata' }).click();
|
||||
await expect(page.getByText('hello world')).toBeVisible();
|
||||
await expect(page.getByRole('link', { name: 'Metadata' })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('edit and delete group', async () => {
|
||||
await page.getByRole('link', { name: 'Edit group' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Edit Group-1' })).toContainText('Edit Group-1');
|
||||
await page.getByRole('button', { name: 'Delete group' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
});
|
||||
|
||||
await test.step('should show empty state after group deletion', async () => {
|
||||
await expect(page.getByRole('heading', { name: 'No groups yet' })).toContainText('No groups yet');
|
||||
});
|
||||
});
|
||||
72
ui/e2e/tests/superuser/mfa.ent.spec.ts
Normal file
72
ui/e2e/tests/superuser/mfa.ent.spec.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test('mfa workflow', async ({ page }) => {
|
||||
await page.goto('dashboard');
|
||||
|
||||
await test.step('create userpass auth method and user', async () => {
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Authentication methods' }).click();
|
||||
await page.getByRole('link', { name: 'Enable new method' }).click();
|
||||
await page.getByLabel('Userpass').click();
|
||||
await page.getByRole('button', { name: 'Enable method' }).click();
|
||||
await page.getByRole('button', { name: 'Update options' }).click();
|
||||
|
||||
await page.getByRole('link', { name: 'Type of auth mount userpass/' }).click();
|
||||
await page.getByLabel('toolbar actions').getByRole('link', { name: 'Create user' }).click();
|
||||
await page.getByRole('textbox', { name: 'Username' }).fill('bob');
|
||||
await page.getByRole('textbox', { name: 'password', exact: true }).fill('bobpassword');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(page.getByRole('link', { name: 'bob', exact: true })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('navigate to MFA page', async () => {
|
||||
await page.getByRole('link', { name: 'Multi-factor authentication' }).click();
|
||||
await expect(page.getByRole('img', { name: 'MFA configure diagram' })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('create method with enforcement', async () => {
|
||||
await page.getByRole('link', { name: 'Configure MFA' }).click();
|
||||
await page.getByRole('radio', { name: 'TOTP' }).check();
|
||||
await page.getByRole('button', { name: 'Next' }).click();
|
||||
await page.getByRole('textbox', { name: 'Issuer' }).fill('mfa-totp-issuer');
|
||||
await page.getByLabel('TTL unit for Period').selectOption('m');
|
||||
await page.getByRole('textbox', { name: 'Number of units' }).fill('5');
|
||||
await page.getByRole('radio', { name: 'SHA1' }).check();
|
||||
await page.getByRole('radio', { name: '6', exact: true }).check();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('mfa-totp-enforcement');
|
||||
await page.getByLabel('target-type').selectOption('method');
|
||||
await page.getByLabel('Auth method').locator('select').selectOption('userpass');
|
||||
await page.getByRole('button', { name: 'Add' }).click();
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
await expect(page.getByText('Issuer mfa-totp-issuer')).toBeVisible();
|
||||
await expect(page.getByText('Period 5 minutes')).toBeVisible();
|
||||
await expect(page.getByText('Digits TOTP code length. 6')).toBeVisible();
|
||||
await expect(page.getByText('Enable self-enrollment No')).toBeVisible();
|
||||
await page.getByRole('link', { name: 'Enforcements' }).click();
|
||||
await expect(page.getByRole('link', { name: 'mfa-totp-enforcement' })).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('verify mfa enforcement on login', async () => {
|
||||
await page.getByRole('button', { name: 'User menu' }).click();
|
||||
await page.getByRole('link', { name: 'Log out' }).click();
|
||||
|
||||
await page.getByLabel('Method').selectOption('userpass');
|
||||
await page.getByRole('textbox', { name: 'Username' }).fill('bob');
|
||||
await page.getByRole('textbox', { name: 'Password' }).fill('bobpassword');
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Multi-factor authentication' })).toBeVisible();
|
||||
await page.getByText('Enter your authentication code to log in. TOTP passcode').click();
|
||||
await page.getByRole('textbox', { name: 'TOTP passcode' }).fill('12');
|
||||
await page.getByRole('button', { name: 'Verify' }).click();
|
||||
await expect(page.getByRole('alert', { name: 'Error' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Cancel' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Sign in to Vault' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
@ -6,20 +6,33 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('namespace workflow', async ({ page }) => {
|
||||
await page.goto('dashboard');
|
||||
// nav to namespaces and create a new namespace
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Namespaces' }).click();
|
||||
await page.getByRole('link', { name: 'Create namespace' }).click();
|
||||
await page.getByRole('textbox', { name: 'Path' }).fill('testNamespace');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await test.step('create namespace', async () => {
|
||||
await page.goto('dashboard');
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Namespaces' }).click();
|
||||
await page.getByRole('link', { name: 'Create namespace' }).click();
|
||||
await page.getByRole('textbox', { name: 'Path' }).fill('testNamespace');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
});
|
||||
|
||||
// click on the namespace picker in the top navbar and switch to the new namespace
|
||||
await page.getByRole('button', { name: 'root' }).click();
|
||||
await page.getByRole('option', { name: 'testNamespace' }).click();
|
||||
await test.step('should display the new namespace in the namespace picker and switch to it', async () => {
|
||||
await page.getByRole('button', { name: 'root' }).click();
|
||||
await page.getByRole('option', { name: 'testNamespace' }).click();
|
||||
});
|
||||
|
||||
// verify that we are switched into the new namespace by checking for the namespace name in the header
|
||||
await expect(page.locator('#app-main-content').getByText('testNamespace')).toBeVisible();
|
||||
await test.step('should switch to the new namespace and display the correct header', async () => {
|
||||
await expect(page.locator('#app-main-content').getByText('testNamespace')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('delete namespace', async () => {
|
||||
await page.getByRole('button', { name: 'testNamespace' }).click();
|
||||
await page.getByRole('option', { name: 'root' }).click();
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Namespaces' }).click();
|
||||
await page.getByRole('button', { name: 'More options' }).click();
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
});
|
||||
});
|
||||
|
||||
test('namespace wizard workflow', async ({ page }) => {
|
||||
|
||||
@ -95,7 +95,6 @@ test('oidc workflow', async ({ page }) => {
|
||||
await page.getByRole('link', { name: 'Create assignment' }).click();
|
||||
await page.getByRole('textbox', { name: 'Name' }).fill('oidc-assignment');
|
||||
await page.getByLabel('Entities').getByText('Search').click();
|
||||
await page.locator('div').filter({ hasText: 'Vault Assignments Create' }).nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create' }).click();
|
||||
await expect(page.getByText('At least one entity or group')).toBeVisible();
|
||||
await page.getByLabel('Groups').getByText('Search').click();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user