mirror of
https://github.com/hashicorp/vault.git
synced 2026-04-03 04:42:30 +02:00
* adds constants util for wizards and updates service to use WizardId type * updates wizards to use WIZARD_ID_MAP values * updates wizard tests to use the service for dismissal * updates playwright setup to add all wizard ids as dismissed in localStorage * removes wizard dismissal step from existing playwright tests * fixes issues accessing owner in beforeEach hooks of namespaces acceptance tests Co-authored-by: Jordan Reimer <zofskeez@gmail.com>
83 lines
4.2 KiB
TypeScript
83 lines
4.2 KiB
TypeScript
/**
|
|
* Copyright IBM Corp. 2016, 2025
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { test as base } from '@playwright/test';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { USER_POLICY_MAP } from './policies';
|
|
import { DISMISSED_WIZARD_KEY, WIZARD_ID_MAP } from '../app/utils/constants/wizard';
|
|
|
|
export type UserSetupOptions = {
|
|
userType: string;
|
|
};
|
|
|
|
// use superuser as the default policy if not provided in the config for a project
|
|
export const setup = base.extend<UserSetupOptions>({
|
|
userType: 'superuser',
|
|
});
|
|
|
|
// setup will run once before all tests
|
|
setup('initialize vault and setup user for testing', async ({ page, userType }) => {
|
|
// on fresh app load navigating to the root will land us on the initialize page
|
|
await page.goto('./');
|
|
// manually update dismissed wizards so that they don't have to be skipped in tests before persisting storage state;
|
|
await page.evaluate(
|
|
({ key, ids }) => {
|
|
localStorage.setItem(key, JSON.stringify(ids));
|
|
},
|
|
{ key: DISMISSED_WIZARD_KEY, ids: Object.values(WIZARD_ID_MAP) }
|
|
);
|
|
// initialize vault
|
|
await page.getByRole('spinbutton', { name: 'Key shares' }).fill('1');
|
|
await page.getByRole('spinbutton', { name: 'Key threshold' }).fill('1');
|
|
await page.getByRole('button', { name: 'Initialize' }).click();
|
|
// listen for download event so we can get the unseal key and root token
|
|
const downloadPromise = page.waitForEvent('download');
|
|
await page.getByRole('button', { name: 'Download keys' }).click();
|
|
const download = await downloadPromise;
|
|
const keysPath = path.join(__dirname, `/tmp/${userType}-keys.json`);
|
|
await download.saveAs(keysPath);
|
|
const { keys, root_token } = JSON.parse(fs.readFileSync(keysPath, 'utf-8'));
|
|
// unseal vault
|
|
await page.getByRole('link', { name: 'Continue to Unseal' }).click();
|
|
await page.getByRole('textbox', { name: 'Unseal Key Portion' }).fill(keys[0]);
|
|
await page.getByRole('button', { name: 'Unseal' }).click();
|
|
// use the root token to login
|
|
await page.getByRole('textbox', { name: 'Token' }).fill(root_token);
|
|
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
// create a policy for a specific user persona
|
|
// defaults to superuser but should be passed in via the project config in playwright.config.ts
|
|
await page.getByRole('link', { name: 'Access control', exact: true }).click();
|
|
// if the intro page is shown, click the create policy link there, otherwise click the create policy link in the toolbar on main page
|
|
if (await page.getByRole('link', { name: 'Create a policy' }).isVisible()) {
|
|
await page.getByRole('link', { name: 'Create a policy' }).click();
|
|
} else {
|
|
await page.getByRole('link', { name: 'Create ACL policy' }).click();
|
|
}
|
|
await page.getByRole('textbox', { name: 'Policy name' }).fill(userType);
|
|
await page.getByRole('radio', { name: 'Code editor' }).check();
|
|
await page.getByRole('textbox', { name: 'Policy editor' }).fill(USER_POLICY_MAP[userType]);
|
|
await page.getByRole('button', { name: 'Create policy' }).click();
|
|
// there is no UI workflow for creating tokens with specific policies
|
|
// generate a token using the web REPL and assign the new policy to it
|
|
await page.getByRole('button', { name: 'Console toggle' }).click();
|
|
await page
|
|
.getByRole('textbox', { name: 'web R.E.P.L.' })
|
|
.fill(`write -field=client_token auth/token/create policies=${userType} ttl=1d`);
|
|
await page.getByRole('textbox', { name: 'web R.E.P.L.' }).press('Enter');
|
|
const newToken = await page.locator('.console-ui-output pre').innerText();
|
|
await page.getByRole('button', { name: 'Console toggle' }).click();
|
|
// log out with the root token and log in with the new token/policy
|
|
await page.getByRole('button', { name: 'User menu' }).click();
|
|
await page.getByRole('link', { name: 'Log out' }).click();
|
|
await page.getByRole('textbox', { name: 'Token' }).fill(newToken);
|
|
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
// wait for the dashboard to load to ensure login was successful
|
|
await page.waitForURL('**/dashboard');
|
|
// save the localStorage state to file which includes the auth token and dismissed wizards
|
|
// subsequent tests can then reuse the session data
|
|
await page.context().storageState({ path: path.join(__dirname, `/tmp/${userType}-session.json`) });
|
|
});
|