Files
threshold-ui/e2e-tests/admin/tests/target.spec.js
T
Michael Li 1cbf3b227e test(e2e): Add additional assertions to UI tests (#2634)
* test(e2e): Address deprecation

* test(e2e): Add additional connection assertions on tests

* CR: Fix flake when waiting for sessions

If no sessions are available and the page needs to reload, we should wait to ensure that the page has loaded before checking what the state of the sessions are

* CR: Address flake in connect methods

Noticed an issue where a session recording was not playable. The theory is that the session didn't last long enough before it was cancelled. This adds a 2 second wait after establishing a connection before continuing.

* CR: Use authenticated state by default

* CR: Update dynamic host catalog assertion

* CR: Simplify host set checks

- Use .all() when looping
- Add check to see if we need to reload the page or not

* CR: Be more specific with locator

Ran into a conflict with the Static/Dynamic host catalog type and the Static/Dynamic credential type.

* CR: Update connection methods to be more resilient

Rather than using a hardcoded sleep, we will now run a command on the target and wait for a specific string to return before continuing.

* CR
2025-01-06 11:40:32 -05:00

234 lines
7.0 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import { test } from '../../global-setup.js';
import { expect } from '@playwright/test';
import * as boundaryCli from '../../helpers/boundary-cli';
import { BasePage } from '../pages/base.js';
import { HostCatalogsPage } from '../pages/host-catalogs.js';
import { OrgsPage } from '../pages/orgs.js';
import { ProjectsPage } from '../pages/projects.js';
import { SessionsPage } from '../pages/sessions.js';
import { TargetsPage } from '../pages/targets.js';
test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Verify session created to target with host, then cancel the session @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host set
const hostCatalogsPage = new HostCatalogsPage(page);
const hostCatalogName = await hostCatalogsPage.createHostCatalog();
const hostSetName = await hostCatalogsPage.createHostSet();
await hostCatalogsPage.createHostInHostSet(targetAddress);
// Create another host set
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: hostCatalogName }).click();
const hostSetName2 = await hostCatalogsPage.createHostSet();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTarget(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add/Remove another host source
await targetsPage.addHostSourceToTarget(hostSetName2);
await targetsPage.removeHostSourceFromTarget(hostSetName2);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(targetId, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
});
test('Verify session created to target with address, then cancel the session @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(targetId, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
});
test('Verify TCP target is updated @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
await targetsPage.createTargetWithAddress(targetAddress, targetPort);
// Update target
await page.getByRole('button', { name: 'Edit Form' }).click();
await page.getByLabel('Name').fill('New target name');
await page.getByLabel('Description').fill('New description');
await page.getByLabel('Target Address').fill('127.0.0.1');
await page.getByLabel('Default Port').fill('10');
await page.getByLabel('Default Client Port').fill('10');
await page.getByLabel('Maximum Duration').fill('1000');
await page.getByLabel('Maximum Connections').fill('10');
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 targetsPage.addEgressWorkerFilterToTarget('"dev" in "/tags/type"');
// Edit a worker filter
await page.getByRole('link', { name: 'Workers', exact: true }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Workers'),
).toBeVisible();
await page
.getByText('Egress workers')
.locator('..')
.getByRole('link', { name: 'Edit worker filter' })
.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Edit Egress Worker Filter'),
).toBeVisible();
await expect(page.getByText('"dev" in "/tags/type"')).toBeVisible();
await page.getByRole('textbox').click({ force: true });
await page.keyboard.press('Meta+A');
await page.keyboard.press('Backspace');
await page.getByRole('textbox').fill('"prod" in "/tags/type"');
await page.getByRole('button', { name: 'Save' }).click();
const basePage = new BasePage(page);
await basePage.dismissSuccessAlert();
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
});