mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-28 04:10:44 -04:00
* add playwright test coverage for policies * add playwright test coverage for policy generator in kv v2 * only show intro button for acl policies * separate ent tests Co-authored-by: lane-wetmore <lane.wetmore@hashicorp.com>
This commit is contained in:
parent
4f71c2cde0
commit
6208c6a416
4 changed files with 192 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ import { tracked } from '@glimmer/tracking';
|
|||
import Component from '@glimmer/component';
|
||||
import { WIZARD_ID } from 'vault/components/wizard/acl-policies/acl-wizard';
|
||||
import errorMessage from 'vault/utils/error-message';
|
||||
import { PolicyTypes } from 'core/utils/code-generators/policy';
|
||||
|
||||
import type ApiService from 'vault/services/api';
|
||||
import type FlashMessageService from 'vault/services/flash-messages';
|
||||
|
|
@ -88,7 +89,7 @@ export default class PagePoliciesComponent extends Component<Args> {
|
|||
}
|
||||
|
||||
get showIntroButton() {
|
||||
return this.showContent && this.hasOnlyDefaultPolicies;
|
||||
return this.args.policyType === PolicyTypes.ACL && this.showContent && this.hasOnlyDefaultPolicies;
|
||||
}
|
||||
|
||||
// Show when it is not in a dismissed state and there are no non-default policies and
|
||||
|
|
|
|||
|
|
@ -126,4 +126,21 @@ test('kvv2 workflow', async ({ page }) => {
|
|||
await expect(page.locator('section')).toContainText(
|
||||
'Version 1 of this secret has been permanently destroyed A version that has been permanently deleted cannot be restored. You can view other versions of this secret in the Version History tab above. KV v2 API docs'
|
||||
);
|
||||
// generate policy
|
||||
await page.getByRole('button', { name: 'Generate policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('foo-policy');
|
||||
await page.getByRole('checkbox', { name: 'sudo' }).nth(0).check();
|
||||
await page.getByRole('checkbox', { name: 'read' }).nth(1).check();
|
||||
await page.getByRole('checkbox', { name: 'list' }).nth(2).check();
|
||||
await page.getByRole('button', { name: 'Delete' }).nth(3).click();
|
||||
await page.getByRole('button', { name: 'Add rule' }).click();
|
||||
await page.getByRole('textbox', { name: 'Resource path' }).nth(5).fill('kv-test/nomatch');
|
||||
await page.getByRole('checkbox', { name: 'create' }).nth(5).check();
|
||||
await page.getByRole('button', { name: 'Automation snippets' }).click();
|
||||
await expect(page.getByRole('code')).toContainText(
|
||||
'resource "vault_policy" "<local identifier>" { name = "foo-policy" policy = <<EOT path "kv-test/metadata/foo" { capabilities = ["sudo"] } path "kv-test/data/foo" { capabilities = ["read"] } path "kv-test/subkeys/foo" { capabilities = ["list"] } path "kv-test/undelete/foo" { capabilities = [] } path "kv-test/destroy/foo" { capabilities = [] } path "kv-test/nomatch" { capabilities = ["create"] } EOT }'
|
||||
);
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.getByRole('link', { name: 'View policy' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'foo-policy' })).toBeVisible();
|
||||
});
|
||||
|
|
|
|||
99
ui/e2e/tests/superuser/policies.ent.spec.ts
Normal file
99
ui/e2e/tests/superuser/policies.ent.spec.ts
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('rgp policy workflow', async ({ page }) => {
|
||||
await page.goto('dashboard');
|
||||
// nav to rgp policies and create a policy
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Role governing policies' }).click();
|
||||
await page.getByRole('heading', { name: 'RGP policies', exact: true }).click();
|
||||
await page.getByRole('link', { name: 'Create RGP policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('rgp-policy');
|
||||
await page.getByRole('button', { name: 'How to write a policy' }).click();
|
||||
await page.getByText('Here is an example policy').click();
|
||||
await page.getByRole('button', { name: 'Copy' }).nth(1).click();
|
||||
// access the clipboard to get the example policy
|
||||
const clipboardValue = await page.evaluate(() => navigator.clipboard.readText());
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy editor' }).fill(clipboardValue);
|
||||
await page.getByLabel('Enforcement level').selectOption('advisory');
|
||||
await page.getByRole('button', { name: 'Create policy' }).click();
|
||||
await page.getByRole('heading', { name: 'rgp-policy' }).click();
|
||||
await page.getByRole('button', { name: 'Download policy' }).click();
|
||||
await expect(page.getByRole('alert', { name: 'Info' })).toBeVisible();
|
||||
await expect(page.getByLabel('Enforcement level: advisory')).toBeVisible();
|
||||
|
||||
// edit
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByLabel('Policy').clear();
|
||||
const updatedValue = clipboardValue + '\n# just a comment';
|
||||
await page.getByLabel('Policy').fill(updatedValue);
|
||||
await page.getByLabel('Enforcement level', { exact: true }).selectOption('hard-mandatory');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(page.getByLabel('Enforcement level: hard-')).toBeVisible();
|
||||
await expect(page.getByRole('code')).toContainText('# just a comment');
|
||||
|
||||
// delete
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByRole('button', { name: 'Delete policy' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
await expect(page.getByRole('link', { name: 'rgp-policy', exact: true })).not.toBeVisible();
|
||||
});
|
||||
|
||||
test('egp policy workflow', async ({ page }) => {
|
||||
await page.goto('dashboard');
|
||||
// nav to egp policies and create a policy
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Endpoint governing policies' }).click();
|
||||
await page.getByRole('heading', { name: 'EGP policies', exact: true }).click();
|
||||
|
||||
await page.getByRole('link', { name: 'Create EGP policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('egp-policy');
|
||||
await page.getByRole('button', { name: 'How to write a policy' }).click();
|
||||
|
||||
await page.getByText('Here is an example policy').click();
|
||||
await page.getByRole('button', { name: 'Copy' }).nth(1).click();
|
||||
// access the clipboard to get the example policy
|
||||
const clipboardValue = await page.evaluate(() => navigator.clipboard.readText());
|
||||
await page.getByRole('button', { name: 'Close' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy editor' }).fill(clipboardValue);
|
||||
await page.getByLabel('Enforcement level').selectOption('advisory');
|
||||
await page.getByRole('textbox', { name: 'Paths list item' }).fill('foo');
|
||||
await page.getByRole('button', { name: 'Add' }).click();
|
||||
await page.getByRole('textbox', { name: 'Paths list item 1' }).fill('bar');
|
||||
await page.getByRole('button', { name: 'Add' }).click();
|
||||
await page.getByRole('button', { name: 'Create policy' }).click();
|
||||
await page.getByRole('heading', { name: 'egp-policy' }).click();
|
||||
await page.getByRole('button', { name: 'Download policy' }).click();
|
||||
await expect(page.getByRole('alert', { name: 'Info' })).toBeVisible();
|
||||
await expect(page.getByLabel('Enforcement level: advisory')).toBeVisible();
|
||||
await expect(page.getByRole('listitem').filter({ hasText: 'foo' })).toBeVisible();
|
||||
await expect(page.getByRole('listitem').filter({ hasText: 'bar' })).toBeVisible();
|
||||
|
||||
// edit
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByLabel('Policy').clear();
|
||||
const updatedValue = clipboardValue + '\n# just a comment';
|
||||
await page.getByLabel('Policy').fill(updatedValue);
|
||||
await page.getByLabel('Enforcement level', { exact: true }).selectOption('hard-mandatory');
|
||||
await page.getByRole('button', { name: 'delete row' }).nth(1).click();
|
||||
await page.getByRole('textbox', { name: 'Paths list item 1' }).fill('baz');
|
||||
await page.getByRole('button', { name: 'Add' }).click();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(page.getByLabel('Enforcement level: hard-')).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Show more code' }).click();
|
||||
await expect(page.getByText('# just a comment')).toBeVisible();
|
||||
await expect(page.getByRole('listitem').filter({ hasText: 'foo' })).toBeVisible();
|
||||
await expect(page.getByRole('listitem').filter({ hasText: 'bar' })).not.toBeVisible();
|
||||
await expect(page.getByRole('listitem').filter({ hasText: 'baz' })).toBeVisible();
|
||||
|
||||
// delete
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByRole('button', { name: 'Delete policy' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
await expect(page.getByRole('link', { name: 'egp-policy', exact: true })).not.toBeVisible();
|
||||
});
|
||||
74
ui/e2e/tests/superuser/policies.spec.ts
Normal file
74
ui/e2e/tests/superuser/policies.spec.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('acl policy workflow', async ({ page }) => {
|
||||
await page.goto('dashboard');
|
||||
// nav to acl policies and create a policy
|
||||
await page.getByRole('link', { name: 'Access control' }).click();
|
||||
await page.getByRole('link', { name: 'Create ACL policy' }).click();
|
||||
await page.getByRole('textbox', { name: 'Policy name' }).fill('acl-policy');
|
||||
await page.getByRole('textbox', { name: 'Resource path' }).fill('kv');
|
||||
await page.getByRole('checkbox', { name: 'read' }).check();
|
||||
await page.getByRole('checkbox', { name: 'update' }).check();
|
||||
await page.getByRole('switch', { name: 'Show preview' }).click();
|
||||
await expect(page.getByRole('code')).toContainText('path "kv" { capabilities = ["read", "update"] }');
|
||||
await page.getByRole('switch', { name: 'Hide preview' }).click();
|
||||
await page.getByRole('button', { name: 'Add rule' }).click();
|
||||
await page.getByRole('textbox', { name: 'Resource path' }).nth(1).fill('pki');
|
||||
await page.getByRole('checkbox', { name: 'list' }).nth(1).check();
|
||||
await page.getByRole('checkbox', { name: 'patch' }).nth(1).check();
|
||||
await page.getByRole('button', { name: 'Add rule' }).click();
|
||||
await page.getByRole('textbox', { name: 'Resource path' }).nth(2).fill('totp');
|
||||
await page.getByRole('checkbox', { name: 'create' }).nth(2).check();
|
||||
// check snippets
|
||||
await page.getByRole('button', { name: 'Automation snippets' }).click();
|
||||
await expect(page.getByRole('code')).toContainText(
|
||||
'resource "vault_policy" "<local identifier>" { name = "acl-policy" policy = <<EOT path "kv" { capabilities = ["read", "update"] } path "pki" { capabilities = ["list", "patch"] } path "totp" { capabilities = ["create"] } EOT }'
|
||||
);
|
||||
await page.getByRole('tab', { name: 'CLI' }).click();
|
||||
await expect(page.getByText('vault policy write acl-policy')).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Delete' }).nth(2).click();
|
||||
await expect(page.getByRole('code')).toContainText(
|
||||
'vault policy write acl-policy - <<EOT path "kv" { capabilities = ["read", "update"] } path "pki" { capabilities = ["list", "patch"] } EOT'
|
||||
);
|
||||
// check change detection
|
||||
await page.getByRole('radio', { name: 'Code editor' }).check();
|
||||
await expect(page.getByRole('heading', { name: 'Policy editor' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Switch and discard changes' })).not.toBeVisible();
|
||||
await page.getByRole('radio', { name: 'Visual editor' }).check();
|
||||
await page.getByRole('radio', { name: 'Code editor' }).check();
|
||||
await page.getByRole('textbox', { name: 'Policy editor' }).clear();
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Policy editor' })
|
||||
.fill(
|
||||
'vault policy write acl-policy - <<EOT path "kv" { capabilities = ["read"] } path "pki" { capabilities = ["list", "patch"] } EOT'
|
||||
);
|
||||
await page.getByRole('radio', { name: 'Visual editor' }).click();
|
||||
await page.getByRole('button', { name: 'Switch and discard changes' }).click();
|
||||
await expect(page.getByRole('code')).toContainText(
|
||||
'EOT path "kv" { capabilities = ["read", "update"] } path "pki" { capabilities = ["list", "patch"] } EOT'
|
||||
);
|
||||
await page.getByRole('button', { name: 'Create policy' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'acl-policy' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Download policy' }).click();
|
||||
await expect(page.getByRole('alert', { name: 'Info' })).toBeVisible();
|
||||
await expect(page.getByText('Policy HCL format')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Automation snippets' })).toBeVisible();
|
||||
|
||||
// edit
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByLabel('Policy').clear();
|
||||
await page.getByLabel('Policy').fill('path "kv" { capabilities = ["read", "update"] }');
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await expect(page.getByLabel('Policy')).toContainText('path "kv" { capabilities = ["read", "update"] }');
|
||||
|
||||
// delete
|
||||
await page.getByRole('link', { name: 'Edit policy' }).click();
|
||||
await page.getByRole('button', { name: 'Delete policy' }).click();
|
||||
await page.getByRole('button', { name: 'Confirm' }).click();
|
||||
await expect(page.getByRole('link', { name: 'acl-policy', exact: true })).not.toBeVisible();
|
||||
});
|
||||
Loading…
Reference in a new issue