1105 lines
39 KiB
JavaScript
1105 lines
39 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
/* eslint-disable no-undef */
|
|
const { expect } = require('@playwright/test');
|
|
const { readFile } = require('fs/promises');
|
|
const { nanoid } = require('nanoid');
|
|
|
|
/**
|
|
* Uses the UI to create a new organization
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the organization
|
|
*/
|
|
exports.createOrg = async (page) => {
|
|
const orgName = 'Org ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'General' })
|
|
.getByRole('link', { name: 'Orgs' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New Org' }).click();
|
|
await page.getByLabel('Name').fill(orgName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
|
|
).toBeVisible();
|
|
|
|
return orgName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new project. Assumes you have selected the desired org.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the project
|
|
*/
|
|
exports.createProject = async (page) => {
|
|
const projectName = 'Project ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'General' })
|
|
.getByRole('link', { name: 'Projects' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(projectName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(projectName),
|
|
).toBeVisible();
|
|
|
|
return projectName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new host catalog. Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the host catalog
|
|
*/
|
|
exports.createHostCatalog = async (page) => {
|
|
const hostCatalogName = 'Host Catalog ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Host Catalogs' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(hostCatalogName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(hostCatalogName),
|
|
).toBeVisible();
|
|
|
|
return hostCatalogName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new host set. Assumes you have just created a new host catalog.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the host set
|
|
*/
|
|
exports.createHostSet = async (page) => {
|
|
const hostSetName = 'Host Set ' + nanoid();
|
|
await page.getByRole('link', { name: 'Host Sets' }).click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(hostSetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(hostSetName),
|
|
).toBeVisible();
|
|
|
|
return hostSetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new host in a host set. Assumes you have just created a new host set.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} address Address of the host
|
|
* @returns Name of the host
|
|
*/
|
|
exports.createHostInHostSet = async (page, address) => {
|
|
const hostName = 'Host ' + nanoid();
|
|
await page.getByText('Manage').click();
|
|
await page.getByRole('link', { name: 'Create and Add Host' }).click();
|
|
await page.getByLabel('Name').fill(hostName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByLabel('Address').fill(address);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('link', { name: hostName })).toBeVisible();
|
|
|
|
return hostName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a static credential store. Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the credential store
|
|
*/
|
|
exports.createStaticCredentialStore = async (page) => {
|
|
const credentialStoreName = 'Credential Store ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Credential Stores' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name (Optional)').fill(credentialStoreName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('group', { name: 'Type' }).getByLabel('Static').click();
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(credentialStoreName),
|
|
).toBeVisible();
|
|
|
|
return credentialStoreName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a vault credential store. Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} vaultAddr address of the vault server
|
|
* @param {string} clientToken vault token to connect to boundary
|
|
* @returns Name of the credential store
|
|
*/
|
|
exports.createVaultCredentialStore = async (page, vaultAddr, clientToken) => {
|
|
const credentialStoreName = 'Credential Store ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Credential Stores' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name (Optional)').fill(credentialStoreName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('group', { name: 'Type' }).getByLabel('Vault').click();
|
|
await page.getByLabel('Address').fill(vaultAddr);
|
|
await page.getByLabel('Token').fill(clientToken);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(credentialStoreName),
|
|
).toBeVisible();
|
|
|
|
return credentialStoreName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a static key pair credential . Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} username username for the credential
|
|
* @param {string} keyPath path to the private key
|
|
* @returns Name of the credential
|
|
*/
|
|
exports.createStaticCredentialKeyPair = async (page, username, keyPath) => {
|
|
const credentialName = 'Credential ' + nanoid();
|
|
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name (Optional)').fill(credentialName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page
|
|
.getByRole('group', { name: 'Type' })
|
|
.getByLabel('Username & Key Pair')
|
|
.click();
|
|
await page.getByLabel('Username', { exact: true }).fill(username);
|
|
const keyData = await readFile(keyPath, {
|
|
encoding: 'utf-8',
|
|
});
|
|
await page.getByLabel('SSH Private Key').fill(keyData);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(credentialName),
|
|
).toBeVisible();
|
|
|
|
return credentialName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a vault-generic credential library. Assumes you have selected
|
|
* the desired credential store.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} vaultPath path to secret in vault
|
|
* @param {string} credentialType type of credential for credential injection
|
|
* @returns Name of the credential library
|
|
*/
|
|
exports.createVaultGenericCredentialLibrary = async (
|
|
page,
|
|
vaultPath,
|
|
credentialType,
|
|
) => {
|
|
const credentialLibraryName = 'Credential Library ' + nanoid();
|
|
await page.getByRole('link', { name: 'Credential Libraries' }).click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page
|
|
.getByLabel('Name (Optional)', { exact: true })
|
|
.fill(credentialLibraryName);
|
|
await page
|
|
.getByLabel('Description (Optional)')
|
|
.fill('This is an automated test');
|
|
await page
|
|
.getByRole('group', { name: 'Type' })
|
|
.getByLabel('Generic Secrets')
|
|
.click();
|
|
await page.getByLabel('Vault Path').fill(vaultPath);
|
|
await page
|
|
.getByRole('combobox', { name: 'Credential Type' })
|
|
.selectOption(credentialType);
|
|
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
|
|
return credentialLibraryName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a vault-ssh-certificate credential library. Assumes you have selected
|
|
* the desired credential store.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} vaultPath path to secret in vault
|
|
* @param {string} username username for the credential
|
|
* @returns Name of the credential library
|
|
*/
|
|
exports.createVaultSshCertificateCredentialLibrary = async (
|
|
page,
|
|
vaultPath,
|
|
username,
|
|
) => {
|
|
const credentialLibraryName = 'Credential Library ' + nanoid();
|
|
|
|
await page.getByRole('link', { name: 'Credential Libraries' }).click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
|
|
await page
|
|
.getByLabel('Name (Optional)', { exact: true })
|
|
.fill(credentialLibraryName);
|
|
await page
|
|
.getByLabel('Description (Optional)')
|
|
.fill('This is an automated test');
|
|
await page
|
|
.getByRole('group', { name: 'Type' })
|
|
.getByLabel('SSH Certificates')
|
|
.click();
|
|
await page.getByLabel('Vault Path').fill(vaultPath);
|
|
await page.getByLabel('Username').fill(username);
|
|
await page.getByLabel('Key Type').selectOption('ecdsa');
|
|
await page.getByLabel('Key Bits').fill('521');
|
|
|
|
await page
|
|
.getByRole('group', { name: 'Extensions' })
|
|
.getByLabel('Key')
|
|
.fill('permity-pty');
|
|
await page
|
|
.getByRole('group', { name: 'Extensions' })
|
|
.getByRole('button', { name: 'Add' })
|
|
.click();
|
|
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
|
|
return credentialLibraryName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new target. Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} port Port of the target
|
|
* @returns Name of the target
|
|
*/
|
|
exports.createTarget = async (page, port) => {
|
|
const targetName = 'Target ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(targetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByLabel('Default Port').fill(port);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(targetName),
|
|
).toBeVisible();
|
|
|
|
return targetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new target with address. Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} address Address of the target
|
|
* @param {string} port Port of the target
|
|
* @returns Name of the target
|
|
*/
|
|
exports.createTargetWithAddress = async (page, address, port) => {
|
|
const targetName = 'Target ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(targetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByLabel('Target Address').fill(address);
|
|
await page.getByLabel('Default Port').fill(port);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(targetName),
|
|
).toBeVisible();
|
|
|
|
return targetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new TCP target with address in boundary-enterprise
|
|
* Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} address Address of the target
|
|
* @param {string} port Port of the target
|
|
* @returns Name of the target
|
|
*/
|
|
exports.createTcpTargetWithAddressEnt = async (page, address, port) => {
|
|
const targetName = 'Target ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(targetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('group', { name: 'Type' }).getByLabel('TCP').click();
|
|
await page.getByLabel('Target Address').fill(address);
|
|
await page.getByLabel('Default Port').fill(port);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(targetName),
|
|
).toBeVisible();
|
|
|
|
return targetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new SSH target with address in boundary-enterprise
|
|
* Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} address Address of the target
|
|
* @param {string} port Port of the target
|
|
* @returns Name of the target
|
|
*/
|
|
exports.createSshTargetWithAddressEnt = async (page, address, port) => {
|
|
const targetName = 'Target ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(targetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('group', { name: 'Type' }).getByLabel('SSH').click();
|
|
await page.getByLabel('Target Address').fill(address);
|
|
await page.getByLabel('Default Port').fill(port);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(targetName),
|
|
).toBeVisible();
|
|
|
|
return targetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new SSH target with address in boundary-enterprise
|
|
* Assumes you have selected the desired project.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} address Address of the target
|
|
* @param {string} port Port of the target
|
|
* @param {string} workerFilterEgress Egress worker filter
|
|
* @returns Name of the target
|
|
*/
|
|
exports.createSshTargetWithAddressAndWorkerFilterEnt = async (
|
|
page,
|
|
address,
|
|
port,
|
|
workerFilterEgress,
|
|
) => {
|
|
const targetName = 'Target ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(targetName);
|
|
await page.getByLabel('Description').fill('This is an automated test');
|
|
await page.getByRole('group', { name: 'Type' }).getByLabel('SSH').click();
|
|
await page.getByLabel('Target Address').fill(address);
|
|
await page.getByLabel('Default Port').fill(port);
|
|
await page.getByLabel('Egress worker filter').click();
|
|
await page.getByRole('textbox', { name: 'Filter' }).fill(workerFilterEgress);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(targetName),
|
|
).toBeVisible();
|
|
|
|
return targetName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to delete a Boundary resource. Assume you have selected the desired resource.
|
|
* Note: For a resource to be deleted using this method,
|
|
* the resource page should allow to delete the resource using the Manage button.
|
|
* @param {Page} page Playwright page object
|
|
*/
|
|
exports.deleteResource = async (page) => {
|
|
await page.getByTitle('Manage').click();
|
|
await page.getByRole('button', { name: /^(Delete|Remove Worker)/ }).click();
|
|
await page.getByText('OK', { exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to remove auth method as primary. Assume you have selected the desired auth method.
|
|
* @param {Page} page Playwright page object
|
|
*/
|
|
exports.removeAuthMethodAsPrimary = async (page) => {
|
|
await page.getByTitle('Manage').click();
|
|
await page.getByRole('button', { name: 'Remove as primary' }).click();
|
|
await page.getByText('OK', { exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to add a host source to a target. Assume you have selected the desired target.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} hostSourceName Name of host source that will be attached to the target
|
|
*/
|
|
exports.addHostSourceToTarget = async (page, hostSourceName) => {
|
|
await page.getByRole('link', { name: 'Host Sources', exact: true }).click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Add Host Sources', exact: true })
|
|
.click();
|
|
await page
|
|
.getByRole('cell', { name: hostSourceName })
|
|
.locator('..')
|
|
.getByRole('checkbox')
|
|
.click({ force: true });
|
|
await page.getByRole('button', { name: 'Add Host Sources' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('link', { name: hostSourceName })).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to navigate to Sessions and waits for the session to appear
|
|
* and be in Active state.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} targetName Name of the target associated with the session
|
|
*/
|
|
exports.waitForSessionToBeVisible = async (page, targetName) => {
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Sessions' })
|
|
.click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Sessions'),
|
|
).toBeVisible();
|
|
let i = 0;
|
|
let sessionIsVisible = false;
|
|
let sessionIsActive = false;
|
|
do {
|
|
i = i + 1;
|
|
sessionIsVisible = await page
|
|
.getByRole('cell', { name: targetName })
|
|
.isVisible();
|
|
sessionIsActive = await page
|
|
.getByRole('cell', { name: 'Active' })
|
|
.isVisible();
|
|
if (sessionIsVisible && sessionIsActive) {
|
|
break;
|
|
}
|
|
|
|
const noSessionsAvailable = await page
|
|
.getByText('No Sessions Available', { exact: true })
|
|
.isVisible();
|
|
if (noSessionsAvailable) {
|
|
await new Promise((r) => setTimeout(r, 1000));
|
|
await page.reload();
|
|
} else {
|
|
await page.getByRole('button', { name: 'Refresh' }).click();
|
|
await expect(page.getByRole('button', { name: 'Refresh' })).toBeEnabled();
|
|
}
|
|
} while (i < 5);
|
|
|
|
if (!sessionIsVisible) {
|
|
throw new Error('Session is not visible');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to navigate to the specified Target and add the Brokered Credentials to it.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} targetName Name of the target associated with the session
|
|
* @param {string} credentialName Name of the credentials to be added to the target
|
|
*/
|
|
exports.addBrokeredCredentialsToTarget = async (
|
|
page,
|
|
targetName,
|
|
credentialName,
|
|
) => {
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: targetName }).click();
|
|
await page
|
|
.getByRole('link', { name: 'Brokered Credentials', exact: true })
|
|
.click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Add Brokered Credentials', exact: true })
|
|
.click();
|
|
await page
|
|
.getByRole('cell', { name: credentialName })
|
|
.locator('..')
|
|
.getByRole('checkbox')
|
|
.click({ force: true });
|
|
await page
|
|
.getByRole('button', { name: 'Add Brokered Credentials', exact: true })
|
|
.click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('link', { name: credentialName })).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to navigate to the specified Target and add the Injected Credentials to it.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} targetName Name of the target associated with the session
|
|
* @param {string} credentialName Name of the credentials to be added to the target
|
|
*/
|
|
exports.addInjectedCredentialsToTarget = async (
|
|
page,
|
|
targetName,
|
|
credentialName,
|
|
) => {
|
|
await page
|
|
.getByRole('navigation', { name: 'Resources' })
|
|
.getByRole('link', { name: 'Targets' })
|
|
.click();
|
|
await page.getByRole('link', { name: targetName }).click();
|
|
await page
|
|
.getByRole('link', {
|
|
name: 'Injected Application Credentials',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', {
|
|
name: 'Add Injected Application Credentials',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await page
|
|
.getByRole('cell', { name: credentialName })
|
|
.locator('..')
|
|
.getByRole('checkbox')
|
|
.click({ force: true });
|
|
await page
|
|
.getByRole('button', {
|
|
name: 'Add Injected Application Credentials',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('link', { name: credentialName })).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create new Auth Method. Assumes you have selected the desired scope.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the auth method
|
|
*/
|
|
exports.createPasswordAuthMethod = async (page) => {
|
|
const authMethodName = 'Auth Method ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'IAM' })
|
|
.getByRole('link', { name: 'Auth Methods' })
|
|
.click();
|
|
await page.getByRole('button', { name: 'New' }).click();
|
|
await page.getByText('Password', { exact: true }).click();
|
|
await page.getByLabel('Name').fill(authMethodName);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(authMethodName),
|
|
).toBeVisible();
|
|
|
|
return authMethodName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to make the first available auth method primary.
|
|
* Assumes you have created new auth method.
|
|
* @param {Page} page Playwright page object
|
|
*/
|
|
exports.makeAuthMethodPrimary = async (page) => {
|
|
await page
|
|
.getByRole('navigation', { name: 'IAM' })
|
|
.getByRole('link', { name: 'Auth Methods' })
|
|
.click();
|
|
await page.getByRole('button', { name: 'Manage' }).click();
|
|
await page.getByText('Make Primary', { exact: true }).click();
|
|
await page.getByText('OK', { exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create new password Account. Assumes you have selected the desired Auth Method
|
|
* which the account will be created for.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} login Login of new account
|
|
* @param {string} password Password of new account
|
|
* @returns Name of the account
|
|
*/
|
|
exports.createPasswordAccount = async (page, login, password) => {
|
|
const accountName = 'Account ' + nanoid();
|
|
|
|
await page.getByRole('link', { name: 'Accounts' }).click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Create Account', exact: true })
|
|
.click();
|
|
await page.getByLabel('Name (Optional)').fill(accountName);
|
|
await page.getByLabel('Login Name').fill(login);
|
|
await page.getByLabel('Password', { exact: true }).fill(password);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(accountName),
|
|
).toBeVisible();
|
|
|
|
return accountName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to set a new password to an account.
|
|
* Assumes you have selected the desired Account.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} password New password of the account
|
|
*/
|
|
exports.setPasswordToAccount = async (page, password) => {
|
|
await page.getByRole('link', { name: 'Set Password' }).click();
|
|
await page.getByLabel(new RegExp('Password*')).fill(password);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new user.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the user
|
|
*/
|
|
exports.createUser = async (page) => {
|
|
const userName = 'User ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'IAM' })
|
|
.getByRole('link', { name: 'Users' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(userName);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(userName),
|
|
).toBeVisible();
|
|
|
|
return userName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to add the first available account to a user.
|
|
* Assumes you have selected the desired user.
|
|
* Assumes you have created new account.
|
|
* @param {Page} page Playwright page object
|
|
*/
|
|
exports.addAccountToUser = async (page) => {
|
|
await page.getByRole('link', { name: 'Accounts', exact: true }).click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Add Accounts', exact: true })
|
|
.click();
|
|
|
|
await page.getByRole('checkbox').click();
|
|
await page.getByRole('button', { name: 'Add Accounts', exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new group. Assumes you have selected the desired scope.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the group
|
|
*/
|
|
exports.createGroup = async (page) => {
|
|
const groupName = 'Group ' + nanoid();
|
|
await page
|
|
.getByRole('navigation', { name: 'IAM' })
|
|
.getByRole('link', { name: 'Groups' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New', exact: true }).click();
|
|
await page.getByLabel('Name').fill(groupName);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(groupName),
|
|
).toBeVisible();
|
|
|
|
return groupName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to add a user to the group. Assumes you have selected the desired group.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} userName Name of the user that will be added to the group
|
|
*/
|
|
exports.addMemberToGroup = async (page, userName) => {
|
|
await page.getByRole('link', { name: 'Members', exact: true }).click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Add Members', exact: true })
|
|
.click();
|
|
await page.getByRole('checkbox', { name: userName }).click();
|
|
await page.getByRole('button', { name: 'Add Members', exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('table').getByText(userName)).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new role. Assumes you have selected the desired scope.
|
|
* @param {Page} page Playwright page object
|
|
*/
|
|
exports.createRole = async (page) => {
|
|
const roleName = 'Role ' + nanoid();
|
|
|
|
await page
|
|
.getByRole('navigation', { name: 'IAM' })
|
|
.getByRole('link', { name: 'Roles' })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New Role' }).click();
|
|
await page.getByLabel('Name').fill(roleName);
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(roleName),
|
|
).toBeVisible();
|
|
|
|
return roleName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to add a principal to the role. Assumes you have selected the desired role.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} principalName Name of the principal that will be added to the role
|
|
*/
|
|
exports.addPrincipalToRole = async (page, principalName) => {
|
|
await page.getByRole('link', { name: 'Principals', exact: true }).click();
|
|
await page
|
|
.getByRole('article')
|
|
.getByRole('link', { name: 'Add Principals', exact: true })
|
|
.click();
|
|
await page.getByRole('checkbox', { name: principalName }).click();
|
|
await page
|
|
.getByRole('button', { name: 'Add Principals', exact: true })
|
|
.click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('table').getByRole('link', { name: principalName }),
|
|
).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to add a grant to the role. Assumes you have selected the desired role.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} grants grants that will be given to the role
|
|
*/
|
|
exports.addGrantsToGroup = async (page, grants) => {
|
|
await page.getByRole('link', { name: 'Grants', exact: true }).click();
|
|
await page.getByRole('textbox', { name: 'New Grant' }).fill(grants);
|
|
await page.getByRole('button', { name: 'Add', exact: true }).click();
|
|
await page.getByRole('button', { name: 'Save', exact: true }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('textbox', { name: 'Grant', exact: true }),
|
|
).toHaveValue(grants);
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new AWS Storage Bucket.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} scope Scope of the Storage Bucket
|
|
* @param {string} bucketName Name of the Storage Bucket
|
|
* @param {string} region Region of the Storage Bucket
|
|
* @param {string} accessKeyId Access Key ID for the Storage Bucket
|
|
* @param {string} secretAccessKey Secret Access Key for the Storage Bucket
|
|
* @param {string} workerFilter Worker filter for the Storage Bucket
|
|
* @returns Name of the Storage Bucket
|
|
*/
|
|
exports.createStorageBucketAws = async (
|
|
page,
|
|
scope,
|
|
bucketName,
|
|
region,
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
workerFilter,
|
|
) => {
|
|
const storageBucketName = 'Bucket ' + nanoid();
|
|
await page
|
|
.getByRole('link', { name: 'Storage Buckets', exact: true })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New Storage Bucket' }).click();
|
|
await page.getByLabel(new RegExp('Name*')).fill(storageBucketName);
|
|
await page.getByLabel('Scope').selectOption({ label: scope });
|
|
await page
|
|
.getByRole('group', { name: 'Provider' })
|
|
.getByLabel('Amazon S3')
|
|
.click();
|
|
await page.getByLabel('Bucket name').fill(bucketName);
|
|
await page.getByLabel('Region').fill(region);
|
|
await page.getByLabel('Access key ID').fill(accessKeyId);
|
|
await page.getByLabel('Secret access key').fill(secretAccessKey);
|
|
await page.getByLabel('Worker filter').fill(workerFilter);
|
|
await page.getByLabel('Disable credential rotation').click();
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(storageBucketName),
|
|
).toBeVisible();
|
|
|
|
return storageBucketName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a new MinIO Storage Bucket.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} scope Scope of the Storage Bucket
|
|
* @param {string} endpointUrl Endpoint URL of the Storage Bucket
|
|
* @param {string} bucketName Name of the Storage Bucket
|
|
* @param {string} region Region of the Storage Bucket
|
|
* @param {string} accessKeyId Access Key ID for the Storage Bucket
|
|
* @param {string} secretAccessKey Secret Access Key for the Storage Bucket
|
|
* @param {string} workerFilter Worker filter for the Storage Bucket
|
|
* @returns Name of the Storage Bucket
|
|
*/
|
|
exports.createStorageBucketMinio = async (
|
|
page,
|
|
scope,
|
|
endpointUrl,
|
|
bucketName,
|
|
region,
|
|
accessKeyId,
|
|
secretAccessKey,
|
|
workerFilter,
|
|
) => {
|
|
const storageBucketName = 'Bucket ' + nanoid();
|
|
await page
|
|
.getByRole('link', { name: 'Storage Buckets', exact: true })
|
|
.click();
|
|
await page.getByRole('link', { name: 'New Storage Bucket' }).click();
|
|
await page.getByLabel(new RegExp('Name*')).fill(storageBucketName);
|
|
await page.getByLabel('Scope').selectOption({ label: scope });
|
|
await page
|
|
.getByRole('group', { name: 'Provider' })
|
|
.getByLabel('MinIO')
|
|
.click();
|
|
await page.getByLabel('Endpoint URL').fill(endpointUrl);
|
|
await page.getByLabel('Bucket name').fill(bucketName);
|
|
await page.getByLabel('Region').fill(region);
|
|
await page.getByLabel('Access key ID').fill(accessKeyId);
|
|
await page.getByLabel('Secret access key').fill(secretAccessKey);
|
|
await page.getByLabel('Worker filter').fill(workerFilter);
|
|
await page.getByLabel('Disable credential rotation').click();
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(storageBucketName),
|
|
).toBeVisible();
|
|
|
|
return storageBucketName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to enable session recording for a target. Assumes you have selected the desired target.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} storageBucketName name of the Storage Bucket used for session recording
|
|
*/
|
|
exports.enableSessionRecording = async (page, storageBucketName) => {
|
|
await page.getByText('Enable recording').click();
|
|
await page.getByLabel('Record sessions for this target').click();
|
|
await page
|
|
.getByLabel('Storage buckets')
|
|
.selectOption({ label: storageBucketName });
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page.getByRole('listitem').getByText(storageBucketName),
|
|
).toBeVisible();
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to create a Storage Policy. Assumes you have selected the desired scope.
|
|
* @param {Page} page Playwright page object
|
|
* @returns Name of the Storage Policy
|
|
*/
|
|
exports.createStoragePolicy = async (page) => {
|
|
const storagePolicyName = 'Policy ' + nanoid();
|
|
await page
|
|
.getByRole('link', { name: 'Storage Policies', exact: true })
|
|
.click();
|
|
await page
|
|
.getByRole('link', { name: 'Create a new storage policy', exact: true })
|
|
.click();
|
|
await page.getByLabel('Name').fill(storagePolicyName);
|
|
await page.getByLabel('Retention Policy').selectOption({ label: 'Forever' });
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(
|
|
page
|
|
.getByRole('navigation', { name: 'breadcrumbs' })
|
|
.getByText(storagePolicyName),
|
|
).toBeVisible();
|
|
|
|
return storagePolicyName;
|
|
};
|
|
|
|
/**
|
|
* Uses the UI to attach Storage Policy to a scope. Assumes you have selected the desired scope.
|
|
* @param {Page} page Playwright page object
|
|
* @param {string} policyName name of the Policy to be attached to the scope
|
|
*/
|
|
exports.attachStoragePolicy = async (page, policyName) => {
|
|
await page
|
|
.getByRole('link', { name: new RegExp('/*Settings'), exact: true })
|
|
.click();
|
|
await page.getByText('Add Storage Policy').click();
|
|
await page.getByLabel('Storage Policy').selectOption({ label: policyName });
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
await expect(
|
|
page.getByRole('alert').getByText('Success', { exact: true }),
|
|
).toBeVisible();
|
|
await page.getByRole('button', { name: 'Dismiss' }).click();
|
|
await expect(page.getByRole('listitem').getByText(policyName)).toBeVisible();
|
|
};
|