test: fix url checks in e2e tests (#12881)

This commit is contained in:
Kayla Washburn-Love 2024-04-11 15:48:53 -06:00 committed by GitHub
parent 93b46fe1f6
commit c5367c201b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 21 deletions

29
site/e2e/expectUrl.ts Normal file
View File

@ -0,0 +1,29 @@
import { expect, type Page } from "@playwright/test";
type PollingOptions = { timeout?: number; intervals?: number[] };
export const expectUrl = expect.extend({
/**
* toHavePathName is an alternative to `toHaveURL` that won't fail if the URL contains query parameters.
*/
async toHavePathName(page: Page, expected: string, options?: PollingOptions) {
let actual: string = new URL(page.url()).pathname;
let pass: boolean;
try {
await expect
.poll(() => (actual = new URL(page.url()).pathname), options)
.toBe(expected);
pass = true;
} catch {
pass = false;
}
return {
name: "toHavePathName",
pass,
actual,
expected,
message: () => "The page does not have the expected URL pathname.",
};
},
});

View File

@ -3,6 +3,7 @@ import { hasFirstUser } from "api/api";
import { Language } from "pages/CreateUserPage/CreateUserForm";
import { setupApiCalls } from "./api";
import * as constants from "./constants";
import { expectUrl } from "./expectUrl";
import { storageState } from "./playwright.config";
test("setup deployment", async ({ page }) => {
@ -21,7 +22,7 @@ test("setup deployment", async ({ page }) => {
await page.getByLabel(Language.passwordLabel).fill(constants.password);
await page.getByTestId("create").click();
await expect(page).toHaveURL(/\/workspaces.*/);
await expectUrl(page).toHavePathName("/workspaces");
await page.context().storageState({ path: storageState });
await page.getByTestId("button-select-template").isVisible();

View File

@ -20,6 +20,7 @@ import {
prometheusPort,
requireEnterpriseTests,
} from "./constants";
import { expectUrl } from "./expectUrl";
import {
Agent,
type App,
@ -49,10 +50,10 @@ export const createWorkspace = async (
richParameters: RichParameter[] = [],
buildParameters: WorkspaceBuildParameter[] = [],
): Promise<string> => {
await page.goto("/templates/" + templateName + "/workspace", {
await page.goto(`/templates/${templateName}/workspace`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL("/templates/" + templateName + "/workspace");
await expectUrl(page).toHavePathName(`/templates/${templateName}/workspace`);
const name = randomName();
await page.getByLabel("name").fill(name);
@ -60,9 +61,7 @@ export const createWorkspace = async (
await fillParameters(page, richParameters, buildParameters);
await page.getByTestId("form-submit").click();
// Workaround: OutdatedAgent lands at "http://localhost:3111/@admin/8d6225b7?resources=echo_dev"
// and this is also a correct location.
await page.waitForURL(new RegExp("/@admin/" + name));
await expectUrl(page).toHavePathName("/@admin/" + name);
await page.waitForSelector("*[data-testid='build-status'] >> text=Running", {
state: "visible",
@ -79,8 +78,8 @@ export const verifyParameters = async (
await page.goto("/@admin/" + workspaceName + "/settings/parameters", {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL(
"/@admin/" + workspaceName + "/settings/parameters",
await expectUrl(page).toHavePathName(
`/@admin/${workspaceName}/settings/parameters`,
);
for (const buildParameter of expectedBuildParameters) {
@ -141,7 +140,7 @@ export const createTemplate = async (
});
await page.goto("/templates/new", { waitUntil: "domcontentloaded" });
await expect(page).toHaveURL("/templates/new");
await expectUrl(page).toHavePathName("/templates/new");
await page.getByTestId("file-upload").setInputFiles({
buffer: await createTemplateVersionTar(responses),
@ -151,7 +150,7 @@ export const createTemplate = async (
const name = randomName();
await page.getByLabel("Name *").fill(name);
await page.getByTestId("form-submit").click();
await expect(page).toHaveURL(`/templates/${name}/files`, {
await expectUrl(page).toHavePathName(`/templates/${name}/files`, {
timeout: 30000,
});
return name;
@ -161,7 +160,7 @@ export const createTemplate = async (
// random name.
export const createGroup = async (page: Page): Promise<string> => {
await page.goto("/groups/create", { waitUntil: "domcontentloaded" });
await expect(page).toHaveURL("/groups/create");
await expectUrl(page).toHavePathName("/groups/create");
const name = randomName();
await page.getByLabel("Name", { exact: true }).fill(name);
@ -222,7 +221,7 @@ export const stopWorkspace = async (page: Page, workspaceName: string) => {
await page.goto("/@admin/" + workspaceName, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL("/@admin/" + workspaceName);
await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`);
await page.getByTestId("workspace-stop-button").click();
@ -241,7 +240,7 @@ export const buildWorkspaceWithParameters = async (
await page.goto("/@admin/" + workspaceName, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL("/@admin/" + workspaceName);
await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`);
await page.getByTestId("build-parameters-button").click();
@ -753,7 +752,7 @@ export const updateTemplateSettings = async (
await page.goto(`/templates/${templateName}/settings`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL(`/templates/${templateName}/settings`);
await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`);
for (const [key, value] of Object.entries(templateSettingValues)) {
// Skip max_port_share_level for now since the frontend is not yet able to handle it
@ -767,7 +766,7 @@ export const updateTemplateSettings = async (
await page.getByTestId("form-submit").click();
const name = templateSettingValues.name ?? templateName;
await expect(page).toHaveURL(`/templates/${name}`);
await expectUrl(page).toHavePathName(`/templates/${name}`);
};
export const updateWorkspace = async (
@ -779,7 +778,7 @@ export const updateWorkspace = async (
await page.goto("/@admin/" + workspaceName, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL("/@admin/" + workspaceName);
await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`);
await page.getByTestId("workspace-update-button").click();
await page.getByTestId("confirm-button").click();
@ -801,8 +800,8 @@ export const updateWorkspaceParameters = async (
await page.goto("/@admin/" + workspaceName + "/settings/parameters", {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL(
"/@admin/" + workspaceName + "/settings/parameters",
await expectUrl(page).toHavePathName(
`/@admin/${workspaceName}/settings/parameters`,
);
await fillParameters(page, richParameters, buildParameters);
@ -827,7 +826,9 @@ export async function openTerminalWindow(
// Specify that the shell should be `bash`, to prevent inheriting a shell that
// isn't POSIX compatible, such as Fish.
const commandQuery = `?command=${encodeURIComponent("/usr/bin/env bash")}`;
await expect(terminal).toHaveURL(`/@admin/${workspaceName}.dev/terminal`);
await expectUrl(terminal).toHavePathName(
`/@admin/${workspaceName}.dev/terminal`,
);
await terminal.goto(`/@admin/${workspaceName}.dev/terminal${commandQuery}`);
return terminal;

View File

@ -1,4 +1,5 @@
import { expect, test } from "@playwright/test";
import { expectUrl } from "../expectUrl";
import {
createGroup,
createTemplate,
@ -25,7 +26,7 @@ test("add and remove a group", async ({ page }) => {
await page.goto(`/templates/${templateName}/settings/permissions`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL(
await expectUrl(page).toHavePathName(
`/templates/${templateName}/settings/permissions`,
);
@ -55,7 +56,7 @@ test("require latest version", async ({ page }) => {
await page.goto(`/templates/${templateName}/settings`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveURL(`/templates/${templateName}/settings`);
await expectUrl(page).toHavePathName(`/templates/${templateName}/settings`);
let checkbox = await page.waitForSelector("#require_active_version");
await checkbox.click();
await page.getByTestId("form-submit").click();

View File

@ -116,6 +116,7 @@ export const CreateTokenForm: FC<CreateTokenFormProps> = ({
{lifetimeDays === "custom" && (
<TextField
data-chromatic="ignore"
type="date"
label="Expires on"
defaultValue={dayjs().add(expDays, "day").format("YYYY-MM-DD")}