chore(site): add e2e to test add and remove user (#12851)

This commit is contained in:
Bruno Quaresma
2024-04-04 09:21:03 -03:00
committed by GitHub
parent a7234f61a1
commit 41b8ff3e81
6 changed files with 93 additions and 7 deletions

View File

@ -7,6 +7,7 @@ import capitalize from "lodash/capitalize";
import path from "path"; import path from "path";
import * as ssh from "ssh2"; import * as ssh from "ssh2";
import { Duplex } from "stream"; import { Duplex } from "stream";
import * as API from "api/api";
import type { import type {
WorkspaceBuildParameter, WorkspaceBuildParameter,
UpdateTemplateMeta, UpdateTemplateMeta,
@ -565,7 +566,7 @@ const createTemplateVersionTar = async (
); );
}; };
const randomName = () => { export const randomName = () => {
return randomUUID().slice(0, 8); return randomUUID().slice(0, 8);
}; };
@ -603,7 +604,7 @@ export const createServer = async (
return e; return e;
}; };
const findSessionToken = async (page: Page): Promise<string> => { export const findSessionToken = async (page: Page): Promise<string> => {
const cookies = await page.context().cookies(); const cookies = await page.context().cookies();
const sessionCookie = cookies.find((c) => c.name === "coder_session_token"); const sessionCookie = cookies.find((c) => c.name === "coder_session_token");
if (!sessionCookie) { if (!sessionCookie) {
@ -825,3 +826,9 @@ export async function openTerminalWindow(
return terminal; return terminal;
} }
export const setupApiCalls = async (page: Page) => {
const token = await findSessionToken(page);
API.setSessionToken(token);
API.setHost(`http://127.0.0.1:${coderPort}`);
};

View File

@ -0,0 +1,35 @@
import { test, expect } from "@playwright/test";
import { randomName } from "../../helpers";
import { beforeCoderTest } from "../../hooks";
test.beforeEach(async ({ page }) => await beforeCoderTest(page));
test("create user with password", async ({ page, baseURL }) => {
await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Users - Coder");
await page.getByRole("button", { name: "Create user" }).click();
await expect(page).toHaveTitle("Create User - Coder");
const name = randomName();
const userValues = {
username: name,
email: `${name}@coder.com`,
loginType: "password",
password: "s3cure&password!",
};
await page.getByLabel("Username").fill(userValues.username);
await page.getByLabel("Email").fill(userValues.email);
await page.getByLabel("Login Type").click();
await page.getByRole("option", { name: "Password", exact: false }).click();
// Using input[name=password] due to the select element utilizing 'password'
// as the label for the currently active option.
const passwordField = page.locator("input[name=password]");
await passwordField.fill(userValues.password);
await page.getByRole("button", { name: "Create user" }).click();
await expect(page.getByText("Successfully created user.")).toBeVisible();
await expect(page).toHaveTitle("Users - Coder");
await expect(page.locator("tr", { hasText: userValues.email })).toBeVisible();
});

View File

@ -0,0 +1,33 @@
import { test, expect } from "@playwright/test";
import * as API from "api/api";
import { randomName, setupApiCalls } from "../../helpers";
import { beforeCoderTest } from "../../hooks";
test.beforeEach(async ({ page }) => await beforeCoderTest(page));
test("remove user", async ({ page, baseURL }) => {
await setupApiCalls(page);
const currentUser = await API.getAuthenticatedUser();
const name = randomName();
const user = await API.createUser({
email: `${name}@coder.com`,
username: name,
password: "s3cure&password!",
login_type: "password",
disable_login: false,
organization_id: currentUser.organization_ids[0],
});
await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Users - Coder");
const userRow = page.locator("tr", { hasText: user.email });
await userRow.getByRole("button", { name: "More options" }).click();
await userRow.getByText("Delete", { exact: false }).click();
const dialog = page.getByTestId("dialog");
await dialog.getByLabel("Name of the user to delete").fill(user.username);
await dialog.getByRole("button", { name: "Delete" }).click();
await expect(page.getByText("Successfully deleted the user.")).toBeVisible();
});

View File

@ -72,6 +72,14 @@ if (token !== null && token.getAttribute("content") !== null) {
} }
} }
export const setSessionToken = (token: string) => {
axios.defaults.headers.common["Coder-Session-Token"] = token;
};
export const setHost = (host?: string) => {
axios.defaults.baseURL = host;
};
const CONTENT_TYPE_JSON = { const CONTENT_TYPE_JSON = {
"Content-Type": "application/json", "Content-Type": "application/json",
}; };

View File

@ -193,7 +193,11 @@ export const CreateUserForm: FC<
type="password" type="password"
/> />
</Stack> </Stack>
<FormFooter onCancel={onCancel} isLoading={isLoading} /> <FormFooter
submitLabel="Create user"
onCancel={onCancel}
isLoading={isLoading}
/>
</form> </form>
</FullPageForm> </FullPageForm>
); );

View File

@ -1,6 +1,5 @@
import { fireEvent, screen } from "@testing-library/react"; import { fireEvent, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { Language as FooterLanguage } from "components/FormFooter/FormFooter";
import { import {
renderWithAuth, renderWithAuth,
waitForLoaderToBeRemoved, waitForLoaderToBeRemoved,
@ -35,9 +34,9 @@ const fillForm = async ({
await userEvent.type(emailField, email); await userEvent.type(emailField, email);
await userEvent.type(loginTypeField, "password"); await userEvent.type(loginTypeField, "password");
await userEvent.type(passwordField as HTMLElement, password); await userEvent.type(passwordField as HTMLElement, password);
const submitButton = await screen.findByText( const submitButton = screen.getByRole("button", {
FooterLanguage.defaultSubmitLabel, name: "Create user",
); });
fireEvent.click(submitButton); fireEvent.click(submitButton);
}; };